diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0b67afefbb9d8..1a1206fae9cc3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17951,6 +17951,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { result.aliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(root.aliasTypeArguments, mapper!); // TODO: GH#18217 break; } + if (result.flags & TypeFlags.Substitution) { + const substitution = result as SubstitutionType; + result = getIntersectionType([substitution.baseType, substitution.constraint]); + } return extraTypes ? getUnionType(append(extraTypes, result)) : result; // We tail-recurse for generic conditional types that (a) have not already been evaluated and cached, and // (b) are non distributive, have a check type that is unaffected by instantiation, or have a non-union check diff --git a/tests/baselines/reference/substitutionTypeUsedAsIndex.symbols b/tests/baselines/reference/substitutionTypeUsedAsIndex.symbols new file mode 100644 index 0000000000000..bf6174ffdfc46 --- /dev/null +++ b/tests/baselines/reference/substitutionTypeUsedAsIndex.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/substitutionTypeUsedAsIndex.ts] //// + +=== substitutionTypeUsedAsIndex.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54886 + +interface Dict_54886 { +>Dict_54886 : Symbol(Dict_54886, Decl(substitutionTypeUsedAsIndex.ts, 0, 0)) + + foo: 1; +>foo : Symbol(Dict_54886.foo, Decl(substitutionTypeUsedAsIndex.ts, 2, 22)) + + bar: 1; +>bar : Symbol(Dict_54886.bar, Decl(substitutionTypeUsedAsIndex.ts, 3, 9)) +} + +type FF_54886 = "foo" extends "foo" | "bar" ? "foo" : never; +>FF_54886 : Symbol(FF_54886, Decl(substitutionTypeUsedAsIndex.ts, 5, 1)) + +type C_54886 = Dict_54886[FF_54886]; // ok +>C_54886 : Symbol(C_54886, Decl(substitutionTypeUsedAsIndex.ts, 7, 60)) +>Dict_54886 : Symbol(Dict_54886, Decl(substitutionTypeUsedAsIndex.ts, 0, 0)) +>FF_54886 : Symbol(FF_54886, Decl(substitutionTypeUsedAsIndex.ts, 5, 1)) + diff --git a/tests/baselines/reference/substitutionTypeUsedAsIndex.types b/tests/baselines/reference/substitutionTypeUsedAsIndex.types new file mode 100644 index 0000000000000..942da90ad4e1a --- /dev/null +++ b/tests/baselines/reference/substitutionTypeUsedAsIndex.types @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/substitutionTypeUsedAsIndex.ts] //// + +=== substitutionTypeUsedAsIndex.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54886 + +interface Dict_54886 { + foo: 1; +>foo : 1 + + bar: 1; +>bar : 1 +} + +type FF_54886 = "foo" extends "foo" | "bar" ? "foo" : never; +>FF_54886 : "foo" + +type C_54886 = Dict_54886[FF_54886]; // ok +>C_54886 : 1 + diff --git a/tests/cases/compiler/substitutionTypeUsedAsIndex.ts b/tests/cases/compiler/substitutionTypeUsedAsIndex.ts new file mode 100644 index 0000000000000..3a880c039cc5d --- /dev/null +++ b/tests/cases/compiler/substitutionTypeUsedAsIndex.ts @@ -0,0 +1,12 @@ +// @strict: true +// @noEmit: true + +// repro from https://github.com/microsoft/TypeScript/issues/54886 + +interface Dict_54886 { + foo: 1; + bar: 1; +} + +type FF_54886 = "foo" extends "foo" | "bar" ? "foo" : never; +type C_54886 = Dict_54886[FF_54886]; // ok