mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
fix(51202): Circular instantiation expression crashing IDEs (#51214)
This commit is contained in:
@@ -6677,6 +6677,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const isInstantiationExpressionType = !!(getObjectFlags(type) & ObjectFlags.InstantiationExpressionType);
|
||||
if (isInstantiationExpressionType) {
|
||||
const instantiationExpressionType = type as InstantiationExpressionType;
|
||||
if (isTypeQueryNode(instantiationExpressionType.node)) {
|
||||
const typeNode = serializeExistingTypeNode(context, instantiationExpressionType.node);
|
||||
if (typeNode) {
|
||||
return typeNode;
|
||||
}
|
||||
}
|
||||
if (context.visitedTypes?.has(typeId)) {
|
||||
return createElidedInformationPlaceholder(context);
|
||||
}
|
||||
return visitAndTransformType(type, createTypeNodeFromObjectType);
|
||||
}
|
||||
// Anonymous types without a symbol are never circular.
|
||||
return createTypeNodeFromObjectType(type);
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ var xs2: typeof Array;
|
||||
>Array : ArrayConstructor
|
||||
|
||||
var xs3: typeof Array<number>;
|
||||
>xs3 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
|
||||
>xs3 : typeof Array<number>
|
||||
>Array : ArrayConstructor
|
||||
|
||||
var xs4: typeof Array<typeof x>;
|
||||
>xs4 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
|
||||
>xs4 : typeof Array<typeof x>
|
||||
>Array : ArrayConstructor
|
||||
>x : number
|
||||
|
||||
|
||||
11
tests/baselines/reference/circularInstantiationExpression.js
Normal file
11
tests/baselines/reference/circularInstantiationExpression.js
Normal file
@@ -0,0 +1,11 @@
|
||||
//// [circularInstantiationExpression.ts]
|
||||
declare function foo<T>(t: T): typeof foo<T>;
|
||||
foo("");
|
||||
|
||||
|
||||
//// [circularInstantiationExpression.js]
|
||||
foo("");
|
||||
|
||||
|
||||
//// [circularInstantiationExpression.d.ts]
|
||||
declare function foo<T>(t: T): typeof foo<T>;
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/circularInstantiationExpression.ts ===
|
||||
declare function foo<T>(t: T): typeof foo<T>;
|
||||
>foo : Symbol(foo, Decl(circularInstantiationExpression.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularInstantiationExpression.ts, 0, 21))
|
||||
>t : Symbol(t, Decl(circularInstantiationExpression.ts, 0, 24))
|
||||
>T : Symbol(T, Decl(circularInstantiationExpression.ts, 0, 21))
|
||||
>foo : Symbol(foo, Decl(circularInstantiationExpression.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularInstantiationExpression.ts, 0, 21))
|
||||
|
||||
foo("");
|
||||
>foo : Symbol(foo, Decl(circularInstantiationExpression.ts, 0, 0))
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
=== tests/cases/compiler/circularInstantiationExpression.ts ===
|
||||
declare function foo<T>(t: T): typeof foo<T>;
|
||||
>foo : <T>(t: T) => typeof foo<T>
|
||||
>t : T
|
||||
>foo : <T>(t: T) => typeof foo<T>
|
||||
|
||||
foo("");
|
||||
>foo("") : (t: string) => any
|
||||
>foo : <T>(t: T) => (t: T) => any
|
||||
>"" : ""
|
||||
|
||||
@@ -33,19 +33,19 @@ const ComeOnFoo = foo<?string?>;
|
||||
>foo : <T>(x: T) => T
|
||||
|
||||
type TWhatFoo = typeof foo<?>;
|
||||
>TWhatFoo : (x: any) => any
|
||||
>TWhatFoo : typeof foo<unknown>
|
||||
>foo : <T>(x: T) => T
|
||||
|
||||
type THuhFoo = typeof foo<string?>;
|
||||
>THuhFoo : (x: string | null) => string | null
|
||||
>THuhFoo : typeof foo<string | null>
|
||||
>foo : <T>(x: T) => T
|
||||
|
||||
type TNopeFoo = typeof foo<?string>;
|
||||
>TNopeFoo : (x: string | null) => string | null
|
||||
>TNopeFoo : typeof foo<string | null>
|
||||
>foo : <T>(x: T) => T
|
||||
|
||||
type TComeOnFoo = typeof foo<?string?>;
|
||||
>TComeOnFoo : (x: string | null) => string | null
|
||||
>TComeOnFoo : typeof foo<(string | null) | null>
|
||||
>foo : <T>(x: T) => T
|
||||
|
||||
const WhatBar = Bar<?>;
|
||||
@@ -69,18 +69,18 @@ const ComeOnBar = Bar<?string?>;
|
||||
>Bar : typeof Bar
|
||||
|
||||
type TWhatBar = typeof Bar<?>;
|
||||
>TWhatBar : { new (x: any): Bar<any>; prototype: Bar<any>; }
|
||||
>TWhatBar : typeof Bar<unknown>
|
||||
>Bar : typeof Bar
|
||||
|
||||
type THuhBar = typeof Bar<string?>;
|
||||
>THuhBar : { new (x: string | null): Bar<string | null>; prototype: Bar<any>; }
|
||||
>THuhBar : typeof Bar<string | null>
|
||||
>Bar : typeof Bar
|
||||
|
||||
type TNopeBar = typeof Bar<?string>;
|
||||
>TNopeBar : { new (x: string | null): Bar<string | null>; prototype: Bar<any>; }
|
||||
>TNopeBar : typeof Bar<string | null>
|
||||
>Bar : typeof Bar
|
||||
|
||||
type TComeOnBar = typeof Bar<?string?>;
|
||||
>TComeOnBar : { new (x: string | null): Bar<string | null>; prototype: Bar<any>; }
|
||||
>TComeOnBar : typeof Bar<(string | null) | null>
|
||||
>Bar : typeof Bar
|
||||
|
||||
|
||||
@@ -41,15 +41,15 @@ type T10 = typeof fx<>; // Error
|
||||
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
|
||||
|
||||
type T11 = typeof fx<string>; // { (x: string): string; (x: string, n: number): string; }
|
||||
>T11 : { (x: string): string; (x: string, n: number): string; }
|
||||
>T11 : typeof fx<string>
|
||||
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
|
||||
|
||||
type T12 = typeof fx<string, number>; // (t: [string, number]) => [string, number]
|
||||
>T12 : (t: [string, number]) => [string, number]
|
||||
>T12 : typeof fx<string, number>
|
||||
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
|
||||
|
||||
type T13 = typeof fx<string, number, boolean>; // Error
|
||||
>T13 : {}
|
||||
>T13 : typeof fx<string, number, boolean>
|
||||
>fx : { <T>(x: T): T; <T>(x: T, n: number): T; <T, U>(t: [T, U]): [T, U]; }
|
||||
|
||||
function f2() {
|
||||
@@ -76,11 +76,11 @@ type T20 = typeof Array<>; // Error
|
||||
>Array : ArrayConstructor
|
||||
|
||||
type T21 = typeof Array<string>; // new (...) => string[]
|
||||
>T21 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
|
||||
>T21 : typeof Array<string>
|
||||
>Array : ArrayConstructor
|
||||
|
||||
type T22 = typeof Array<string, number>; // Error
|
||||
>T22 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; }
|
||||
>T22 : typeof Array<string, number>
|
||||
>Array : ArrayConstructor
|
||||
|
||||
declare class C<T> {
|
||||
@@ -439,7 +439,7 @@ function makeBox<T>(value: T) {
|
||||
}
|
||||
|
||||
type BoxFunc<T> = typeof makeBox<T>; // (value: T) => { value: T }
|
||||
>BoxFunc : (value: T) => { value: T; }
|
||||
>BoxFunc : typeof makeBox<T>
|
||||
>makeBox : <T>(value: T) => { value: T; }
|
||||
|
||||
type StringBoxFunc = BoxFunc<string>; // (value: string) => { value: string }
|
||||
@@ -469,7 +469,7 @@ declare const g1: {
|
||||
}
|
||||
|
||||
type T30<V> = typeof g1<V>; // { (a: V) => { a: V }; new (b: V) => { b: V }; }
|
||||
>T30 : { (a: V): { a: V; }; new (b: V): { b: V; }; }
|
||||
>T30 : typeof g1<V>
|
||||
>g1 : { <T>(a: T): { a: T; }; new <U>(b: U): { b: U; }; }
|
||||
|
||||
type T31<A> = ReturnType<T30<A>>; // { a: A }
|
||||
@@ -489,11 +489,11 @@ declare const g2: {
|
||||
}
|
||||
|
||||
type T40<U extends string> = typeof g2<U>; // Error
|
||||
>T40 : { (a: U): U; new <T extends number>(b: T): T; }
|
||||
>T40 : typeof g2<U>
|
||||
>g2 : { <T extends string>(a: T): T; new <T extends number>(b: T): T; }
|
||||
|
||||
type T41<U extends number> = typeof g2<U>; // Error
|
||||
>T41 : { <T extends string>(a: T): T; new (b: U): U; }
|
||||
>T41 : typeof g2<U>
|
||||
>g2 : { <T extends string>(a: T): T; new <T extends number>(b: T): T; }
|
||||
|
||||
declare const g3: {
|
||||
@@ -507,10 +507,10 @@ declare const g3: {
|
||||
}
|
||||
|
||||
type T50<U extends string> = typeof g3<U>; // (a: U) => U
|
||||
>T50 : (a: U) => U
|
||||
>T50 : typeof g3<U>
|
||||
>g3 : { <T extends string>(a: T): T; new <T extends number, Q>(b: T): T; }
|
||||
|
||||
type T51<U extends number> = typeof g3<U, any>; // (b: U) => U
|
||||
>T51 : new (b: U) => U
|
||||
>T51 : typeof g3<U, any>
|
||||
>g3 : { <T extends string>(a: T): T; new <T extends number, Q>(b: T): T; }
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
=== /tests/cases/fourslash/quickInfoCircularInstantiationExpression.ts ===
|
||||
// declare function foo<T>(t: T): typeof foo<T>;
|
||||
// foo("");
|
||||
// ^^^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | function foo<string>(t: string): (t: string) => ...
|
||||
// | ----------------------------------------------------------------------
|
||||
|
||||
[
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/quickInfoCircularInstantiationExpression.ts",
|
||||
"position": 46,
|
||||
"name": ""
|
||||
},
|
||||
"item": {
|
||||
"kind": "function",
|
||||
"kindModifiers": "declare",
|
||||
"textSpan": {
|
||||
"start": 46,
|
||||
"length": 3
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "foo",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "<",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": ">",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "t",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "t",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "=>",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "...",
|
||||
"kind": "text"
|
||||
}
|
||||
],
|
||||
"documentation": []
|
||||
}
|
||||
}
|
||||
]
|
||||
14
tests/baselines/reference/selfReferentialFunctionType.js
Normal file
14
tests/baselines/reference/selfReferentialFunctionType.js
Normal file
@@ -0,0 +1,14 @@
|
||||
//// [selfReferentialFunctionType.ts]
|
||||
declare function f<T>(args: typeof f<T>): T;
|
||||
declare function g<T = typeof g>(args: T): T;
|
||||
declare function h<T>(): typeof h<T>;
|
||||
|
||||
|
||||
//// [selfReferentialFunctionType.js]
|
||||
"use strict";
|
||||
|
||||
|
||||
//// [selfReferentialFunctionType.d.ts]
|
||||
declare function f<T>(args: typeof f<T>): T;
|
||||
declare function g<T = typeof g>(args: T): T;
|
||||
declare function h<T>(): typeof h<T>;
|
||||
@@ -0,0 +1,23 @@
|
||||
=== tests/cases/compiler/selfReferentialFunctionType.ts ===
|
||||
declare function f<T>(args: typeof f<T>): T;
|
||||
>f : Symbol(f, Decl(selfReferentialFunctionType.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 0, 19))
|
||||
>args : Symbol(args, Decl(selfReferentialFunctionType.ts, 0, 22))
|
||||
>f : Symbol(f, Decl(selfReferentialFunctionType.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 0, 19))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 0, 19))
|
||||
|
||||
declare function g<T = typeof g>(args: T): T;
|
||||
>g : Symbol(g, Decl(selfReferentialFunctionType.ts, 0, 44))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 1, 19))
|
||||
>g : Symbol(g, Decl(selfReferentialFunctionType.ts, 0, 44))
|
||||
>args : Symbol(args, Decl(selfReferentialFunctionType.ts, 1, 33))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 1, 19))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 1, 19))
|
||||
|
||||
declare function h<T>(): typeof h<T>;
|
||||
>h : Symbol(h, Decl(selfReferentialFunctionType.ts, 1, 45))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 2, 19))
|
||||
>h : Symbol(h, Decl(selfReferentialFunctionType.ts, 1, 45))
|
||||
>T : Symbol(T, Decl(selfReferentialFunctionType.ts, 2, 19))
|
||||
|
||||
15
tests/baselines/reference/selfReferentialFunctionType.types
Normal file
15
tests/baselines/reference/selfReferentialFunctionType.types
Normal file
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/compiler/selfReferentialFunctionType.ts ===
|
||||
declare function f<T>(args: typeof f<T>): T;
|
||||
>f : <T>(args: typeof f<T>) => T
|
||||
>args : typeof f<T>
|
||||
>f : <T>(args: typeof f<T>) => T
|
||||
|
||||
declare function g<T = typeof g>(args: T): T;
|
||||
>g : <T = typeof g>(args: T) => T
|
||||
>g : <T = typeof g>(args: T) => T
|
||||
>args : T
|
||||
|
||||
declare function h<T>(): typeof h<T>;
|
||||
>h : <T>() => typeof h<T>
|
||||
>h : <T>() => typeof h<T>
|
||||
|
||||
3
tests/cases/compiler/circularInstantiationExpression.ts
Normal file
3
tests/cases/compiler/circularInstantiationExpression.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// @declaration: true
|
||||
declare function foo<T>(t: T): typeof foo<T>;
|
||||
foo("");
|
||||
6
tests/cases/compiler/selfReferentialFunctionType.ts
Normal file
6
tests/cases/compiler/selfReferentialFunctionType.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
declare function f<T>(args: typeof f<T>): T;
|
||||
declare function g<T = typeof g>(args: T): T;
|
||||
declare function h<T>(): typeof h<T>;
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////declare function foo<T>(t: T): typeof foo<T>;
|
||||
/////**/foo("");
|
||||
|
||||
verify.baselineQuickInfo();
|
||||
Reference in New Issue
Block a user