diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d4565607249fd..bcd8ef1771440 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19545,13 +19545,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper)); const newAliasSymbol = aliasSymbol || type.aliasSymbol; const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper); - const id = getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments); + const id = (type.objectFlags & ObjectFlags.SingleSignatureType ? "S" : "") + getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments); if (!target.instantiations) { target.instantiations = new Map(); target.instantiations.set(getTypeListId(typeParameters) + getAliasId(target.aliasSymbol, target.aliasTypeArguments), target); } let result = target.instantiations.get(id); if (!result) { + if (type.objectFlags & ObjectFlags.SingleSignatureType) { + result = instantiateAnonymousType(type, mapper); + target.instantiations.set(id, result); + return result; + } const newMapper = createTypeMapper(typeParameters, typeArguments); result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) : target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) : diff --git a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols new file mode 100644 index 0000000000000..dec6af6bac2c5 --- /dev/null +++ b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts] //// + +=== genericCallInferenceWithGenericLocalFunction.ts === +// https://github.com/microsoft/TypeScript/issues/43961 + +const createTransform = (tr: (from: I) => O) => tr; +>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5)) +>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 25)) +>O : Symbol(O, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 27)) +>tr : Symbol(tr, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 31)) +>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 36)) +>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 25)) +>O : Symbol(O, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 27)) +>tr : Symbol(tr, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 31)) + +function withP2

(p: P) { +>withP2 : Symbol(withP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 57)) +>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 16)) +>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 19)) +>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 16)) + + const m = (from: I) => ({ ...from, ...p }); +>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 7)) +>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 13)) +>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 17)) +>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 13)) +>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 17)) +>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 19)) + + return createTransform(m); +>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5)) +>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 7)) +} + +const addP2 = withP2({ foo: 1 }); +>addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5)) +>withP2 : Symbol(withP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 57)) +>foo : Symbol(foo, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 22)) + +const added2 = addP2({ bar: 2 }); +>added2 : Symbol(added2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 5)) +>addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5)) +>bar : Symbol(bar, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 22)) + diff --git a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types new file mode 100644 index 0000000000000..05b6d0617f3db --- /dev/null +++ b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types @@ -0,0 +1,76 @@ +//// [tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts] //// + +=== genericCallInferenceWithGenericLocalFunction.ts === +// https://github.com/microsoft/TypeScript/issues/43961 + +const createTransform = (tr: (from: I) => O) => tr; +>createTransform : (tr: (from: I) => O) => (from: I) => O +> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^ +>(tr: (from: I) => O) => tr : (tr: (from: I) => O) => (from: I) => O +> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^ +>tr : (from: I) => O +> : ^ ^^ ^^^^^ +>from : I +> : ^ +>tr : (from: I) => O +> : ^ ^^ ^^^^^ + +function withP2

(p: P) { +>withP2 :

(p: P) => (from: I) => I & P +> : ^ ^^ ^^ ^^^^^^^^^ ^^^^^^^^^^^^^ +>p : P +> : ^ + + const m = (from: I) => ({ ...from, ...p }); +>m : (from: I) => I & P +> : ^ ^^ ^^ ^^^^^^^^^^ +>(from: I) => ({ ...from, ...p }) : (from: I) => I & P +> : ^ ^^ ^^ ^^^^^^^^^^ +>from : I +> : ^ +>({ ...from, ...p }) : I & P +> : ^^^^^ +>{ ...from, ...p } : I & P +> : ^^^^^ +>from : I +> : ^ +>p : P +> : ^ + + return createTransform(m); +>createTransform(m) : (from: I) => I & P +> : ^^^^ ^^^^^^^^^^^^^ +>createTransform : (tr: (from: I) => O) => (from: I) => O +> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^^ +>m : (from: I) => I & P +> : ^ ^^ ^^ ^^^^^^^^^^ +} + +const addP2 = withP2({ foo: 1 }); +>addP2 : (from: I) => I & { foo: number; } +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withP2({ foo: 1 }) : (from: I) => I & { foo: number; } +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withP2 :

(p: P) => (from: I) => I & P +> : ^ ^^ ^^ ^^^^^^^^^ ^^^^^^^^^^^^^ +>{ foo: 1 } : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>foo : number +> : ^^^^^^ +>1 : 1 +> : ^ + +const added2 = addP2({ bar: 2 }); +>added2 : { bar: number; } & { foo: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addP2({ bar: 2 }) : { bar: number; } & { foo: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addP2 : (from: I) => I & { foo: number; } +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ bar: 2 } : { bar: number; } +> : ^^^^^^^^^^^^^^^^ +>bar : number +> : ^^^^^^ +>2 : 2 +> : ^ + diff --git a/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts b/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts new file mode 100644 index 0000000000000..1aff11c5b3507 --- /dev/null +++ b/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts @@ -0,0 +1,14 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/43961 + +const createTransform = (tr: (from: I) => O) => tr; + +function withP2

(p: P) { + const m = (from: I) => ({ ...from, ...p }); + return createTransform(m); +} + +const addP2 = withP2({ foo: 1 }); +const added2 = addP2({ bar: 2 });