Skip to content

Commit

Permalink
Cherry-pick PR #47909 into release-4.6 (#47912)
Browse files Browse the repository at this point in the history
Component commits:
f4a5562 wip: possible fixes

75cb739 pass parameter type to assignBindingElementTypes

4a7de63 undo unnecessary changes

b618cf9 update baselines

Co-authored-by: Gabriela Araujo Britto <gabrielaa@microsoft.com>
  • Loading branch information
TypeScript Bot and gabritto authored Feb 16, 2022
1 parent 83efc9f commit b6ec37a
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31832,21 +31832,22 @@ namespace ts {
if (links.type === unknownType) {
links.type = getTypeFromBindingPattern(declaration.name);
}
assignBindingElementTypes(declaration.name);
assignBindingElementTypes(declaration.name, links.type);
}
}
}

// When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
// the destructured type into the contained binding elements.
function assignBindingElementTypes(pattern: BindingPattern) {
function assignBindingElementTypes(pattern: BindingPattern, parentType: Type) {
for (const element of pattern.elements) {
if (!isOmittedExpression(element)) {
const type = getBindingElementTypeFromParentType(element, parentType);
if (element.name.kind === SyntaxKind.Identifier) {
getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
getSymbolLinks(getSymbolOfNode(element)).type = type;
}
else {
assignBindingElementTypes(element.name);
assignBindingElementTypes(element.name, type);
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions tests/baselines/reference/narrowingRestGenericCall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//// [narrowingRestGenericCall.ts]
interface Slugs {
foo: string;
bar: string;
}

function call<T extends object>(obj: T, cb: (val: T) => void) {
cb(obj);
}

declare let obj: Slugs;
call(obj, ({foo, ...rest}) => {
console.log(rest.bar);
});

//// [narrowingRestGenericCall.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
function call(obj, cb) {
cb(obj);
}
call(obj, function (_a) {
var foo = _a.foo, rest = __rest(_a, ["foo"]);
console.log(rest.bar);
});
44 changes: 44 additions & 0 deletions tests/baselines/reference/narrowingRestGenericCall.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
=== tests/cases/compiler/narrowingRestGenericCall.ts ===
interface Slugs {
>Slugs : Symbol(Slugs, Decl(narrowingRestGenericCall.ts, 0, 0))

foo: string;
>foo : Symbol(Slugs.foo, Decl(narrowingRestGenericCall.ts, 0, 17))

bar: string;
>bar : Symbol(Slugs.bar, Decl(narrowingRestGenericCall.ts, 1, 14))
}

function call<T extends object>(obj: T, cb: (val: T) => void) {
>call : Symbol(call, Decl(narrowingRestGenericCall.ts, 3, 1))
>T : Symbol(T, Decl(narrowingRestGenericCall.ts, 5, 14))
>obj : Symbol(obj, Decl(narrowingRestGenericCall.ts, 5, 32))
>T : Symbol(T, Decl(narrowingRestGenericCall.ts, 5, 14))
>cb : Symbol(cb, Decl(narrowingRestGenericCall.ts, 5, 39))
>val : Symbol(val, Decl(narrowingRestGenericCall.ts, 5, 45))
>T : Symbol(T, Decl(narrowingRestGenericCall.ts, 5, 14))

cb(obj);
>cb : Symbol(cb, Decl(narrowingRestGenericCall.ts, 5, 39))
>obj : Symbol(obj, Decl(narrowingRestGenericCall.ts, 5, 32))
}

declare let obj: Slugs;
>obj : Symbol(obj, Decl(narrowingRestGenericCall.ts, 9, 11))
>Slugs : Symbol(Slugs, Decl(narrowingRestGenericCall.ts, 0, 0))

call(obj, ({foo, ...rest}) => {
>call : Symbol(call, Decl(narrowingRestGenericCall.ts, 3, 1))
>obj : Symbol(obj, Decl(narrowingRestGenericCall.ts, 9, 11))
>foo : Symbol(foo, Decl(narrowingRestGenericCall.ts, 10, 12))
>rest : Symbol(rest, Decl(narrowingRestGenericCall.ts, 10, 16))

console.log(rest.bar);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>rest.bar : Symbol(Slugs.bar, Decl(narrowingRestGenericCall.ts, 1, 14))
>rest : Symbol(rest, Decl(narrowingRestGenericCall.ts, 10, 16))
>bar : Symbol(Slugs.bar, Decl(narrowingRestGenericCall.ts, 1, 14))

});
42 changes: 42 additions & 0 deletions tests/baselines/reference/narrowingRestGenericCall.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
=== tests/cases/compiler/narrowingRestGenericCall.ts ===
interface Slugs {
foo: string;
>foo : string

bar: string;
>bar : string
}

function call<T extends object>(obj: T, cb: (val: T) => void) {
>call : <T extends object>(obj: T, cb: (val: T) => void) => void
>obj : T
>cb : (val: T) => void
>val : T

cb(obj);
>cb(obj) : void
>cb : (val: T) => void
>obj : T
}

declare let obj: Slugs;
>obj : Slugs

call(obj, ({foo, ...rest}) => {
>call(obj, ({foo, ...rest}) => { console.log(rest.bar);}) : void
>call : <T extends object>(obj: T, cb: (val: T) => void) => void
>obj : Slugs
>({foo, ...rest}) => { console.log(rest.bar);} : ({ foo, ...rest }: Slugs) => void
>foo : string
>rest : { bar: string; }

console.log(rest.bar);
>console.log(rest.bar) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>rest.bar : string
>rest : { bar: string; }
>bar : string

});
13 changes: 13 additions & 0 deletions tests/cases/compiler/narrowingRestGenericCall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
interface Slugs {
foo: string;
bar: string;
}

function call<T extends object>(obj: T, cb: (val: T) => void) {
cb(obj);
}

declare let obj: Slugs;
call(obj, ({foo, ...rest}) => {
console.log(rest.bar);
});

0 comments on commit b6ec37a

Please sign in to comment.