mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Fix incorrect rest element type inside contextually typed parameter (#47909)
* wip: possible fixes * pass parameter type to assignBindingElementTypes * undo unnecessary changes * update baselines
This commit is contained in:
parent
d13af64bde
commit
67f47bf420
@ -31851,21 +31851,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
tests/baselines/reference/narrowingRestGenericCall.js
Normal file
34
tests/baselines/reference/narrowingRestGenericCall.js
Normal file
@ -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
tests/baselines/reference/narrowingRestGenericCall.symbols
Normal file
44
tests/baselines/reference/narrowingRestGenericCall.symbols
Normal file
@ -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
tests/baselines/reference/narrowingRestGenericCall.types
Normal file
42
tests/baselines/reference/narrowingRestGenericCall.types
Normal file
@ -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
tests/cases/compiler/narrowingRestGenericCall.ts
Normal file
13
tests/cases/compiler/narrowingRestGenericCall.ts
Normal file
@ -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);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user