From f4a556254323b395db712996ba71cddac1c116cd Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 15 Feb 2022 09:41:47 -0800 Subject: [PATCH 1/4] wip: possible fixes --- src/compiler/checker.ts | 19 +++++--- .../reference/narrowingRestGenericCall.js | 36 +++++++++++++++ .../narrowingRestGenericCall.symbols | 45 +++++++++++++++++++ .../reference/narrowingRestGenericCall.types | 43 ++++++++++++++++++ .../compiler/narrowingRestGenericCall.ts | 14 ++++++ 5 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/narrowingRestGenericCall.js create mode 100644 tests/baselines/reference/narrowingRestGenericCall.symbols create mode 100644 tests/baselines/reference/narrowingRestGenericCall.types create mode 100644 tests/cases/compiler/narrowingRestGenericCall.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c38d9c2a0416a..e0fd69eab48bd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26061,12 +26061,17 @@ namespace ts { links.resolvedSignature = cached; return type; } + const contextualSignature = getContextualSignature(func); if (contextualSignature) { + // const inferenceContext = getInferenceContext(func); // >> Changed here + // const signature = inferenceContext ? + // instantiateSignature(contextualSignature, inferenceContext.mapper) : contextualSignature; + const signature = contextualSignature; const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0); return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ? - getRestTypeAtPosition(contextualSignature, index) : - tryGetTypeAtPosition(contextualSignature, index); + getRestTypeAtPosition(signature, index) : + tryGetTypeAtPosition(signature, index); } } @@ -31858,21 +31863,23 @@ 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); // >> Changed here if (element.name.kind === SyntaxKind.Identifier) { - getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + // getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); + getSymbolLinks(getSymbolOfNode(element)).type = type; } else { - assignBindingElementTypes(element.name); + assignBindingElementTypes(element.name, type); } } } diff --git a/tests/baselines/reference/narrowingRestGenericCall.js b/tests/baselines/reference/narrowingRestGenericCall.js new file mode 100644 index 0000000000000..e9d5185eb01e0 --- /dev/null +++ b/tests/baselines/reference/narrowingRestGenericCall.js @@ -0,0 +1,36 @@ +//// [narrowingRestGenericCall.ts] +interface Slugs { + foo: string; + bar: string; +} + +function call(obj: T, cb: (val: T) => void) { + cb(obj); +} + +declare let obj: Slugs; +call(obj, ({foo, ...rest}) => { + console.log(rest.bar); + // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) +}); + +//// [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); + // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) +}); diff --git a/tests/baselines/reference/narrowingRestGenericCall.symbols b/tests/baselines/reference/narrowingRestGenericCall.symbols new file mode 100644 index 0000000000000..880a7797b6cee --- /dev/null +++ b/tests/baselines/reference/narrowingRestGenericCall.symbols @@ -0,0 +1,45 @@ +=== 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(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)) + + // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) +}); diff --git a/tests/baselines/reference/narrowingRestGenericCall.types b/tests/baselines/reference/narrowingRestGenericCall.types new file mode 100644 index 0000000000000..fdb88753102b7 --- /dev/null +++ b/tests/baselines/reference/narrowingRestGenericCall.types @@ -0,0 +1,43 @@ +=== tests/cases/compiler/narrowingRestGenericCall.ts === +interface Slugs { + foo: string; +>foo : string + + bar: string; +>bar : string +} + +function call(obj: T, cb: (val: T) => void) { +>call : (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); // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339)}) : void +>call : (obj: T, cb: (val: T) => void) => void +>obj : Slugs +>({foo, ...rest}) => { console.log(rest.bar); // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339)} : ({ 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 + + // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) +}); diff --git a/tests/cases/compiler/narrowingRestGenericCall.ts b/tests/cases/compiler/narrowingRestGenericCall.ts new file mode 100644 index 0000000000000..eb3e70580a594 --- /dev/null +++ b/tests/cases/compiler/narrowingRestGenericCall.ts @@ -0,0 +1,14 @@ +interface Slugs { + foo: string; + bar: string; +} + +function call(obj: T, cb: (val: T) => void) { + cb(obj); +} + +declare let obj: Slugs; +call(obj, ({foo, ...rest}) => { + console.log(rest.bar); + // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) +}); \ No newline at end of file From 75cb7392f372924d7e3969d405b8594dea9cdbe9 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 15 Feb 2022 11:23:29 -0800 Subject: [PATCH 2/4] pass parameter type to assignBindingElementTypes --- src/compiler/checker.ts | 6 +----- tests/cases/compiler/narrowingRestGenericCall.ts | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e0fd69eab48bd..59d1e28db8846 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26064,9 +26064,6 @@ namespace ts { const contextualSignature = getContextualSignature(func); if (contextualSignature) { - // const inferenceContext = getInferenceContext(func); // >> Changed here - // const signature = inferenceContext ? - // instantiateSignature(contextualSignature, inferenceContext.mapper) : contextualSignature; const signature = contextualSignature; const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0); return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ? @@ -31873,9 +31870,8 @@ namespace ts { function assignBindingElementTypes(pattern: BindingPattern, parentType: Type) { for (const element of pattern.elements) { if (!isOmittedExpression(element)) { - const type = getBindingElementTypeFromParentType(element, parentType); // >> Changed here + const type = getBindingElementTypeFromParentType(element, parentType); if (element.name.kind === SyntaxKind.Identifier) { - // getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); getSymbolLinks(getSymbolOfNode(element)).type = type; } else { diff --git a/tests/cases/compiler/narrowingRestGenericCall.ts b/tests/cases/compiler/narrowingRestGenericCall.ts index eb3e70580a594..ed74403099e0a 100644 --- a/tests/cases/compiler/narrowingRestGenericCall.ts +++ b/tests/cases/compiler/narrowingRestGenericCall.ts @@ -10,5 +10,4 @@ function call(obj: T, cb: (val: T) => void) { declare let obj: Slugs; call(obj, ({foo, ...rest}) => { console.log(rest.bar); - // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) }); \ No newline at end of file From 4a7de63c83bef54ec35922cc0a01386365c777c5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 15 Feb 2022 11:45:58 -0800 Subject: [PATCH 3/4] undo unnecessary changes --- src/compiler/checker.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 59d1e28db8846..78854ac51dacb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26061,14 +26061,12 @@ namespace ts { links.resolvedSignature = cached; return type; } - const contextualSignature = getContextualSignature(func); if (contextualSignature) { - const signature = contextualSignature; const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0); return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ? - getRestTypeAtPosition(signature, index) : - tryGetTypeAtPosition(signature, index); + getRestTypeAtPosition(contextualSignature, index) : + tryGetTypeAtPosition(contextualSignature, index); } } From b618cf9371a06e4f7c03edf9d8fc552149f5f27f Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 15 Feb 2022 11:47:58 -0800 Subject: [PATCH 4/4] update baselines --- tests/baselines/reference/narrowingRestGenericCall.js | 2 -- tests/baselines/reference/narrowingRestGenericCall.symbols | 1 - tests/baselines/reference/narrowingRestGenericCall.types | 5 ++--- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/narrowingRestGenericCall.js b/tests/baselines/reference/narrowingRestGenericCall.js index e9d5185eb01e0..a180bcb364f1a 100644 --- a/tests/baselines/reference/narrowingRestGenericCall.js +++ b/tests/baselines/reference/narrowingRestGenericCall.js @@ -11,7 +11,6 @@ function call(obj: T, cb: (val: T) => void) { declare let obj: Slugs; call(obj, ({foo, ...rest}) => { console.log(rest.bar); - // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) }); //// [narrowingRestGenericCall.js] @@ -32,5 +31,4 @@ function call(obj, cb) { call(obj, function (_a) { var foo = _a.foo, rest = __rest(_a, ["foo"]); console.log(rest.bar); - // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) }); diff --git a/tests/baselines/reference/narrowingRestGenericCall.symbols b/tests/baselines/reference/narrowingRestGenericCall.symbols index 880a7797b6cee..a128942700bc8 100644 --- a/tests/baselines/reference/narrowingRestGenericCall.symbols +++ b/tests/baselines/reference/narrowingRestGenericCall.symbols @@ -41,5 +41,4 @@ call(obj, ({foo, ...rest}) => { >rest : Symbol(rest, Decl(narrowingRestGenericCall.ts, 10, 16)) >bar : Symbol(Slugs.bar, Decl(narrowingRestGenericCall.ts, 1, 14)) - // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) }); diff --git a/tests/baselines/reference/narrowingRestGenericCall.types b/tests/baselines/reference/narrowingRestGenericCall.types index fdb88753102b7..a04e883ad9c7d 100644 --- a/tests/baselines/reference/narrowingRestGenericCall.types +++ b/tests/baselines/reference/narrowingRestGenericCall.types @@ -23,10 +23,10 @@ declare let obj: Slugs; >obj : Slugs call(obj, ({foo, ...rest}) => { ->call(obj, ({foo, ...rest}) => { console.log(rest.bar); // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339)}) : void +>call(obj, ({foo, ...rest}) => { console.log(rest.bar);}) : void >call : (obj: T, cb: (val: T) => void) => void >obj : Slugs ->({foo, ...rest}) => { console.log(rest.bar); // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339)} : ({ foo, ...rest }: Slugs) => void +>({foo, ...rest}) => { console.log(rest.bar);} : ({ foo, ...rest }: Slugs) => void >foo : string >rest : { bar: string; } @@ -39,5 +39,4 @@ call(obj, ({foo, ...rest}) => { >rest : { bar: string; } >bar : string - // ~~~ Property 'bar' does not exist on type 'Omit'. ts(2339) });