mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Add tests for excess property check for intersection containing a recursive type (#52063)
This commit is contained in:
parent
6bedd1c227
commit
9b718d0a70
@ -0,0 +1,84 @@
|
||||
tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(13,9): error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type '{ l2: Schema1<boolean>; }'.
|
||||
Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: Schema1<boolean>; }'.
|
||||
tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(26,9): error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type '{ l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts(39,9): error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type '{ l2: Schema3<boolean>; }'.
|
||||
Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: Schema3<boolean>; }'.
|
||||
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<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
Object literal may only specify known properties, and 'invalid' does not exist in type 'Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts (4 errors) ====
|
||||
// repro from #44750
|
||||
|
||||
type Request = { l1: { l2: boolean } };
|
||||
type Example<T> = { ex?: T | null };
|
||||
|
||||
type Schema1<T> = (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema1<T[P]> }; }) & Example<T>;
|
||||
|
||||
export const schemaObj1: Schema1<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type '{ l2: Schema1<boolean>; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: Schema1<boolean>; }'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts:6:65: The expected type comes from property 'props' which is declared here on type 'Schema1<{ l2: boolean; }>'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema2<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: { [P in keyof T]: Schema2<T[P]> }; } & Example<T>);
|
||||
|
||||
export const schemaObj2: Schema2<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type '{ l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts:19:78: The expected type comes from property 'props' which is declared here on type '{ props: { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }; } & Example<{ l2: boolean; }>'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema3<T> = Example<T> & (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema3<T[P]> }; });
|
||||
|
||||
export const schemaObj3: Schema3<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type '{ l2: Schema3<boolean>; }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'invalid' does not exist in type '{ l2: Schema3<boolean>; }'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts:32:78: The expected type comes from property 'props' which is declared here on type 'Schema3<{ l2: boolean; }>'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema4<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: Example<T> & { [P in keyof T]: Schema4<T[P]> }; });
|
||||
|
||||
export const schemaObj4: Schema4<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ l2: { type: "boolean"; }; invalid: false; }' is not assignable to type 'Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
!!! error TS2322: Object literal may only specify known properties, and 'invalid' does not exist in type 'Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }'.
|
||||
!!! related TS6500 tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts:45:78: The expected type comes from property 'props' which is declared here on type '{ props: Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }; }'
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -0,0 +1,178 @@
|
||||
=== tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts ===
|
||||
// repro from #44750
|
||||
|
||||
type Request = { l1: { l2: boolean } };
|
||||
>Request : Symbol(Request, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 0, 0))
|
||||
>l1 : Symbol(l1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 16))
|
||||
>l2 : Symbol(l2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 22))
|
||||
|
||||
type Example<T> = { ex?: T | null };
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 3, 13))
|
||||
>ex : Symbol(ex, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 3, 19))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 3, 13))
|
||||
|
||||
type Schema1<T> = (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema1<T[P]> }; }) & Example<T>;
|
||||
>Schema1 : Symbol(Schema1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 3, 36))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 13))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 13))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 40))
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 63))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 74))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 13))
|
||||
>Schema1 : Symbol(Schema1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 3, 36))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 13))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 74))
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 5, 13))
|
||||
|
||||
export const schemaObj1: Schema1<Request> = {
|
||||
>schemaObj1 : Symbol(schemaObj1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 7, 12))
|
||||
>Schema1 : Symbol(Schema1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 3, 36))
|
||||
>Request : Symbol(Request, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 0, 0))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 7, 45))
|
||||
|
||||
l1: {
|
||||
>l1 : Symbol(l1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 8, 10))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 9, 9))
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : Symbol(l2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 10, 14))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 11, 13))
|
||||
|
||||
invalid: false,
|
||||
>invalid : Symbol(invalid, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 11, 32))
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema2<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: { [P in keyof T]: Schema2<T[P]> }; } & Example<T>);
|
||||
>Schema2 : Symbol(Schema2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 16, 1))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 13))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 13))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 40))
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 13))
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 76))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 87))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 13))
|
||||
>Schema2 : Symbol(Schema2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 16, 1))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 13))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 87))
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 18, 13))
|
||||
|
||||
export const schemaObj2: Schema2<Request> = {
|
||||
>schemaObj2 : Symbol(schemaObj2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 20, 12))
|
||||
>Schema2 : Symbol(Schema2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 16, 1))
|
||||
>Request : Symbol(Request, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 0, 0))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 20, 45))
|
||||
|
||||
l1: {
|
||||
>l1 : Symbol(l1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 21, 10))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 22, 9))
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : Symbol(l2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 23, 14))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 24, 13))
|
||||
|
||||
invalid: false,
|
||||
>invalid : Symbol(invalid, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 24, 32))
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema3<T> = Example<T> & (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema3<T[P]> }; });
|
||||
>Schema3 : Symbol(Schema3, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 29, 1))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 13))
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 13))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 13))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 53))
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 76))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 87))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 13))
|
||||
>Schema3 : Symbol(Schema3, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 29, 1))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 13))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 31, 87))
|
||||
|
||||
export const schemaObj3: Schema3<Request> = {
|
||||
>schemaObj3 : Symbol(schemaObj3, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 33, 12))
|
||||
>Schema3 : Symbol(Schema3, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 29, 1))
|
||||
>Request : Symbol(Request, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 0, 0))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 33, 45))
|
||||
|
||||
l1: {
|
||||
>l1 : Symbol(l1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 34, 10))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 35, 9))
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : Symbol(l2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 36, 14))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 37, 13))
|
||||
|
||||
invalid: false,
|
||||
>invalid : Symbol(invalid, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 37, 32))
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema4<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: Example<T> & { [P in keyof T]: Schema4<T[P]> }; });
|
||||
>Schema4 : Symbol(Schema4, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 42, 1))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 13))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 13))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 40))
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 13))
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 76))
|
||||
>Example : Symbol(Example, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 2, 39))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 13))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 100))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 13))
|
||||
>Schema4 : Symbol(Schema4, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 42, 1))
|
||||
>T : Symbol(T, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 13))
|
||||
>P : Symbol(P, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 44, 100))
|
||||
|
||||
export const schemaObj4: Schema4<Request> = {
|
||||
>schemaObj4 : Symbol(schemaObj4, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 46, 12))
|
||||
>Schema4 : Symbol(Schema4, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 42, 1))
|
||||
>Request : Symbol(Request, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 0, 0))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 46, 45))
|
||||
|
||||
l1: {
|
||||
>l1 : Symbol(l1, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 47, 10))
|
||||
|
||||
props: {
|
||||
>props : Symbol(props, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 48, 9))
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : Symbol(l2, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 49, 14))
|
||||
>type : Symbol(type, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 50, 13))
|
||||
|
||||
invalid: false,
|
||||
>invalid : Symbol(invalid, Decl(excessPropertyCheckIntersectionWithRecursiveType.ts, 50, 32))
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -0,0 +1,157 @@
|
||||
=== tests/cases/compiler/excessPropertyCheckIntersectionWithRecursiveType.ts ===
|
||||
// repro from #44750
|
||||
|
||||
type Request = { l1: { l2: boolean } };
|
||||
>Request : { l1: { l2: boolean;}; }
|
||||
>l1 : { l2: boolean; }
|
||||
>l2 : boolean
|
||||
|
||||
type Example<T> = { ex?: T | null };
|
||||
>Example : Example<T>
|
||||
>ex : T | null | undefined
|
||||
>null : null
|
||||
|
||||
type Schema1<T> = (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema1<T[P]> }; }) & Example<T>;
|
||||
>Schema1 : Schema1<T>
|
||||
>type : "boolean"
|
||||
>props : { [P in keyof T]: Schema1<T[P]>; }
|
||||
|
||||
export const schemaObj1: Schema1<Request> = {
|
||||
>schemaObj1 : Schema1<Request>
|
||||
>{ props: { l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, },} : { props: { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }; }
|
||||
|
||||
props: {
|
||||
>props : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
>{ l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, } : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
|
||||
l1: {
|
||||
>l1 : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
>{ props: { l2: { type: 'boolean' }, invalid: false, }, } : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
|
||||
props: {
|
||||
>props : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
>{ l2: { type: 'boolean' }, invalid: false, } : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : { type: "boolean"; }
|
||||
>{ type: 'boolean' } : { type: "boolean"; }
|
||||
>type : "boolean"
|
||||
>'boolean' : "boolean"
|
||||
|
||||
invalid: false,
|
||||
>invalid : boolean
|
||||
>false : false
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema2<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: { [P in keyof T]: Schema2<T[P]> }; } & Example<T>);
|
||||
>Schema2 : Schema2<T>
|
||||
>type : "boolean"
|
||||
>props : { [P in keyof T]: Schema2<T[P]>; }
|
||||
|
||||
export const schemaObj2: Schema2<Request> = {
|
||||
>schemaObj2 : { props: { l1: { props: { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }; } & Example<{ l2: boolean; }>; }; } & Example<Request>
|
||||
>{ props: { l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, },} : { props: { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }; }
|
||||
|
||||
props: {
|
||||
>props : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
>{ l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, } : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
|
||||
l1: {
|
||||
>l1 : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
>{ props: { l2: { type: 'boolean' }, invalid: false, }, } : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
|
||||
props: {
|
||||
>props : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
>{ l2: { type: 'boolean' }, invalid: false, } : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : { type: "boolean"; }
|
||||
>{ type: 'boolean' } : { type: "boolean"; }
|
||||
>type : "boolean"
|
||||
>'boolean' : "boolean"
|
||||
|
||||
invalid: false,
|
||||
>invalid : boolean
|
||||
>false : false
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema3<T> = Example<T> & (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema3<T[P]> }; });
|
||||
>Schema3 : Schema3<T>
|
||||
>type : "boolean"
|
||||
>props : { [P in keyof T]: Schema3<T[P]>; }
|
||||
|
||||
export const schemaObj3: Schema3<Request> = {
|
||||
>schemaObj3 : Schema3<Request>
|
||||
>{ props: { l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, },} : { props: { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }; }
|
||||
|
||||
props: {
|
||||
>props : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
>{ l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, } : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
|
||||
l1: {
|
||||
>l1 : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
>{ props: { l2: { type: 'boolean' }, invalid: false, }, } : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
|
||||
props: {
|
||||
>props : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
>{ l2: { type: 'boolean' }, invalid: false, } : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : { type: "boolean"; }
|
||||
>{ type: 'boolean' } : { type: "boolean"; }
|
||||
>type : "boolean"
|
||||
>'boolean' : "boolean"
|
||||
|
||||
invalid: false,
|
||||
>invalid : boolean
|
||||
>false : false
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema4<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: Example<T> & { [P in keyof T]: Schema4<T[P]> }; });
|
||||
>Schema4 : Schema4<T>
|
||||
>type : "boolean"
|
||||
>props : Example<T> & { [P in keyof T]: Schema4<T[P]>; }
|
||||
|
||||
export const schemaObj4: Schema4<Request> = {
|
||||
>schemaObj4 : { props: Example<Request> & { l1: { props: Example<{ l2: boolean; }> & { l2: ({ type: "boolean"; } & Example<false>) | ({ type: "boolean"; } & Example<true>); }; }; }; }
|
||||
>{ props: { l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, },} : { props: { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }; }
|
||||
|
||||
props: {
|
||||
>props : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
>{ l1: { props: { l2: { type: 'boolean' }, invalid: false, }, }, } : { l1: { props: { l2: { type: "boolean"; }; invalid: boolean; }; }; }
|
||||
|
||||
l1: {
|
||||
>l1 : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
>{ props: { l2: { type: 'boolean' }, invalid: false, }, } : { props: { l2: { type: "boolean"; }; invalid: boolean; }; }
|
||||
|
||||
props: {
|
||||
>props : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
>{ l2: { type: 'boolean' }, invalid: false, } : { l2: { type: "boolean"; }; invalid: boolean; }
|
||||
|
||||
l2: { type: 'boolean' },
|
||||
>l2 : { type: "boolean"; }
|
||||
>{ type: 'boolean' } : { type: "boolean"; }
|
||||
>type : "boolean"
|
||||
>'boolean' : "boolean"
|
||||
|
||||
invalid: false,
|
||||
>invalid : boolean
|
||||
>false : false
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// repro from #44750
|
||||
|
||||
type Request = { l1: { l2: boolean } };
|
||||
type Example<T> = { ex?: T | null };
|
||||
|
||||
type Schema1<T> = (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema1<T[P]> }; }) & Example<T>;
|
||||
|
||||
export const schemaObj1: Schema1<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema2<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: { [P in keyof T]: Schema2<T[P]> }; } & Example<T>);
|
||||
|
||||
export const schemaObj2: Schema2<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema3<T> = Example<T> & (T extends boolean ? { type: 'boolean'; } : { props: { [P in keyof T]: Schema3<T[P]> }; });
|
||||
|
||||
export const schemaObj3: Schema3<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Schema4<T> = (T extends boolean ? { type: 'boolean'; } & Example<T> : { props: Example<T> & { [P in keyof T]: Schema4<T[P]> }; });
|
||||
|
||||
export const schemaObj4: Schema4<Request> = {
|
||||
props: {
|
||||
l1: {
|
||||
props: {
|
||||
l2: { type: 'boolean' },
|
||||
invalid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user