Skip to content

Stop looking at binding patterns for type argument inference #45719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25274,7 +25274,8 @@ namespace ts {
if (result) {
return result;
}
if (!(contextFlags! & ContextFlags.SkipBindingPatterns) && isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable
if (!(contextFlags! & ContextFlags.SkipBindingPatterns) && isBindingPattern(declaration.name)) {
// This is less a contextual type and more an implied shape - in some cases, this may be undesirable
return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
}
}
Expand Down Expand Up @@ -28573,7 +28574,7 @@ namespace ts {
// 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
// return type of 'wrap'.
if (node.kind !== SyntaxKind.Decorator) {
const contextualType = getContextualType(node, every(signature.typeParameters, p => !!getDefaultFromTypeParameter(p)) ? ContextFlags.SkipBindingPatterns : ContextFlags.None);
const contextualType = getContextualType(node, ContextFlags.SkipBindingPatterns);
if (contextualType) {
// We clone the inference context to avoid disturbing a resolution in progress for an
// outer call expression. Effectively we just want a snapshot of whatever has been
Expand Down
20 changes: 1 addition & 19 deletions tests/baselines/reference/destructuringTuple.errors.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
tests/cases/compiler/destructuringTuple.ts(11,7): error TS2461: Type 'number' is not an array type.
tests/cases/compiler/destructuringTuple.ts(11,48): error TS2769: No overload matches this call.
Overload 1 of 3, '(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number', gave the following error.
Type 'never[]' is not assignable to type 'number'.
Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error.
Type 'never[]' is not assignable to type '[]'.
Target allows only 0 element(s) but source may have more.
tests/cases/compiler/destructuringTuple.ts(11,60): error TS2769: No overload matches this call.
Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type 'number' is not assignable to parameter of type 'ConcatArray<never>'.
Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type 'number' is not assignable to parameter of type 'ConcatArray<never>'.


==== tests/cases/compiler/destructuringTuple.ts (3 errors) ====
==== tests/cases/compiler/destructuringTuple.ts (1 errors) ====
declare var tuple: [boolean, number, ...string[]];

const [a, b, c, ...rest] = tuple;
Expand All @@ -24,17 +17,6 @@ tests/cases/compiler/destructuringTuple.ts(11,60): error TS2769: No overload mat
// Repros from #32140

const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []);
~~~~~~~
!!! error TS2461: Type 'number' is not an array type.
~~~~~~~~~~~~~~~
!!! error TS2769: No overload matches this call.
!!! error TS2769: Overload 1 of 3, '(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number', gave the following error.
!!! error TS2769: Type 'never[]' is not assignable to type 'number'.
!!! error TS2769: Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error.
!!! error TS2769: Type 'never[]' is not assignable to type '[]'.
!!! error TS2769: Target allows only 0 element(s) but source may have more.
!!! related TS6502 /.ts/lib.es5.d.ts:1412:24: The expected type comes from the return type of this signature.
!!! related TS6502 /.ts/lib.es5.d.ts:1418:27: The expected type comes from the return type of this signature.
~~
!!! error TS2769: No overload matches this call.
!!! error TS2769: Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Expand Down
10 changes: 5 additions & 5 deletions tests/baselines/reference/destructuringTuple.types
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ declare var receiver: typeof tuple;
// Repros from #32140

const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []);
>oops1 : any
>[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : number
>oops1 : never
>[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : never[]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used to think [1, 2, 3].reduce((accu, el) => accu.concat(el), []) is a number. You probably need the (unfortunate) overload resolution error in the function body to get that far off track in the first place, but there’s really no reason why destructuring [oops1] from the result should have any effect on what we think this type is.

>[1, 2, 3].reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }
>[1, 2, 3] : number[]
>1 : 1
>2 : 2
>3 : 3
>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }
>(accu, el) => accu.concat(el) : (accu: [], el: number) => never[]
>accu : []
>(accu, el) => accu.concat(el) : (accu: never[], el: number) => never[]
>accu : never[]
>el : number
>accu.concat(el) : never[]
>accu.concat : { (...items: ConcatArray<never>[]): never[]; (...items: ConcatArray<never>[]): never[]; }
>accu : []
>accu : never[]
>concat : { (...items: ConcatArray<never>[]): never[]; (...items: ConcatArray<never>[]): never[]; }
>el : number
>[] : never[]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// <reference path="fourslash.ts" />

//// declare function pick<T, K extends keyof T>(keys: K[], obj: T): Pick<T, K>;
//// const { /**/ } = pick(['b'], { a: 'a', b: 'b' });

verify.completions({
marker: "",
exact: ["b"]
});