From 68585f2a1e964bc9a8dccf9c7a6bb6c82498b6c6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 17 Apr 2019 11:20:50 -0700 Subject: [PATCH 1/4] Ignore string (but keep numeric) index signatures coming from constraints --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0c91e1ba06208..0a025f29c20c4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9864,13 +9864,13 @@ namespace ts { return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : - getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number))) : + getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) : type === wildcardType ? wildcardType : type.flags & TypeFlags.Unknown ? neverType : type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType : stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) : !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) : - !noIndexSignatures && getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : + getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique); } @@ -9988,10 +9988,10 @@ namespace ts { if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { return objectType; } - const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || - getIndexInfoOfType(objectType, IndexKind.String); + const stringIndexInfo = getIndexInfoOfType(objectType, IndexKind.String); + const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || stringIndexInfo; if (indexInfo) { - if (accessFlags & AccessFlags.NoIndexSignatures) { + if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo === stringIndexInfo) { if (accessExpression) { error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType)); } From 07d259593a78815b8fdc00c6c2db4f5ffa602cfb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 17 Apr 2019 12:37:01 -0700 Subject: [PATCH 2/4] Add regression test --- .../conformance/types/keyof/keyofAndIndexedAccess2.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts index 2d96e20f12a9d..2d63e5681bab6 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts @@ -110,3 +110,13 @@ interface Type { function get123(): Type[K] { return 123; // Error } + +// Repros from #30938 + +function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { + cb(param.elements[0]); +} + +function fn2>(param: T, cb: (element: T[number]) => void) { + cb(param[0]); +} From f9a55ac55ec1b99e4f2a835040bce1441aefc9a0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 17 Apr 2019 12:37:10 -0700 Subject: [PATCH 3/4] Accept new baselines --- .../keyofAndIndexedAccess2.errors.txt | 10 +++++ .../reference/keyofAndIndexedAccess2.js | 17 +++++++++ .../reference/keyofAndIndexedAccess2.symbols | 37 +++++++++++++++++++ .../reference/keyofAndIndexedAccess2.types | 34 +++++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt index 6e1b87a72e38d..ba2fe38c1451b 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt @@ -187,4 +187,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23 !!! error TS2322: Type '123' is not assignable to type '123 & "some string"'. !!! error TS2322: Type '123' is not assignable to type '"some string"'. } + + // Repros from #30938 + + function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { + cb(param.elements[0]); + } + + function fn2>(param: T, cb: (element: T[number]) => void) { + cb(param[0]); + } \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.js b/tests/baselines/reference/keyofAndIndexedAccess2.js index 8dad708c2988c..2ef82b3d68efd 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.js +++ b/tests/baselines/reference/keyofAndIndexedAccess2.js @@ -108,6 +108,16 @@ interface Type { function get123(): Type[K] { return 123; // Error } + +// Repros from #30938 + +function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { + cb(param.elements[0]); +} + +function fn2>(param: T, cb: (element: T[number]) => void) { + cb(param[0]); +} //// [keyofAndIndexedAccess2.js] @@ -183,3 +193,10 @@ export function getEntity(id, state) { function get123() { return 123; // Error } +// Repros from #30938 +function fn(param, cb) { + cb(param.elements[0]); +} +function fn2(param, cb) { + cb(param[0]); +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.symbols b/tests/baselines/reference/keyofAndIndexedAccess2.symbols index 803700efa372a..5113eb736db5d 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess2.symbols @@ -388,3 +388,40 @@ function get123(): Type[K] { return 123; // Error } +// Repros from #30938 + +function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { +>fn : Symbol(fn, Decl(keyofAndIndexedAccess2.ts, 108, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 112, 12)) +>elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 23)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 51)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 112, 77)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 112, 12)) +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 112, 86)) +>element : Symbol(element, Decl(keyofAndIndexedAccess2.ts, 112, 92)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 112, 12)) + + cb(param.elements[0]); +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 112, 86)) +>param.elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 23), Decl(keyofAndIndexedAccess2.ts, 112, 51)) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 112, 77)) +>elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 23), Decl(keyofAndIndexedAccess2.ts, 112, 51)) +} + +function fn2>(param: T, cb: (element: T[number]) => void) { +>fn2 : Symbol(fn2, Decl(keyofAndIndexedAccess2.ts, 114, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 116, 13)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 116, 38)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 116, 13)) +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 116, 47)) +>element : Symbol(element, Decl(keyofAndIndexedAccess2.ts, 116, 53)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 116, 13)) + + cb(param[0]); +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 116, 47)) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 116, 38)) +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.types b/tests/baselines/reference/keyofAndIndexedAccess2.types index 5f5b80a481911..286db62e4b565 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.types +++ b/tests/baselines/reference/keyofAndIndexedAccess2.types @@ -423,3 +423,37 @@ function get123(): Type[K] { >123 : 123 } +// Repros from #30938 + +function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { +>fn : (param: T, cb: (element: T["elements"][number]) => void) => void +>elements : string[] +>elements : number[] +>param : T +>cb : (element: T["elements"][number]) => void +>element : T["elements"][number] + + cb(param.elements[0]); +>cb(param.elements[0]) : void +>cb : (element: T["elements"][number]) => void +>param.elements[0] : string | number +>param.elements : string[] | number[] +>param : T +>elements : string[] | number[] +>0 : 0 +} + +function fn2>(param: T, cb: (element: T[number]) => void) { +>fn2 : (param: T, cb: (element: T[number]) => void) => void +>param : T +>cb : (element: T[number]) => void +>element : T[number] + + cb(param[0]); +>cb(param[0]) : void +>cb : (element: T[number]) => void +>param[0] : string +>param : T +>0 : 0 +} + From 4ce0d202e9eab846e6c60eda3cc8c39adc001415 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 18 Apr 2019 11:39:36 -0700 Subject: [PATCH 4/4] Accept new baselines --- .../keyofAndIndexedAccess2.errors.txt | 16 ++-- .../reference/keyofAndIndexedAccess2.js | 16 ++-- .../reference/keyofAndIndexedAccess2.symbols | 76 +++++++++---------- .../reference/keyofAndIndexedAccess2.types | 30 ++++---- 4 files changed, 65 insertions(+), 73 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt index 8b018263a4b1e..9a937066374ab 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt @@ -188,7 +188,13 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23 !!! error TS2322: Type '123' is not assignable to type '"some string"'. } -<<<<<<< HEAD + // Repro from #30920 + + type StrictExtract = T extends U ? U extends T ? T : never : never; + type StrictExclude = T extends StrictExtract ? never : T; + type A = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; }; + type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; + // Repros from #30938 function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { @@ -198,12 +204,4 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23 function fn2>(param: T, cb: (element: T[number]) => void) { cb(param[0]); } -======= - // Repro from #30920 - - type StrictExtract = T extends U ? U extends T ? T : never : never; - type StrictExclude = T extends StrictExtract ? never : T; - type A = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; }; - type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; ->>>>>>> master \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.js b/tests/baselines/reference/keyofAndIndexedAccess2.js index 9956a17bf4748..906bcd0eab3de 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.js +++ b/tests/baselines/reference/keyofAndIndexedAccess2.js @@ -109,7 +109,13 @@ function get123(): Type[K] { return 123; // Error } -<<<<<<< HEAD +// Repro from #30920 + +type StrictExtract = T extends U ? U extends T ? T : never : never; +type StrictExclude = T extends StrictExtract ? never : T; +type A = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; }; +type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; + // Repros from #30938 function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { @@ -119,14 +125,6 @@ function fn} | {elements: Array}>(par function fn2>(param: T, cb: (element: T[number]) => void) { cb(param[0]); } -======= -// Repro from #30920 - -type StrictExtract = T extends U ? U extends T ? T : never : never; -type StrictExclude = T extends StrictExtract ? never : T; -type A = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; }; -type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; ->>>>>>> master //// [keyofAndIndexedAccess2.js] diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.symbols b/tests/baselines/reference/keyofAndIndexedAccess2.symbols index e0eb723649a4c..24e1a8b0674e7 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess2.symbols @@ -388,44 +388,6 @@ function get123(): Type[K] { return 123; // Error } -<<<<<<< HEAD -// Repros from #30938 - -function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { ->fn : Symbol(fn, Decl(keyofAndIndexedAccess2.ts, 108, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 112, 12)) ->elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 23)) ->Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) ->elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 51)) ->Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) ->param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 112, 77)) ->T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 112, 12)) ->cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 112, 86)) ->element : Symbol(element, Decl(keyofAndIndexedAccess2.ts, 112, 92)) ->T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 112, 12)) - - cb(param.elements[0]); ->cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 112, 86)) ->param.elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 23), Decl(keyofAndIndexedAccess2.ts, 112, 51)) ->param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 112, 77)) ->elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 112, 23), Decl(keyofAndIndexedAccess2.ts, 112, 51)) -} - -function fn2>(param: T, cb: (element: T[number]) => void) { ->fn2 : Symbol(fn2, Decl(keyofAndIndexedAccess2.ts, 114, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 116, 13)) ->Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) ->param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 116, 38)) ->T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 116, 13)) ->cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 116, 47)) ->element : Symbol(element, Decl(keyofAndIndexedAccess2.ts, 116, 53)) ->T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 116, 13)) - - cb(param[0]); ->cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 116, 47)) ->param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 116, 38)) -} -======= // Repro from #30920 type StrictExtract = T extends U ? U extends T ? T : never : never; @@ -471,5 +433,41 @@ type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; >T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 115, 7)) >Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 115, 20)) >V : Symbol(V, Decl(keyofAndIndexedAccess2.ts, 115, 9)) ->>>>>>> master + +// Repros from #30938 + +function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { +>fn : Symbol(fn, Decl(keyofAndIndexedAccess2.ts, 115, 69)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 119, 12)) +>elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 119, 23)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 119, 51)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 119, 77)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 119, 12)) +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 119, 86)) +>element : Symbol(element, Decl(keyofAndIndexedAccess2.ts, 119, 92)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 119, 12)) + + cb(param.elements[0]); +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 119, 86)) +>param.elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 119, 23), Decl(keyofAndIndexedAccess2.ts, 119, 51)) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 119, 77)) +>elements : Symbol(elements, Decl(keyofAndIndexedAccess2.ts, 119, 23), Decl(keyofAndIndexedAccess2.ts, 119, 51)) +} + +function fn2>(param: T, cb: (element: T[number]) => void) { +>fn2 : Symbol(fn2, Decl(keyofAndIndexedAccess2.ts, 121, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 123, 13)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 123, 38)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 123, 13)) +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 123, 47)) +>element : Symbol(element, Decl(keyofAndIndexedAccess2.ts, 123, 53)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 123, 13)) + + cb(param[0]); +>cb : Symbol(cb, Decl(keyofAndIndexedAccess2.ts, 123, 47)) +>param : Symbol(param, Decl(keyofAndIndexedAccess2.ts, 123, 38)) +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.types b/tests/baselines/reference/keyofAndIndexedAccess2.types index 16bd970d341c8..6c0f3dff934d8 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.types +++ b/tests/baselines/reference/keyofAndIndexedAccess2.types @@ -423,7 +423,20 @@ function get123(): Type[K] { >123 : 123 } -<<<<<<< HEAD +// Repro from #30920 + +type StrictExtract = T extends U ? U extends T ? T : never : never; +>StrictExtract : StrictExtract + +type StrictExclude = T extends StrictExtract ? never : T; +>StrictExclude : StrictExclude + +type A = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; }; +>A : A + +type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; +>B : A<{ [Q in keyof T]: StrictExclude, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }> + // Repros from #30938 function fn} | {elements: Array}>(param: T, cb: (element: T['elements'][number]) => void) { @@ -457,19 +470,4 @@ function fn2>(param: T, cb: (element: T[number]) => void >param : T >0 : 0 } -======= -// Repro from #30920 - -type StrictExtract = T extends U ? U extends T ? T : never : never; ->StrictExtract : StrictExtract - -type StrictExclude = T extends StrictExtract ? never : T; ->StrictExclude : StrictExclude - -type A = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; }; ->A : A - -type B = A<{ [Q in keyof T]: StrictExclude, {}>; }>; ->B : A<{ [Q in keyof T]: StrictExclude, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }> ->>>>>>> master