Skip to content

Exclude types originating in literals from recursion depth limiter check #34742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16272,7 +16272,7 @@ namespace ts {
// for finite but deeply expanding indexed accesses (eg, for `Q[P1][P2][P3][P4][P5]`).
function isDeeplyNestedType(type: Type, stack: Type[], depth: number): boolean {
// We track all object types that have an associated symbol (representing the origin of the type)
if (depth >= 5 && type.flags & TypeFlags.Object) {
if (depth >= 5 && type.flags & TypeFlags.Object && !isObjectOrArrayLiteralType(type)) {
const symbol = type.symbol;
if (symbol) {
let count = 0;
Expand Down
69 changes: 69 additions & 0 deletions tests/baselines/reference/deeplyNestedCheck.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
tests/cases/compiler/deeplyNestedCheck.ts(34,25): error TS2741: Property 'i' is missing in type '{}' but required in type 'H'.
tests/cases/compiler/deeplyNestedCheck.ts(52,35): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/deeplyNestedCheck.ts(53,50): error TS2322: Type 'number' is not assignable to type 'string'.


==== tests/cases/compiler/deeplyNestedCheck.ts (3 errors) ====
// Repro from #14794

interface DataSnapshot<X = {}> {
child(path: string): DataSnapshot;
}

interface Snapshot<T> extends DataSnapshot {
child<U extends Extract<keyof T, string>>(path: U): Snapshot<T[U]>;
}

// Repro from 34619

interface A { b: B[] }
interface B { c: C }
interface C { d: D[] }
interface D { e: E[] }
interface E { f: F[] }
interface F { g: G }
interface G { h: H[] }
interface H { i: string }

const x: A = {
b: [
{
c: {
d: [
{
e: [
{
f: [
{
g: {
h: [
{
~
// i: '',
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
},
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2741: Property 'i' is missing in type '{}' but required in type 'H'.
!!! related TS2728 tests/cases/compiler/deeplyNestedCheck.ts:20:15: 'i' is declared here.
],
},
},
],
},
],
},
],
},
},
],
};

// Repro from 34619

const a1: string[][][][][] = [[[[[42]]]]];
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
const a2: string[][][][][][][][][][] = [[[[[[[[[[42]]]]]]]]]];
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

74 changes: 74 additions & 0 deletions tests/baselines/reference/deeplyNestedCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,81 @@ interface DataSnapshot<X = {}> {
interface Snapshot<T> extends DataSnapshot {
child<U extends Extract<keyof T, string>>(path: U): Snapshot<T[U]>;
}

// Repro from 34619

interface A { b: B[] }
interface B { c: C }
interface C { d: D[] }
interface D { e: E[] }
interface E { f: F[] }
interface F { g: G }
interface G { h: H[] }
interface H { i: string }

const x: A = {
b: [
{
c: {
d: [
{
e: [
{
f: [
{
g: {
h: [
{
// i: '',
},
],
},
},
],
},
],
},
],
},
},
],
};

// Repro from 34619

const a1: string[][][][][] = [[[[[42]]]]];
const a2: string[][][][][][][][][][] = [[[[[[[[[[42]]]]]]]]]];


//// [deeplyNestedCheck.js]
// Repro from #14794
var x = {
b: [
{
c: {
d: [
{
e: [
{
f: [
{
g: {
h: [
{
// i: '',
},
]
}
},
]
},
]
},
]
}
},
]
};
// Repro from 34619
var a1 = [[[[[42]]]]];
var a2 = [[[[[[[[[[42]]]]]]]]]];
89 changes: 89 additions & 0 deletions tests/baselines/reference/deeplyNestedCheck.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,92 @@ interface Snapshot<T> extends DataSnapshot {
>U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8))
}

// Repro from 34619

interface A { b: B[] }
>A : Symbol(A, Decl(deeplyNestedCheck.ts, 8, 1))
>b : Symbol(A.b, Decl(deeplyNestedCheck.ts, 12, 13))
>B : Symbol(B, Decl(deeplyNestedCheck.ts, 12, 22))

interface B { c: C }
>B : Symbol(B, Decl(deeplyNestedCheck.ts, 12, 22))
>c : Symbol(B.c, Decl(deeplyNestedCheck.ts, 13, 13))
>C : Symbol(C, Decl(deeplyNestedCheck.ts, 13, 20))

interface C { d: D[] }
>C : Symbol(C, Decl(deeplyNestedCheck.ts, 13, 20))
>d : Symbol(C.d, Decl(deeplyNestedCheck.ts, 14, 13))
>D : Symbol(D, Decl(deeplyNestedCheck.ts, 14, 22))

interface D { e: E[] }
>D : Symbol(D, Decl(deeplyNestedCheck.ts, 14, 22))
>e : Symbol(D.e, Decl(deeplyNestedCheck.ts, 15, 13))
>E : Symbol(E, Decl(deeplyNestedCheck.ts, 15, 22))

interface E { f: F[] }
>E : Symbol(E, Decl(deeplyNestedCheck.ts, 15, 22))
>f : Symbol(E.f, Decl(deeplyNestedCheck.ts, 16, 13))
>F : Symbol(F, Decl(deeplyNestedCheck.ts, 16, 22))

interface F { g: G }
>F : Symbol(F, Decl(deeplyNestedCheck.ts, 16, 22))
>g : Symbol(F.g, Decl(deeplyNestedCheck.ts, 17, 13))
>G : Symbol(G, Decl(deeplyNestedCheck.ts, 17, 20))

interface G { h: H[] }
>G : Symbol(G, Decl(deeplyNestedCheck.ts, 17, 20))
>h : Symbol(G.h, Decl(deeplyNestedCheck.ts, 18, 13))
>H : Symbol(H, Decl(deeplyNestedCheck.ts, 18, 22))

interface H { i: string }
>H : Symbol(H, Decl(deeplyNestedCheck.ts, 18, 22))
>i : Symbol(H.i, Decl(deeplyNestedCheck.ts, 19, 13))

const x: A = {
>x : Symbol(x, Decl(deeplyNestedCheck.ts, 21, 5))
>A : Symbol(A, Decl(deeplyNestedCheck.ts, 8, 1))

b: [
>b : Symbol(b, Decl(deeplyNestedCheck.ts, 21, 14))
{
c: {
>c : Symbol(c, Decl(deeplyNestedCheck.ts, 23, 5))

d: [
>d : Symbol(d, Decl(deeplyNestedCheck.ts, 24, 10))
{
e: [
>e : Symbol(e, Decl(deeplyNestedCheck.ts, 26, 11))
{
f: [
>f : Symbol(f, Decl(deeplyNestedCheck.ts, 28, 15))
{
g: {
>g : Symbol(g, Decl(deeplyNestedCheck.ts, 30, 19))

h: [
>h : Symbol(h, Decl(deeplyNestedCheck.ts, 31, 24))
{
// i: '',
},
],
},
},
],
},
],
},
],
},
},
],
};

// Repro from 34619

const a1: string[][][][][] = [[[[[42]]]]];
>a1 : Symbol(a1, Decl(deeplyNestedCheck.ts, 51, 5))

const a2: string[][][][][][][][][][] = [[[[[[[[[[42]]]]]]]]]];
>a2 : Symbol(a2, Decl(deeplyNestedCheck.ts, 52, 5))

108 changes: 108 additions & 0 deletions tests/baselines/reference/deeplyNestedCheck.types
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,111 @@ interface Snapshot<T> extends DataSnapshot {
>path : U
}

// Repro from 34619

interface A { b: B[] }
>b : B[]

interface B { c: C }
>c : C

interface C { d: D[] }
>d : D[]

interface D { e: E[] }
>e : E[]

interface E { f: F[] }
>f : F[]

interface F { g: G }
>g : G

interface G { h: H[] }
>h : H[]

interface H { i: string }
>i : string

const x: A = {
>x : A
>{ b: [ { c: { d: [ { e: [ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ], }, ], }, }, ],} : { b: { c: { d: { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]; }; }[]; }

b: [
>b : { c: { d: { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]; }; }[]
>[ { c: { d: [ { e: [ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ], }, ], }, }, ] : { c: { d: { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]; }; }[]
{
>{ c: { d: [ { e: [ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ], }, ], }, } : { c: { d: { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]; }; }

c: {
>c : { d: { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]; }
>{ d: [ { e: [ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ], }, ], } : { d: { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]; }

d: [
>d : { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]
>[ { e: [ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ], }, ] : { e: { f: { g: { h: {}[]; }; }[]; }[]; }[]
{
>{ e: [ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ], } : { e: { f: { g: { h: {}[]; }; }[]; }[]; }

e: [
>e : { f: { g: { h: {}[]; }; }[]; }[]
>[ { f: [ { g: { h: [ { // i: '', }, ], }, }, ], }, ] : { f: { g: { h: {}[]; }; }[]; }[]
{
>{ f: [ { g: { h: [ { // i: '', }, ], }, }, ], } : { f: { g: { h: {}[]; }; }[]; }

f: [
>f : { g: { h: {}[]; }; }[]
>[ { g: { h: [ { // i: '', }, ], }, }, ] : { g: { h: {}[]; }; }[]
{
>{ g: { h: [ { // i: '', }, ], }, } : { g: { h: {}[]; }; }

g: {
>g : { h: {}[]; }
>{ h: [ { // i: '', }, ], } : { h: {}[]; }

h: [
>h : {}[]
>[ { // i: '', }, ] : {}[]
{
>{ // i: '', } : {}

// i: '',
},
],
},
},
],
},
],
},
],
},
},
],
};

// Repro from 34619

const a1: string[][][][][] = [[[[[42]]]]];
>a1 : string[][][][][]
>[[[[[42]]]]] : number[][][][][]
>[[[[42]]]] : number[][][][]
>[[[42]]] : number[][][]
>[[42]] : number[][]
>[42] : number[]
>42 : 42

const a2: string[][][][][][][][][][] = [[[[[[[[[[42]]]]]]]]]];
>a2 : string[][][][][][][][][][]
>[[[[[[[[[[42]]]]]]]]]] : number[][][][][][][][][][]
>[[[[[[[[[42]]]]]]]]] : number[][][][][][][][][]
>[[[[[[[[42]]]]]]]] : number[][][][][][][][]
>[[[[[[[42]]]]]]] : number[][][][][][][]
>[[[[[[42]]]]]] : number[][][][][][]
>[[[[[42]]]]] : number[][][][][]
>[[[[42]]]] : number[][][][]
>[[[42]]] : number[][][]
>[[42]] : number[][]
>[42] : number[]
>42 : 42

Loading