From c3bcc4cccb1e90eace671cf6428dde75eb887cd4 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 22 Sep 2021 12:00:31 -0700 Subject: [PATCH] Revert binding pattern inference changes, but only for tuples --- src/compiler/checker.ts | 5 +++-- src/compiler/types.ts | 4 +++- .../reference/destructuringTuple.errors.txt | 20 ++++++++++++++++++- .../reference/destructuringTuple.types | 10 +++++----- .../reference/destructuringTuple2.js | 7 +++++++ .../reference/destructuringTuple2.symbols | 14 +++++++++++++ .../reference/destructuringTuple2.types | 17 ++++++++++++++++ tests/cases/compiler/destructuringTuple2.ts | 2 ++ 8 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/destructuringTuple2.js create mode 100644 tests/baselines/reference/destructuringTuple2.symbols create mode 100644 tests/baselines/reference/destructuringTuple2.types create mode 100644 tests/cases/compiler/destructuringTuple2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 34c3379903c39..ece1fd3c13030 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25442,7 +25442,8 @@ namespace ts { if (result) { return result; } - if (!(contextFlags! & ContextFlags.SkipBindingPatterns) && isBindingPattern(declaration.name)) { + if (!(contextFlags! & ContextFlags.SkipObjectBindingPatterns) && isObjectBindingPattern(declaration.name) || + !(contextFlags! & ContextFlags.SkipArrayBindingPatterns) && isArrayBindingPattern(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); } @@ -28750,7 +28751,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, ContextFlags.SkipBindingPatterns); + const contextualType = getContextualType(node, ContextFlags.SkipObjectBindingPatterns); 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 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b6a6258b21a24..d07631751f7f5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4409,7 +4409,9 @@ namespace ts { Signature = 1 << 0, // Obtaining contextual signature NoConstraints = 1 << 1, // Don't obtain type variable constraints Completions = 1 << 2, // Ignore inference to current node and parent nodes out to the containing call for completions - SkipBindingPatterns = 1 << 3, // Ignore contextual types applied by binding patterns + SkipArrayBindingPatterns = 1 << 3, // Ignore contextual types applied by array binding patterns + SkipObjectBindingPatterns = 1 << 4, // Ignore contextual types applied by object binding patterns + SkipBindingPatterns = SkipArrayBindingPatterns | SkipObjectBindingPatterns, } // NOTE: If modifying this enum, must modify `TypeFormatFlags` too! diff --git a/tests/baselines/reference/destructuringTuple.errors.txt b/tests/baselines/reference/destructuringTuple.errors.txt index 2471c24dc9682..8e6ec9f05b65e 100644 --- a/tests/baselines/reference/destructuringTuple.errors.txt +++ b/tests/baselines/reference/destructuringTuple.errors.txt @@ -1,3 +1,10 @@ +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[]', gave the following error. Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. @@ -5,7 +12,7 @@ tests/cases/compiler/destructuringTuple.ts(11,60): error TS2769: No overload mat Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. -==== tests/cases/compiler/destructuringTuple.ts (1 errors) ==== +==== tests/cases/compiler/destructuringTuple.ts (3 errors) ==== declare var tuple: [boolean, number, ...string[]]; const [a, b, c, ...rest] = tuple; @@ -17,6 +24,17 @@ 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:1429:24: The expected type comes from the return type of this signature. +!!! related TS6502 /.ts/lib.es5.d.ts:1435: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[]', gave the following error. diff --git a/tests/baselines/reference/destructuringTuple.types b/tests/baselines/reference/destructuringTuple.types index e4fc79d71f688..0227d82572ddc 100644 --- a/tests/baselines/reference/destructuringTuple.types +++ b/tests/baselines/reference/destructuringTuple.types @@ -23,20 +23,20 @@ declare var receiver: typeof tuple; // Repros from #32140 const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); ->oops1 : never ->[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : never[] +>oops1 : any +>[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : number >[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; (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; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } ->(accu, el) => accu.concat(el) : (accu: never[], el: number) => never[] ->accu : never[] +>(accu, el) => accu.concat(el) : (accu: [], el: number) => never[] +>accu : [] >el : number >accu.concat(el) : never[] >accu.concat : { (...items: ConcatArray[]): never[]; (...items: ConcatArray[]): never[]; } ->accu : never[] +>accu : [] >concat : { (...items: ConcatArray[]): never[]; (...items: ConcatArray[]): never[]; } >el : number >[] : never[] diff --git a/tests/baselines/reference/destructuringTuple2.js b/tests/baselines/reference/destructuringTuple2.js new file mode 100644 index 0000000000000..99fd18324c173 --- /dev/null +++ b/tests/baselines/reference/destructuringTuple2.js @@ -0,0 +1,7 @@ +//// [destructuringTuple2.ts] +declare const f: (cb: () => T) => T; +const [a, b, c] = f(() => [1, "hi", true]); + + +//// [destructuringTuple2.js] +var _a = f(function () { return [1, "hi", true]; }), a = _a[0], b = _a[1], c = _a[2]; diff --git a/tests/baselines/reference/destructuringTuple2.symbols b/tests/baselines/reference/destructuringTuple2.symbols new file mode 100644 index 0000000000000..f379524614f3f --- /dev/null +++ b/tests/baselines/reference/destructuringTuple2.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/destructuringTuple2.ts === +declare const f: (cb: () => T) => T; +>f : Symbol(f, Decl(destructuringTuple2.ts, 0, 13)) +>T : Symbol(T, Decl(destructuringTuple2.ts, 0, 18)) +>cb : Symbol(cb, Decl(destructuringTuple2.ts, 0, 21)) +>T : Symbol(T, Decl(destructuringTuple2.ts, 0, 18)) +>T : Symbol(T, Decl(destructuringTuple2.ts, 0, 18)) + +const [a, b, c] = f(() => [1, "hi", true]); +>a : Symbol(a, Decl(destructuringTuple2.ts, 1, 7)) +>b : Symbol(b, Decl(destructuringTuple2.ts, 1, 9)) +>c : Symbol(c, Decl(destructuringTuple2.ts, 1, 12)) +>f : Symbol(f, Decl(destructuringTuple2.ts, 0, 13)) + diff --git a/tests/baselines/reference/destructuringTuple2.types b/tests/baselines/reference/destructuringTuple2.types new file mode 100644 index 0000000000000..8c32c810f6608 --- /dev/null +++ b/tests/baselines/reference/destructuringTuple2.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/destructuringTuple2.ts === +declare const f: (cb: () => T) => T; +>f : (cb: () => T) => T +>cb : () => T + +const [a, b, c] = f(() => [1, "hi", true]); +>a : number +>b : string +>c : boolean +>f(() => [1, "hi", true]) : [number, string, boolean] +>f : (cb: () => T) => T +>() => [1, "hi", true] : () => [number, string, boolean] +>[1, "hi", true] : [number, string, true] +>1 : 1 +>"hi" : "hi" +>true : true + diff --git a/tests/cases/compiler/destructuringTuple2.ts b/tests/cases/compiler/destructuringTuple2.ts new file mode 100644 index 0000000000000..69c7cc16acb89 --- /dev/null +++ b/tests/cases/compiler/destructuringTuple2.ts @@ -0,0 +1,2 @@ +declare const f: (cb: () => T) => T; +const [a, b, c] = f(() => [1, "hi", true]);