diff --git a/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.errors.txt b/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.errors.txt index f222f399dabfa..b03c485b178a2 100644 --- a/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.errors.txt +++ b/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.errors.txt @@ -6,9 +6,12 @@ tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(39,9): Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: Schema3; }'. tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(52,9): error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type 'Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example) | ({ type: "boolean"; } & Example); }'. Object literal may only specify known properties, and 'invalid' does not exist in type 'Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example) | ({ type: "boolean"; } & Example); }'. +tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(86,11): error TS2322: Type '{ name: string; children: { name: string; children: { name: string; }[]; }[]; }' is not assignable to type 'User'. + Object literal may only specify known properties, and 'children' does not exist in type 'User'. +tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(102,35): error TS2339: Property 'children' does not exist on type 'User'. -==== tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts (4 errors) ==== +==== tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts (6 errors) ==== // repro from #44750 type Request = { l1: { l2: boolean } }; @@ -81,4 +84,56 @@ tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(52,9): }, }, } + + // repro from #40405 + + type Length = T["length"]; + type Prepend = ((head: V, ...args: T) => void) extends ( + ...args: infer R + ) => void + ? R + : any; + + type BuildTree = { + 1: T; + 0: T & { children: BuildTree>[] }; + }[Length extends N ? 1 : 0]; + + interface User { + name: string; + } + + type GrandUser = BuildTree; + + const grandUser: GrandUser = { + name: "Grand User", + children: [ + { + name: "Son", + children: [ + { + name: "Grand son", + children: [ + ~~~~~~~~ +!!! error TS2322: Type '{ name: string; children: { name: string; children: { name: string; }[]; }[]; }' is not assignable to type 'User'. +!!! error TS2322: Object literal may only specify known properties, and 'children' does not exist in type 'User'. + { + name: "123", + children: [ + { + name: "Some other name", + }, + ], + }, + ], + }, + ], + }, + ], + }; + + grandUser.children[0].children[0].children[0]; + ~~~~~~~~ +!!! error TS2339: Property 'children' does not exist on type 'User'. + \ No newline at end of file diff --git a/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.symbols b/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.symbols index 581bf89beeb68..6b377e44993c1 100644 --- a/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.symbols +++ b/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.symbols @@ -176,3 +176,115 @@ export const schemaObj4: Schema4 = { }, } +// repro from #40405 + +type Length = T["length"]; +>Length : Symbol(Length, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 55, 1)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 59, 12)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 59, 12)) + +type Prepend = ((head: V, ...args: T) => void) extends ( +>Prepend : Symbol(Prepend, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 59, 43)) +>V : Symbol(V, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 13)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 15)) +>head : Symbol(head, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 37)) +>V : Symbol(V, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 13)) +>args : Symbol(args, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 45)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 15)) + + ...args: infer R +>args : Symbol(args, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 60, 76)) +>R : Symbol(R, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 61, 16)) + +) => void + ? R +>R : Symbol(R, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 61, 16)) + + : any; + +type BuildTree = { +>BuildTree : Symbol(BuildTree, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 64, 8)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 15)) +>N : Symbol(N, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 17)) +>I : Symbol(I, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 40)) + + 1: T; +>1 : Symbol(1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 66)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 15)) + + 0: T & { children: BuildTree>[] }; +>0 : Symbol(0, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 67, 7)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 15)) +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 68, 10)) +>BuildTree : Symbol(BuildTree, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 64, 8)) +>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 15)) +>N : Symbol(N, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 17)) +>Prepend : Symbol(Prepend, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 59, 43)) +>I : Symbol(I, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 40)) + +}[Length extends N ? 1 : 0]; +>Length : Symbol(Length, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 55, 1)) +>I : Symbol(I, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 40)) +>N : Symbol(N, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 66, 17)) + +interface User { +>User : Symbol(User, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 69, 31)) + + name: string; +>name : Symbol(User.name, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 71, 16)) +} + +type GrandUser = BuildTree; +>GrandUser : Symbol(GrandUser, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 73, 1)) +>BuildTree : Symbol(BuildTree, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 64, 8)) +>User : Symbol(User, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 69, 31)) + +const grandUser: GrandUser = { +>grandUser : Symbol(grandUser, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 77, 5)) +>GrandUser : Symbol(GrandUser, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 73, 1)) + + name: "Grand User", +>name : Symbol(name, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 77, 30)) + + children: [ +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 78, 21)) + { + name: "Son", +>name : Symbol(name, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 80, 5)) + + children: [ +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 81, 18)) + { + name: "Grand son", +>name : Symbol(name, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 83, 9)) + + children: [ +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 84, 28)) + { + name: "123", +>name : Symbol(name, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 86, 13)) + + children: [ +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 87, 26)) + { + name: "Some other name", +>name : Symbol(name, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 89, 17)) + + }, + ], + }, + ], + }, + ], + }, + ], +}; + +grandUser.children[0].children[0].children[0]; +>grandUser.children[0].children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 68, 10)) +>grandUser.children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 68, 10)) +>grandUser : Symbol(grandUser, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 77, 5)) +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 68, 10)) +>children : Symbol(children, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 68, 10)) + + diff --git a/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.types b/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.types index 0f8126fe44bd8..e3ef29eda26d9 100644 --- a/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.types +++ b/tests/baselines/reference/excessPropertyCheckIntersectionWithRecursiveType.types @@ -154,3 +154,116 @@ export const schemaObj4: Schema4 = { }, } +// repro from #40405 + +type Length = T["length"]; +>Length : Length + +type Prepend = ((head: V, ...args: T) => void) extends ( +>Prepend : [head: V, ...args: T] +>head : V +>args : T + + ...args: infer R +>args : R + +) => void + ? R + : any; + +type BuildTree = { +>BuildTree : BuildTree +>-1 : -1 +>1 : 1 + + 1: T; +>1 : T + + 0: T & { children: BuildTree>[] }; +>0 : T & { children: BuildTree>[]; } +>children : BuildTree[] + +}[Length extends N ? 1 : 0]; + +interface User { + name: string; +>name : string +} + +type GrandUser = BuildTree; +>GrandUser : User & { children: (User & { children: User[]; })[]; } + +const grandUser: GrandUser = { +>grandUser : User & { children: (User & { children: User[]; })[]; } +>{ name: "Grand User", children: [ { name: "Son", children: [ { name: "Grand son", children: [ { name: "123", children: [ { name: "Some other name", }, ], }, ], }, ], }, ],} : { name: string; children: { name: string; children: { name: string; children: { name: string; children: { name: string; }[]; }[]; }[]; }[]; } + + name: "Grand User", +>name : string +>"Grand User" : "Grand User" + + children: [ +>children : { name: string; children: { name: string; children: { name: string; children: { name: string; }[]; }[]; }[]; }[] +>[ { name: "Son", children: [ { name: "Grand son", children: [ { name: "123", children: [ { name: "Some other name", }, ], }, ], }, ], }, ] : { name: string; children: { name: string; children: { name: string; children: { name: string; }[]; }[]; }[]; }[] + { +>{ name: "Son", children: [ { name: "Grand son", children: [ { name: "123", children: [ { name: "Some other name", }, ], }, ], }, ], } : { name: string; children: { name: string; children: { name: string; children: { name: string; }[]; }[]; }[]; } + + name: "Son", +>name : string +>"Son" : "Son" + + children: [ +>children : { name: string; children: { name: string; children: { name: string; }[]; }[]; }[] +>[ { name: "Grand son", children: [ { name: "123", children: [ { name: "Some other name", }, ], }, ], }, ] : { name: string; children: { name: string; children: { name: string; }[]; }[]; }[] + { +>{ name: "Grand son", children: [ { name: "123", children: [ { name: "Some other name", }, ], }, ], } : { name: string; children: { name: string; children: { name: string; }[]; }[]; } + + name: "Grand son", +>name : string +>"Grand son" : "Grand son" + + children: [ +>children : { name: string; children: { name: string; }[]; }[] +>[ { name: "123", children: [ { name: "Some other name", }, ], }, ] : { name: string; children: { name: string; }[]; }[] + { +>{ name: "123", children: [ { name: "Some other name", }, ], } : { name: string; children: { name: string; }[]; } + + name: "123", +>name : string +>"123" : "123" + + children: [ +>children : { name: string; }[] +>[ { name: "Some other name", }, ] : { name: string; }[] + { +>{ name: "Some other name", } : { name: string; } + + name: "Some other name", +>name : string +>"Some other name" : "Some other name" + + }, + ], + }, + ], + }, + ], + }, + ], +}; + +grandUser.children[0].children[0].children[0]; +>grandUser.children[0].children[0].children[0] : any +>grandUser.children[0].children[0].children : any +>grandUser.children[0].children[0] : User +>grandUser.children[0].children : User[] +>grandUser.children[0] : User & { children: User[]; } +>grandUser.children : (User & { children: User[]; })[] +>grandUser : User & { children: (User & { children: User[]; })[]; } +>children : (User & { children: User[]; })[] +>0 : 0 +>children : User[] +>0 : 0 +>children : any +>0 : 0 + + diff --git a/tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts b/tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts index 187ed70e80721..85b569ac13791 100644 --- a/tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts +++ b/tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts @@ -57,3 +57,50 @@ export const schemaObj4: Schema4 = { }, }, } + +// repro from #40405 + +type Length = T["length"]; +type Prepend = ((head: V, ...args: T) => void) extends ( + ...args: infer R +) => void + ? R + : any; + +type BuildTree = { + 1: T; + 0: T & { children: BuildTree>[] }; +}[Length extends N ? 1 : 0]; + +interface User { + name: string; +} + +type GrandUser = BuildTree; + +const grandUser: GrandUser = { + name: "Grand User", + children: [ + { + name: "Son", + children: [ + { + name: "Grand son", + children: [ + { + name: "123", + children: [ + { + name: "Some other name", + }, + ], + }, + ], + }, + ], + }, + ], +}; + +grandUser.children[0].children[0].children[0]; +