-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Description
Bug Report
π Search Terms
auto import type-only value
π Version & Regression Information
- This is the behaviour in every version I tried
β― Playground Link
Playground link with relevant code
π» Code
import type { ComponentType } from 'react';
import { useState } from 'react';
export function Component({ prop } : { prop: ComponentType }) {
const codeIsUnimportant = useState(1);
// trigger auto-import for this line
useEffect(() => {}, []);
}π Expected behaviour
When I trigger auto-import for the useEffect function, TS should look at all of the imports and find the first value import declaration with the correct source to use.
I.e. I would expect this result:
import type { ComponentType } from 'react';
import { useState, useEffect } from 'react';π Actual behaviour
When I trigger auto-import for the useEffect function, TS looks for the first import declaration with the correct source, even if it's a type-only import. If it is type-only, TS will remove the qualifier entirely.
I.e. it results in this code
import { ComponentType, useEffect } from 'react';
import { useState } from 'react';Which is pretty bad because it means TS changes the meaning of the code for some compilers!
If 5.0's verbatimModuleSyntax is turned on, then instead you get this:
import { useEffect, type ComponentType } from 'react';
import { useState } from 'react';Which is marginally better as it at least preserves the meaning of the code.
Note that the same thing happens if you reverse the situation.
playground
import { useState } from 'react';
import type { ComponentType } from 'react';
export function Component({ prop } : { prop: ComponentType }) {
const codeIsUnimportant = useState(1);
// trigger auto-import for this line
type T = InvalidEvent;
}By default TS will insert the type import in the value import:
import { InvalidEvent, useState } from 'react';
import type { ComponentType } from 'react';If 5.0's verbatimModuleSyntax is turned on, then instead you get this:
import { type InvalidEvent, useState } from 'react';
import type { ComponentType } from 'react';Suggested change:
- When auto-importing, gather all of the import declaratinos.
- If the imported thing is a type, then prefer using the first type-only import declaration.
- If the imported thing is a value, then prefer using the first value import declaration.
- If there is no matching declaration, then I think one of the following should occur:
- If the thing is a value and the only import declarations are type-only, then insert a new value import declaration. DO NOT mutate the existing import declaration(s) to remove the top-level type-only qualifier.
- If the thing is a type and the only import declarations are value, then one of the following should occur (perhaps configurably?):
- Insert a new specifier into the value declaration, qualifying the specifier with
type - Insert a new type-only import declaration.
- Insert a new specifier into the value declaration, qualifying the specifier with
The most important bit, IMO, is that TS should NEVER remove the top-level type qualifier from an import when performing an auto-import.