diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6a720d947d..079d942df4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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(parameter.valueDeclaration.name); + } assignBindingElementTypes(parameter.valueDeclaration); } else if (isInferentialContext(mapper)) { diff --git a/tests/baselines/reference/fallbackToBindingPatternForTypeInference.js b/tests/baselines/reference/fallbackToBindingPatternForTypeInference.js new file mode 100644 index 0000000000..fd0632b2be --- /dev/null +++ b/tests/baselines/reference/fallbackToBindingPatternForTypeInference.js @@ -0,0 +1,25 @@ +//// [fallbackToBindingPatternForTypeInference.ts] +declare function trans(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'; +}); diff --git a/tests/baselines/reference/fallbackToBindingPatternForTypeInference.symbols b/tests/baselines/reference/fallbackToBindingPatternForTypeInference.symbols new file mode 100644 index 0000000000..e7049d50e1 --- /dev/null +++ b/tests/baselines/reference/fallbackToBindingPatternForTypeInference.symbols @@ -0,0 +1,28 @@ +=== tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts === +declare function trans(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)) + diff --git a/tests/baselines/reference/fallbackToBindingPatternForTypeInference.types b/tests/baselines/reference/fallbackToBindingPatternForTypeInference.types new file mode 100644 index 0000000000..c8f01abaf8 --- /dev/null +++ b/tests/baselines/reference/fallbackToBindingPatternForTypeInference.types @@ -0,0 +1,40 @@ +=== tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts === +declare function trans(f: (x: T) => string): number; +>trans : (f: (x: T) => string) => number +>T : T +>f : (x: T) => string +>x : T +>T : T + +trans(({a}) => a); +>trans(({a}) => a) : number +>trans : (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 : (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 : (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 : (f: (x: T) => string) => number +>([{g},{h}]) => 'foo' : ([{g}, {h}]: [{ g: any; }, { h: any; }]) => string +>g : any +>h : any +>'foo' : string + diff --git a/tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts b/tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts new file mode 100644 index 0000000000..de6940110d --- /dev/null +++ b/tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts @@ -0,0 +1,5 @@ +declare function trans(f: (x: T) => string): number; +trans(({a}) => a); +trans(([b,c]) => 'foo'); +trans(({d: [e,f]}) => 'foo'); +trans(([{g},{h}]) => 'foo');