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

* Exclude types originating in literals from recursion depth limiter check

* Add tests

* Accept new baselines

* Remove superfluous test
This commit is contained in:
Anders Hejlsberg 2019-10-31 06:14:43 -07:00 committed by GitHub
parent 234680851b
commit 9ff378aab3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 385 additions and 1 deletions

View file

@ -16346,7 +16346,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;

View file

@ -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'.

View file

@ -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]]]]]]]]]];

View file

@ -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))

View file

@ -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

View file

@ -7,3 +7,47 @@ 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]]]]]]]]]];