Use binding pattern for type inference result {}
The binding pattern provides additional information when the contextual type is not found and would otherwise fix a type parameter to `{}`.
This commit is contained in:
parent
ef75346e7e
commit
ae4a983c59
|
@ -11455,6 +11455,12 @@ namespace ts {
|
||||||
const links = getSymbolLinks(parameter);
|
const links = getSymbolLinks(parameter);
|
||||||
if (!links.type) {
|
if (!links.type) {
|
||||||
links.type = instantiateType(contextualType, mapper);
|
links.type = instantiateType(contextualType, mapper);
|
||||||
|
// if inference didn't come up with anything but {}, fall back to the binding pattern if present.
|
||||||
|
if (links.type === emptyObjectType &&
|
||||||
|
(parameter.valueDeclaration.name.kind === SyntaxKind.ObjectBindingPattern ||
|
||||||
|
parameter.valueDeclaration.name.kind === SyntaxKind.ArrayBindingPattern)) {
|
||||||
|
links.type = getTypeFromBindingPattern(<BindingPattern>parameter.valueDeclaration.name);
|
||||||
|
}
|
||||||
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
|
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
|
||||||
}
|
}
|
||||||
else if (isInferentialContext(mapper)) {
|
else if (isInferentialContext(mapper)) {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
//// [fallbackToBindingPatternForTypeInference.ts]
|
||||||
|
declare function trans<T>(f: (x: T) => string): number;
|
||||||
|
trans(({a}) => a);
|
||||||
|
trans(([b,c]) => 'foo');
|
||||||
|
trans(({d: [e,f]}) => 'foo');
|
||||||
|
trans(([{g},{h}]) => 'foo');
|
||||||
|
|
||||||
|
|
||||||
|
//// [fallbackToBindingPatternForTypeInference.js]
|
||||||
|
trans(function (_a) {
|
||||||
|
var a = _a.a;
|
||||||
|
return a;
|
||||||
|
});
|
||||||
|
trans(function (_a) {
|
||||||
|
var b = _a[0], c = _a[1];
|
||||||
|
return 'foo';
|
||||||
|
});
|
||||||
|
trans(function (_a) {
|
||||||
|
var _b = _a.d, e = _b[0], f = _b[1];
|
||||||
|
return 'foo';
|
||||||
|
});
|
||||||
|
trans(function (_a) {
|
||||||
|
var g = _a[0].g, h = _a[1].h;
|
||||||
|
return 'foo';
|
||||||
|
});
|
|
@ -0,0 +1,28 @@
|
||||||
|
=== tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts ===
|
||||||
|
declare function trans<T>(f: (x: T) => string): number;
|
||||||
|
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
|
||||||
|
>T : Symbol(T, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 23))
|
||||||
|
>f : Symbol(f, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 26))
|
||||||
|
>x : Symbol(x, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 30))
|
||||||
|
>T : Symbol(T, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 23))
|
||||||
|
|
||||||
|
trans(({a}) => a);
|
||||||
|
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
|
||||||
|
>a : Symbol(a, Decl(fallbackToBindingPatternForTypeInference.ts, 1, 8))
|
||||||
|
>a : Symbol(a, Decl(fallbackToBindingPatternForTypeInference.ts, 1, 8))
|
||||||
|
|
||||||
|
trans(([b,c]) => 'foo');
|
||||||
|
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
|
||||||
|
>b : Symbol(b, Decl(fallbackToBindingPatternForTypeInference.ts, 2, 8))
|
||||||
|
>c : Symbol(c, Decl(fallbackToBindingPatternForTypeInference.ts, 2, 10))
|
||||||
|
|
||||||
|
trans(({d: [e,f]}) => 'foo');
|
||||||
|
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
|
||||||
|
>e : Symbol(e, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 12))
|
||||||
|
>f : Symbol(f, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 14))
|
||||||
|
|
||||||
|
trans(([{g},{h}]) => 'foo');
|
||||||
|
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
|
||||||
|
>g : Symbol(g, Decl(fallbackToBindingPatternForTypeInference.ts, 4, 9))
|
||||||
|
>h : Symbol(h, Decl(fallbackToBindingPatternForTypeInference.ts, 4, 13))
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
=== tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts ===
|
||||||
|
declare function trans<T>(f: (x: T) => string): number;
|
||||||
|
>trans : <T>(f: (x: T) => string) => number
|
||||||
|
>T : T
|
||||||
|
>f : (x: T) => string
|
||||||
|
>x : T
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
trans(({a}) => a);
|
||||||
|
>trans(({a}) => a) : number
|
||||||
|
>trans : <T>(f: (x: T) => string) => number
|
||||||
|
>({a}) => a : ({a}: { a: any; }) => any
|
||||||
|
>a : any
|
||||||
|
>a : any
|
||||||
|
|
||||||
|
trans(([b,c]) => 'foo');
|
||||||
|
>trans(([b,c]) => 'foo') : number
|
||||||
|
>trans : <T>(f: (x: T) => string) => number
|
||||||
|
>([b,c]) => 'foo' : ([b, c]: [any, any]) => string
|
||||||
|
>b : any
|
||||||
|
>c : any
|
||||||
|
>'foo' : string
|
||||||
|
|
||||||
|
trans(({d: [e,f]}) => 'foo');
|
||||||
|
>trans(({d: [e,f]}) => 'foo') : number
|
||||||
|
>trans : <T>(f: (x: T) => string) => number
|
||||||
|
>({d: [e,f]}) => 'foo' : ({d: [e, f]}: { d: [any, any]; }) => string
|
||||||
|
>d : any
|
||||||
|
>e : any
|
||||||
|
>f : any
|
||||||
|
>'foo' : string
|
||||||
|
|
||||||
|
trans(([{g},{h}]) => 'foo');
|
||||||
|
>trans(([{g},{h}]) => 'foo') : number
|
||||||
|
>trans : <T>(f: (x: T) => string) => number
|
||||||
|
>([{g},{h}]) => 'foo' : ([{g}, {h}]: [{ g: any; }, { h: any; }]) => string
|
||||||
|
>g : any
|
||||||
|
>h : any
|
||||||
|
>'foo' : string
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
declare function trans<T>(f: (x: T) => string): number;
|
||||||
|
trans(({a}) => a);
|
||||||
|
trans(([b,c]) => 'foo');
|
||||||
|
trans(({d: [e,f]}) => 'foo');
|
||||||
|
trans(([{g},{h}]) => 'foo');
|
Loading…
Reference in a new issue