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:
Nathan Shively-Sanders 2016-05-16 16:09:36 -07:00
parent ef75346e7e
commit ae4a983c59
5 changed files with 104 additions and 0 deletions

View file

@ -11455,6 +11455,12 @@ namespace ts {
const links = getSymbolLinks(parameter);
if (!links.type) {
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);
}
else if (isInferentialContext(mapper)) {

View file

@ -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';
});

View file

@ -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))

View file

@ -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

View file

@ -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');