Skip to content

Commit 4ece0a3

Browse files
Partially reuse type nodes (microsoft#58516)
1 parent 2d47953 commit 4ece0a3

File tree

56 files changed

+807
-300
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+807
-300
lines changed

src/compiler/checker.ts

Lines changed: 125 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5996,6 +5996,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
59965996
if (!nodeIsSynthesized(range) && !(range.flags & NodeFlags.Synthesized) && (!context.enclosingFile || context.enclosingFile !== getSourceFileOfNode(range))) {
59975997
range = factory.cloneNode(range);
59985998
}
5999+
if (range === location) return range;
59996000
if (!location) {
60006001
return range;
60016002
}
@@ -8340,6 +8341,62 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
83408341
}
83418342
}
83428343

8344+
function serializeTypeName(context: NodeBuilderContext, node: EntityName, isTypeOf?: boolean, typeArguments?: readonly TypeNode[]) {
8345+
const meaning = isTypeOf ? SymbolFlags.Value : SymbolFlags.Type;
8346+
const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
8347+
if (!symbol) return undefined;
8348+
const resolvedSymbol = symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol;
8349+
if (isSymbolAccessible(symbol, context.enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible) return undefined;
8350+
return symbolToTypeNode(resolvedSymbol, context, meaning, typeArguments);
8351+
}
8352+
8353+
function canReuseTypeNode(context: NodeBuilderContext, existing: TypeNode) {
8354+
if (isInJSFile(existing)) {
8355+
if (isLiteralImportTypeNode(existing)) {
8356+
// Ensure resolvedSymbol is present
8357+
void getTypeFromImportTypeNode(existing);
8358+
const nodeSymbol = getNodeLinks(existing).resolvedSymbol;
8359+
return (
8360+
!nodeSymbol ||
8361+
!(
8362+
// The import type resolved using jsdoc fallback logic
8363+
(!existing.isTypeOf && !(nodeSymbol.flags & SymbolFlags.Type)) ||
8364+
// The import type had type arguments autofilled by js fallback logic
8365+
!(length(existing.typeArguments) >= getMinTypeArgumentCount(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(nodeSymbol)))
8366+
)
8367+
);
8368+
}
8369+
}
8370+
if (isTypeReferenceNode(existing)) {
8371+
if (isConstTypeReference(existing)) return false;
8372+
const type = getTypeFromTypeReference(existing);
8373+
const symbol = getNodeLinks(existing).resolvedSymbol;
8374+
if (!symbol) return false;
8375+
if (symbol.flags & SymbolFlags.TypeParameter) {
8376+
return true;
8377+
}
8378+
if (isInJSDoc(existing)) {
8379+
return existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)
8380+
&& !getIntendedTypeFromJSDocTypeReference(existing) // We should probably allow the reuse of JSDoc reference types such as String Number etc
8381+
&& (symbol.flags & SymbolFlags.Type); // JSDoc type annotations can reference values (meaning typeof value) as well as types. We only reuse type nodes
8382+
}
8383+
}
8384+
if (
8385+
isTypeOperatorNode(existing) &&
8386+
existing.operator === SyntaxKind.UniqueKeyword &&
8387+
existing.type.kind === SyntaxKind.SymbolKeyword
8388+
) {
8389+
const effectiveEnclosingContext = context.enclosingDeclaration && getEnclosingDeclarationIgnoringFakeScope(context.enclosingDeclaration);
8390+
return !!findAncestor(existing, n => n === effectiveEnclosingContext);
8391+
}
8392+
return true;
8393+
}
8394+
8395+
function serializeExistingTypeNode(context: NodeBuilderContext, typeNode: TypeNode) {
8396+
const type = getTypeFromTypeNode(typeNode);
8397+
return typeToTypeNodeHelper(type, context);
8398+
}
8399+
83438400
/**
83448401
* Do you mean to call this directly? You probably should use `tryReuseExistingTypeNode` instead,
83458402
* which performs sanity checking on the type before doing this.
@@ -8353,6 +8410,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
83538410
if (hadError) {
83548411
return undefined;
83558412
}
8413+
context.approximateLength += existing.end - existing.pos;
83568414
return transformed;
83578415

83588416
function visitExistingNodeTreeSymbols(node: Node): Node | undefined {
@@ -8456,8 +8514,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
84568514
);
84578515
}
84588516
}
8459-
if (isTypeReferenceNode(node) && isInJSDoc(node) && (!existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(node, getTypeFromTypeNode(node)) || getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(node, SymbolFlags.Type, /*ignoreErrors*/ true))) {
8460-
return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
8517+
if (isTypeReferenceNode(node)) {
8518+
if (canReuseTypeNode(context, node)) {
8519+
const { introducesError, node: newName } = trackExistingEntityName(node.typeName, context);
8520+
const typeArguments = visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, isTypeNode);
8521+
8522+
if (!introducesError) {
8523+
const updated = factory.updateTypeReferenceNode(
8524+
node,
8525+
newName,
8526+
typeArguments,
8527+
);
8528+
return setTextRange(context, updated, node);
8529+
}
8530+
else {
8531+
const serializedName = serializeTypeName(context, node.typeName, /*isTypeOf*/ false, typeArguments);
8532+
if (serializedName) {
8533+
return setTextRange(context, serializedName, node.typeName);
8534+
}
8535+
}
8536+
}
8537+
return serializeExistingTypeNode(context, node);
84618538
}
84628539
if (isLiteralImportTypeNode(node)) {
84638540
const nodeSymbol = getNodeLinks(node).resolvedSymbol;
@@ -8471,7 +8548,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
84718548
!(length(node.typeArguments) >= getMinTypeArgumentCount(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(nodeSymbol)))
84728549
)
84738550
) {
8474-
return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
8551+
return setTextRange(context, typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
84758552
}
84768553
return factory.updateImportTypeNode(
84778554
node,
@@ -8503,15 +8580,47 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
85038580
}
85048581
return visited;
85058582
}
8506-
8507-
if (isEntityName(node) || isEntityNameExpression(node)) {
8508-
if (isDeclarationName(node)) {
8509-
return node;
8583+
if (isTypeQueryNode(node)) {
8584+
const { introducesError, node: exprName } = trackExistingEntityName(node.exprName, context);
8585+
if (introducesError) {
8586+
const serializedName = serializeTypeName(context, node.exprName, /*isTypeOf*/ true);
8587+
if (serializedName) {
8588+
return setTextRange(context, serializedName, node.exprName);
8589+
}
8590+
return serializeExistingTypeNode(context, node);
85108591
}
8511-
const { introducesError, node: result } = trackExistingEntityName(node, context);
8592+
return factory.updateTypeQueryNode(
8593+
node,
8594+
exprName,
8595+
visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, isTypeNode),
8596+
);
8597+
}
8598+
if (isComputedPropertyName(node) && isEntityNameExpression(node.expression)) {
8599+
const { node: result, introducesError } = trackExistingEntityName(node.expression, context);
8600+
if (!introducesError) {
8601+
return factory.updateComputedPropertyName(node, result);
8602+
}
8603+
else {
8604+
const type = getWidenedType(getRegularTypeOfExpression(node.expression));
8605+
const computedPropertyNameType = typeToTypeNodeHelper(type, context);
8606+
Debug.assertNode(computedPropertyNameType, isLiteralTypeNode);
8607+
const literal = computedPropertyNameType.literal;
8608+
if (literal.kind === SyntaxKind.StringLiteral && isIdentifierText(literal.text, getEmitScriptTarget(compilerOptions))) {
8609+
return factory.createIdentifier(literal.text);
8610+
}
8611+
if (literal.kind === SyntaxKind.NumericLiteral && !literal.text.startsWith("-")) {
8612+
return literal;
8613+
}
8614+
return factory.updateComputedPropertyName(node, literal);
8615+
}
8616+
}
8617+
if (isTypePredicateNode(node) && isIdentifier(node.parameterName)) {
8618+
const { node: result, introducesError } = trackExistingEntityName(node.parameterName, context);
8619+
// Should not usually happen the only case is when a type predicate comes from a JSDoc type annotation with it's own parameter symbol definition.
8620+
// /** @type {(v: unknown) => v is undefined} */
8621+
// const isUndef = v => v === undefined;
85128622
hadError = hadError || introducesError;
8513-
// We should not go to child nodes of the entity name, they will not be accessible
8514-
return result;
8623+
return factory.updateTypePredicateNode(node, node.assertsModifier, result, visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode));
85158624
}
85168625

85178626
if (isTupleTypeNode(node) || isTypeLiteralNode(node) || isMappedTypeNode(node)) {
@@ -8543,6 +8652,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
85438652
);
85448653
}
85458654

8655+
if (isTypeOperatorNode(node) && node.operator === SyntaxKind.UniqueKeyword && node.type.kind === SyntaxKind.SymbolKeyword) {
8656+
if (!canReuseTypeNode(context, node)) {
8657+
return serializeExistingTypeNode(context, node);
8658+
}
8659+
}
8660+
85468661
return visitEachChild(node, visitExistingNodeTreeSymbols, /*context*/ undefined);
85478662

85488663
function getEffectiveDotDotDotForParameter(p: ParameterDeclaration) {

tests/baselines/reference/callbackTagNamespace.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var x = 1;
1616
/** @type {NS.Nested.Inner} */
1717
function f(space, peace) {
1818
>f : (space: any, peace: any) => string | number
19-
> : ^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^
19+
> : ^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
2020
>space : any
2121
>peace : any
2222

tests/baselines/reference/callsOnComplexSignatures.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function test1() {
4343

4444
function test(t: Temp1 | Temp2) {
4545
>test : (t: Temp1 | Temp2) => void
46-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^
46+
> : ^ ^^^^^^^ ^^^^^^^^^^^^^^
4747
>t : Temp1 | Temp2
4848
> : ^^^^^^^^^^^^^
4949

tests/baselines/reference/correlatedUnions.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ function ff1() {
822822
}
823823
function apply<K extends Keys>(funKey: K, ...args: ArgMap[K]) {
824824
>apply : <K extends keyof { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }>(funKey: K, ...args: { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]) => void
825-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
825+
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
826826
>funKey : K
827827
> : ^
828828
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]
@@ -854,7 +854,7 @@ function ff1() {
854854
>apply('sum', 1, 2) : void
855855
> : ^^^^
856856
>apply : <K extends keyof { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }>(funKey: K, ...args: { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]) => void
857-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
857+
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
858858
>'sum' : "sum"
859859
> : ^^^^^
860860
>1 : 1
@@ -868,7 +868,7 @@ function ff1() {
868868
>apply('concat', 'str1', 'str2', 'str3' ) : void
869869
> : ^^^^
870870
>apply : <K extends keyof { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }>(funKey: K, ...args: { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]) => void
871-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
871+
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
872872
>'concat' : "concat"
873873
> : ^^^^^^^^
874874
>'str1' : "str1"

tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ export default (suit: Suit, rank: Rank) => ({suit, rank});
4141
=== index.ts ===
4242
export let lazyCard = () => import('./Card').then(a => a.default);
4343
>lazyCard : () => Promise<(suit: import("Types").Suit, rank: import("Types").Rank) => { suit: import("Types").Suit; rank: import("Types").Rank; }>
44-
> : ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44+
> : ^^^^^^^^^^^^^^^ ^^ ^^^^^^^ ^^^^^^ ^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4545
>() => import('./Card').then(a => a.default) : () => Promise<(suit: import("Types").Suit, rank: import("Types").Rank) => { suit: import("Types").Suit; rank: import("Types").Rank; }>
46-
> : ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46+
> : ^^^^^^^^^^^^^^^ ^^ ^^^^^^^ ^^^^^^ ^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4747
>import('./Card').then(a => a.default) : Promise<(suit: import("Types").Suit, rank: import("Types").Rank) => { suit: import("Types").Suit; rank: import("Types").Rank; }>
48-
> : ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
> : ^^^^^^^^^ ^^ ^^^^^^^ ^^^^^^ ^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4949
>import('./Card').then : <TResult1 = typeof import("Card"), TResult2 = never>(onfulfilled?: (value: typeof import("Card")) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
5050
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5151
>import('./Card') : Promise<typeof import("Card")>
@@ -55,15 +55,15 @@ export let lazyCard = () => import('./Card').then(a => a.default);
5555
>then : <TResult1 = typeof import("Card"), TResult2 = never>(onfulfilled?: (value: typeof import("Card")) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
5656
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5757
>a => a.default : (a: typeof import("Card")) => (suit: import("Types").Suit, rank: import("Types").Rank) => { suit: import("Types").Suit; rank: import("Types").Rank; }
58-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58+
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^ ^^^^^^ ^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959
>a : typeof import("Card")
6060
> : ^^^^^^^^^^^^^^^^^^^^^
6161
>a.default : (suit: import("Types").Suit, rank: import("Types").Rank) => { suit: import("Types").Suit; rank: import("Types").Rank; }
62-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62+
> : ^ ^^ ^^^^^^^ ^^^^^^ ^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6363
>a : typeof import("Card")
6464
> : ^^^^^^^^^^^^^^^^^^^^^
6565
>default : (suit: import("Types").Suit, rank: import("Types").Rank) => { suit: import("Types").Suit; rank: import("Types").Rank; }
66-
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66+
> : ^ ^^ ^^^^^^^ ^^^^^^ ^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6767

6868
export { Suit, Rank } from './Types';
6969
>Suit : any

tests/baselines/reference/declarationEmitExportAssignedNamespaceNoTripleSlashTypesReference.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function getComp(): Component {
5555
=== src/inferred-comp-export.ts ===
5656
import { getComp } from "./get-comp";
5757
>getComp : () => import("node_modules/@types/react/index").Component
58-
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58+
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
5959

6060
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
6161
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
@@ -71,7 +71,7 @@ export const obj = {
7171
>getComp() : import("node_modules/@types/react/index").Component
7272
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7373
>getComp : () => import("node_modules/@types/react/index").Component
74-
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
74+
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
7575
}
7676
=== src/some-other-file.ts ===
7777

0 commit comments

Comments
 (0)