diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16fb7b31797ae..ba982a4d11193 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18903,6 +18903,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getIndexType(type: Type, indexFlags = IndexFlags.None): Type { type = getReducedType(type); return isNoInferType(type) ? getNoInferType(getIndexType((type as SubstitutionType).baseType, indexFlags)) : + type.flags & TypeFlags.Substitution && !isGenericType((type as SubstitutionType).baseType) && !isGenericType((type as SubstitutionType).constraint) ? getUnionType([getIndexType((type as SubstitutionType).baseType, indexFlags), getIndexType((type as SubstitutionType).constraint, indexFlags)]) : shouldDeferIndexType(type, indexFlags) ? getIndexTypeForGenericType(type as InstantiableType | UnionOrIntersectionType, indexFlags) : type.flags & TypeFlags.Union ? getIntersectionType(map((type as UnionType).types, t => getIndexType(t, indexFlags))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type as IntersectionType).types, t => getIndexType(t, indexFlags))) : diff --git a/tests/baselines/reference/substitutionTypeNonGenericIndexType1.symbols b/tests/baselines/reference/substitutionTypeNonGenericIndexType1.symbols new file mode 100644 index 0000000000000..7ca5986fa6817 --- /dev/null +++ b/tests/baselines/reference/substitutionTypeNonGenericIndexType1.symbols @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts] //// + +=== substitutionTypeNonGenericIndexType1.ts === +// https://github.com/microsoft/TypeScript/issues/61728 + +type BasicConditional = keyof T extends any +>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType1.ts, 0, 0)) +>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType1.ts, 2, 22)) +>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType1.ts, 2, 22)) + + ? true + : false; + +type Config = { rejectClose: true }; +>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType1.ts, 4, 10)) +>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType1.ts, 6, 15)) + +type Test = +>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType1.ts, 6, 36)) + + Config extends {} +>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType1.ts, 4, 10)) + + ? { + rejectClose: BasicConditional; +>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType1.ts, 9, 7)) +>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType1.ts, 0, 0)) +>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType1.ts, 4, 10)) + } + : never; + +type RejectClose = Test["rejectClose"]; +>RejectClose : Symbol(RejectClose, Decl(substitutionTypeNonGenericIndexType1.ts, 12, 12)) +>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType1.ts, 6, 36)) + diff --git a/tests/baselines/reference/substitutionTypeNonGenericIndexType1.types b/tests/baselines/reference/substitutionTypeNonGenericIndexType1.types new file mode 100644 index 0000000000000..e511332ee5c9b --- /dev/null +++ b/tests/baselines/reference/substitutionTypeNonGenericIndexType1.types @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts] //// + +=== substitutionTypeNonGenericIndexType1.ts === +// https://github.com/microsoft/TypeScript/issues/61728 + +type BasicConditional = keyof T extends any +>BasicConditional : BasicConditional +> : ^^^^^^^^^^^^^^^^^^^ + + ? true +>true : true +> : ^^^^ + + : false; +>false : false +> : ^^^^^ + +type Config = { rejectClose: true }; +>Config : Config +> : ^^^^^^ +>rejectClose : true +> : ^^^^ +>true : true +> : ^^^^ + +type Test = +>Test : { rejectClose: BasicConditional; } +> : ^^^^^^^^^^^^^^^ ^^^ + + Config extends {} + ? { + rejectClose: BasicConditional; +>rejectClose : true +> : ^^^^ + } + : never; + +type RejectClose = Test["rejectClose"]; +>RejectClose : true +> : ^^^^ + diff --git a/tests/baselines/reference/substitutionTypeNonGenericIndexType2.symbols b/tests/baselines/reference/substitutionTypeNonGenericIndexType2.symbols new file mode 100644 index 0000000000000..b1801fd76cf52 --- /dev/null +++ b/tests/baselines/reference/substitutionTypeNonGenericIndexType2.symbols @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts] //// + +=== substitutionTypeNonGenericIndexType2.ts === +type BasicConditional = keyof T extends infer R ? R : never; +>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 0)) +>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 22)) +>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 22)) +>R : Symbol(R, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 48)) +>R : Symbol(R, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 48)) + +type Config = { rejectClose: true }; +>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 63)) +>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType2.ts, 2, 15)) + +type Test = Config extends {} +>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType2.ts, 2, 36)) +>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 63)) + + ? { + rejectClose: BasicConditional; +>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType2.ts, 5, 5)) +>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 0)) +>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 63)) + } + : never; + +const test: Test["rejectClose"] = "rejectClose"; +>test : Symbol(test, Decl(substitutionTypeNonGenericIndexType2.ts, 10, 5)) +>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType2.ts, 2, 36)) + diff --git a/tests/baselines/reference/substitutionTypeNonGenericIndexType2.types b/tests/baselines/reference/substitutionTypeNonGenericIndexType2.types new file mode 100644 index 0000000000000..ff8895db9b950 --- /dev/null +++ b/tests/baselines/reference/substitutionTypeNonGenericIndexType2.types @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts] //// + +=== substitutionTypeNonGenericIndexType2.ts === +type BasicConditional = keyof T extends infer R ? R : never; +>BasicConditional : BasicConditional +> : ^^^^^^^^^^^^^^^^^^^ + +type Config = { rejectClose: true }; +>Config : Config +> : ^^^^^^ +>rejectClose : true +> : ^^^^ +>true : true +> : ^^^^ + +type Test = Config extends {} +>Test : { rejectClose: BasicConditional; } +> : ^^^^^^^^^^^^^^^ ^^^ + + ? { + rejectClose: BasicConditional; +>rejectClose : "rejectClose" +> : ^^^^^^^^^^^^^ + } + : never; + +const test: Test["rejectClose"] = "rejectClose"; +>test : "rejectClose" +> : ^^^^^^^^^^^^^ +>"rejectClose" : "rejectClose" +> : ^^^^^^^^^^^^^ + diff --git a/tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts b/tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts new file mode 100644 index 0000000000000..bd9a75f23f103 --- /dev/null +++ b/tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts @@ -0,0 +1,18 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/61728 + +type BasicConditional = keyof T extends any + ? true + : false; + +type Config = { rejectClose: true }; +type Test = + Config extends {} + ? { + rejectClose: BasicConditional; + } + : never; + +type RejectClose = Test["rejectClose"]; diff --git a/tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts b/tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts new file mode 100644 index 0000000000000..fdc159e353c3f --- /dev/null +++ b/tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts @@ -0,0 +1,14 @@ +// @strict: true +// @noEmit: true + +type BasicConditional = keyof T extends infer R ? R : never; + +type Config = { rejectClose: true }; + +type Test = Config extends {} + ? { + rejectClose: BasicConditional; + } + : never; + +const test: Test["rejectClose"] = "rejectClose";