mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-12 04:17:34 -06:00
Only collect inferences which actually have inferences into the returnMapper (#30111)
This commit is contained in:
parent
5ec5e0466d
commit
a6a3ae00a6
@ -10691,6 +10691,23 @@ namespace ts {
|
||||
mapper;
|
||||
}
|
||||
|
||||
function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined {
|
||||
// Filter context to only those parameters which actually have inference candidates
|
||||
const params = [];
|
||||
const inferences = [];
|
||||
for (let i = 0; i < context.typeParameters.length; i++) {
|
||||
const info = context.inferences[i];
|
||||
if (info.candidates || info.contraCandidates) {
|
||||
params.push(context.typeParameters[i]);
|
||||
inferences.push(info);
|
||||
}
|
||||
}
|
||||
if (!params.length) {
|
||||
return undefined;
|
||||
}
|
||||
return createInferenceContext(params, context.signature, context.flags | InferenceFlags.NoDefault, context.compareTypes, inferences);
|
||||
}
|
||||
|
||||
function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper;
|
||||
function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper | undefined): TypeMapper;
|
||||
function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper): TypeMapper {
|
||||
@ -14900,7 +14917,7 @@ namespace ts {
|
||||
// parameter should be instantiated to the empty object type.
|
||||
inferredType = instantiateType(defaultType,
|
||||
combineTypeMappers(
|
||||
createBackreferenceMapper(context.signature!.typeParameters!, index),
|
||||
createBackreferenceMapper(context.typeParameters, index),
|
||||
context));
|
||||
}
|
||||
else {
|
||||
@ -20069,7 +20086,7 @@ namespace ts {
|
||||
inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
|
||||
// Create a type mapper for instantiating generic contextual types using the inferences made
|
||||
// from the return type.
|
||||
context.returnMapper = cloneTypeMapper(context);
|
||||
context.returnMapper = cloneInferredPartOfContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
tests/baselines/reference/returnTypeInferenceNotTooBroad.js
Normal file
24
tests/baselines/reference/returnTypeInferenceNotTooBroad.js
Normal file
@ -0,0 +1,24 @@
|
||||
//// [returnTypeInferenceNotTooBroad.ts]
|
||||
type Signs = { kind: 'a'; a: 3; } | { kind: 'b'; b: 2; } | { kind: 'c'; c: 1; };
|
||||
interface Opts<T> {
|
||||
low?: number;
|
||||
sign?: T
|
||||
}
|
||||
interface Wrapper<T> {
|
||||
}
|
||||
declare function sepsis<T extends Signs>(opts: Opts<T>): Wrapper<T>;
|
||||
declare function unwrap<T>(w: Wrapper<T>): T;
|
||||
export const y = sepsis({ low: 1, sign: { kind: 'a', a: 3 }});
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yun = unwrap(y);
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yone = unwrap(sepsis({ low: 1, sign: { kind: 'a', a: 3 }}));
|
||||
|
||||
//// [returnTypeInferenceNotTooBroad.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.y = sepsis({ low: 1, sign: { kind: 'a', a: 3 } });
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
exports.yun = unwrap(exports.y);
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
exports.yone = unwrap(sepsis({ low: 1, sign: { kind: 'a', a: 3 } }));
|
||||
@ -0,0 +1,67 @@
|
||||
=== tests/cases/compiler/returnTypeInferenceNotTooBroad.ts ===
|
||||
type Signs = { kind: 'a'; a: 3; } | { kind: 'b'; b: 2; } | { kind: 'c'; c: 1; };
|
||||
>Signs : Symbol(Signs, Decl(returnTypeInferenceNotTooBroad.ts, 0, 0))
|
||||
>kind : Symbol(kind, Decl(returnTypeInferenceNotTooBroad.ts, 0, 14))
|
||||
>a : Symbol(a, Decl(returnTypeInferenceNotTooBroad.ts, 0, 25))
|
||||
>kind : Symbol(kind, Decl(returnTypeInferenceNotTooBroad.ts, 0, 37))
|
||||
>b : Symbol(b, Decl(returnTypeInferenceNotTooBroad.ts, 0, 48))
|
||||
>kind : Symbol(kind, Decl(returnTypeInferenceNotTooBroad.ts, 0, 60))
|
||||
>c : Symbol(c, Decl(returnTypeInferenceNotTooBroad.ts, 0, 71))
|
||||
|
||||
interface Opts<T> {
|
||||
>Opts : Symbol(Opts, Decl(returnTypeInferenceNotTooBroad.ts, 0, 80))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 1, 15))
|
||||
|
||||
low?: number;
|
||||
>low : Symbol(Opts.low, Decl(returnTypeInferenceNotTooBroad.ts, 1, 19))
|
||||
|
||||
sign?: T
|
||||
>sign : Symbol(Opts.sign, Decl(returnTypeInferenceNotTooBroad.ts, 2, 17))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 1, 15))
|
||||
}
|
||||
interface Wrapper<T> {
|
||||
>Wrapper : Symbol(Wrapper, Decl(returnTypeInferenceNotTooBroad.ts, 4, 1))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 5, 18))
|
||||
}
|
||||
declare function sepsis<T extends Signs>(opts: Opts<T>): Wrapper<T>;
|
||||
>sepsis : Symbol(sepsis, Decl(returnTypeInferenceNotTooBroad.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 7, 24))
|
||||
>Signs : Symbol(Signs, Decl(returnTypeInferenceNotTooBroad.ts, 0, 0))
|
||||
>opts : Symbol(opts, Decl(returnTypeInferenceNotTooBroad.ts, 7, 41))
|
||||
>Opts : Symbol(Opts, Decl(returnTypeInferenceNotTooBroad.ts, 0, 80))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 7, 24))
|
||||
>Wrapper : Symbol(Wrapper, Decl(returnTypeInferenceNotTooBroad.ts, 4, 1))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 7, 24))
|
||||
|
||||
declare function unwrap<T>(w: Wrapper<T>): T;
|
||||
>unwrap : Symbol(unwrap, Decl(returnTypeInferenceNotTooBroad.ts, 7, 68))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 8, 24))
|
||||
>w : Symbol(w, Decl(returnTypeInferenceNotTooBroad.ts, 8, 27))
|
||||
>Wrapper : Symbol(Wrapper, Decl(returnTypeInferenceNotTooBroad.ts, 4, 1))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 8, 24))
|
||||
>T : Symbol(T, Decl(returnTypeInferenceNotTooBroad.ts, 8, 24))
|
||||
|
||||
export const y = sepsis({ low: 1, sign: { kind: 'a', a: 3 }});
|
||||
>y : Symbol(y, Decl(returnTypeInferenceNotTooBroad.ts, 9, 12))
|
||||
>sepsis : Symbol(sepsis, Decl(returnTypeInferenceNotTooBroad.ts, 6, 1))
|
||||
>low : Symbol(low, Decl(returnTypeInferenceNotTooBroad.ts, 9, 25))
|
||||
>sign : Symbol(sign, Decl(returnTypeInferenceNotTooBroad.ts, 9, 33))
|
||||
>kind : Symbol(kind, Decl(returnTypeInferenceNotTooBroad.ts, 9, 41))
|
||||
>a : Symbol(a, Decl(returnTypeInferenceNotTooBroad.ts, 9, 52))
|
||||
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yun = unwrap(y);
|
||||
>yun : Symbol(yun, Decl(returnTypeInferenceNotTooBroad.ts, 11, 12))
|
||||
>unwrap : Symbol(unwrap, Decl(returnTypeInferenceNotTooBroad.ts, 7, 68))
|
||||
>y : Symbol(y, Decl(returnTypeInferenceNotTooBroad.ts, 9, 12))
|
||||
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yone = unwrap(sepsis({ low: 1, sign: { kind: 'a', a: 3 }}));
|
||||
>yone : Symbol(yone, Decl(returnTypeInferenceNotTooBroad.ts, 13, 12))
|
||||
>unwrap : Symbol(unwrap, Decl(returnTypeInferenceNotTooBroad.ts, 7, 68))
|
||||
>sepsis : Symbol(sepsis, Decl(returnTypeInferenceNotTooBroad.ts, 6, 1))
|
||||
>low : Symbol(low, Decl(returnTypeInferenceNotTooBroad.ts, 13, 35))
|
||||
>sign : Symbol(sign, Decl(returnTypeInferenceNotTooBroad.ts, 13, 43))
|
||||
>kind : Symbol(kind, Decl(returnTypeInferenceNotTooBroad.ts, 13, 51))
|
||||
>a : Symbol(a, Decl(returnTypeInferenceNotTooBroad.ts, 13, 62))
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
=== tests/cases/compiler/returnTypeInferenceNotTooBroad.ts ===
|
||||
type Signs = { kind: 'a'; a: 3; } | { kind: 'b'; b: 2; } | { kind: 'c'; c: 1; };
|
||||
>Signs : Signs
|
||||
>kind : "a"
|
||||
>a : 3
|
||||
>kind : "b"
|
||||
>b : 2
|
||||
>kind : "c"
|
||||
>c : 1
|
||||
|
||||
interface Opts<T> {
|
||||
low?: number;
|
||||
>low : number
|
||||
|
||||
sign?: T
|
||||
>sign : T
|
||||
}
|
||||
interface Wrapper<T> {
|
||||
}
|
||||
declare function sepsis<T extends Signs>(opts: Opts<T>): Wrapper<T>;
|
||||
>sepsis : <T extends Signs>(opts: Opts<T>) => Wrapper<T>
|
||||
>opts : Opts<T>
|
||||
|
||||
declare function unwrap<T>(w: Wrapper<T>): T;
|
||||
>unwrap : <T>(w: Wrapper<T>) => T
|
||||
>w : Wrapper<T>
|
||||
|
||||
export const y = sepsis({ low: 1, sign: { kind: 'a', a: 3 }});
|
||||
>y : Wrapper<{ kind: "a"; a: 3; }>
|
||||
>sepsis({ low: 1, sign: { kind: 'a', a: 3 }}) : Wrapper<{ kind: "a"; a: 3; }>
|
||||
>sepsis : <T extends Signs>(opts: Opts<T>) => Wrapper<T>
|
||||
>{ low: 1, sign: { kind: 'a', a: 3 }} : { low: number; sign: { kind: "a"; a: 3; }; }
|
||||
>low : number
|
||||
>1 : 1
|
||||
>sign : { kind: "a"; a: 3; }
|
||||
>{ kind: 'a', a: 3 } : { kind: "a"; a: 3; }
|
||||
>kind : "a"
|
||||
>'a' : "a"
|
||||
>a : 3
|
||||
>3 : 3
|
||||
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yun = unwrap(y);
|
||||
>yun : { kind: "a"; a: 3; }
|
||||
>unwrap(y) : { kind: "a"; a: 3; }
|
||||
>unwrap : <T>(w: Wrapper<T>) => T
|
||||
>y : Wrapper<{ kind: "a"; a: 3; }>
|
||||
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yone = unwrap(sepsis({ low: 1, sign: { kind: 'a', a: 3 }}));
|
||||
>yone : { kind: "a"; a: 3; }
|
||||
>unwrap(sepsis({ low: 1, sign: { kind: 'a', a: 3 }})) : { kind: "a"; a: 3; }
|
||||
>unwrap : <T>(w: Wrapper<T>) => T
|
||||
>sepsis({ low: 1, sign: { kind: 'a', a: 3 }}) : Wrapper<{ kind: "a"; a: 3; }>
|
||||
>sepsis : <T extends Signs>(opts: Opts<T>) => Wrapper<T>
|
||||
>{ low: 1, sign: { kind: 'a', a: 3 }} : { low: number; sign: { kind: "a"; a: 3; }; }
|
||||
>low : number
|
||||
>1 : 1
|
||||
>sign : { kind: "a"; a: 3; }
|
||||
>{ kind: 'a', a: 3 } : { kind: "a"; a: 3; }
|
||||
>kind : "a"
|
||||
>'a' : "a"
|
||||
>a : 3
|
||||
>3 : 3
|
||||
|
||||
14
tests/cases/compiler/returnTypeInferenceNotTooBroad.ts
Normal file
14
tests/cases/compiler/returnTypeInferenceNotTooBroad.ts
Normal file
@ -0,0 +1,14 @@
|
||||
type Signs = { kind: 'a'; a: 3; } | { kind: 'b'; b: 2; } | { kind: 'c'; c: 1; };
|
||||
interface Opts<T> {
|
||||
low?: number;
|
||||
sign?: T
|
||||
}
|
||||
interface Wrapper<T> {
|
||||
}
|
||||
declare function sepsis<T extends Signs>(opts: Opts<T>): Wrapper<T>;
|
||||
declare function unwrap<T>(w: Wrapper<T>): T;
|
||||
export const y = sepsis({ low: 1, sign: { kind: 'a', a: 3 }});
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yun = unwrap(y);
|
||||
// $ExpectType { kind: "a"; a: 3; }
|
||||
export const yone = unwrap(sepsis({ low: 1, sign: { kind: 'a', a: 3 }}));
|
||||
Loading…
x
Reference in New Issue
Block a user