From dcc5815d832e9f0b2e0602736e43874d8e7aa3f5 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 4 Dec 2017 13:03:20 -0800 Subject: [PATCH] Hack to allow concat to work even when an Array isn't assignable to ReadonlyArray --- src/lib/es5.d.ts | 9 ++--- tests/baselines/reference/arrayConcat2.types | 12 +++---- tests/baselines/reference/arrayConcat3.js | 12 +++++++ .../baselines/reference/arrayConcat3.symbols | 32 ++++++++++++++++++ tests/baselines/reference/arrayConcat3.types | 33 +++++++++++++++++++ .../baselines/reference/arrayConcatMap.types | 4 +-- ...typeIsAssignableToReadonlyArray.errors.txt | 8 ++--- tests/baselines/reference/concatError.types | 8 ++--- tests/baselines/reference/concatTuples.types | 4 +-- .../emitSkipsThisWithRestParameter.types | 4 +-- .../intersectionTypeInference3.types | 4 +-- .../iteratorSpreadInArray6.errors.txt | 30 ++++++++++++----- .../reference/iteratorSpreadInArray6.types | 4 +-- .../reference/iteratorSpreadInArray7.types | 4 +-- .../reference/parserRealSource4.types | 4 +-- tests/baselines/reference/parserharness.types | 4 +-- .../reference/restInvalidArgumentType.types | 2 +- .../reference/spreadInvalidArgumentType.types | 4 +-- ...ymousTypeNotReferencingTypeParameter.types | 4 +-- .../baselines/reference/underscoreTest1.types | 4 +-- tests/cases/compiler/arrayConcat3.ts | 5 +++ 21 files changed, 146 insertions(+), 49 deletions(-) create mode 100644 tests/baselines/reference/arrayConcat3.js create mode 100644 tests/baselines/reference/arrayConcat3.symbols create mode 100644 tests/baselines/reference/arrayConcat3.types create mode 100644 tests/cases/compiler/arrayConcat3.ts diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index aaefeec7d1a52..93f9081bc7a5d 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -992,12 +992,13 @@ interface ReadonlyArray { * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: ReadonlyArray[]): T[]; + // TODO: https://github.com/Microsoft/TypeScript/issues/20454 + concat(...items: (T[] | ReadonlyArray)[]): T[]; /** * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: (T | ReadonlyArray)[]): T[]; + concat(...items: (T | T[] | ReadonlyArray)[]): T[]; /** * Adds all the elements of an array separated by the specified separator string. * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. @@ -1113,12 +1114,12 @@ interface Array { * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: ReadonlyArray[]): T[]; + concat(...items: (T[] | ReadonlyArray)[]): T[]; /** * Combines two or more arrays. * @param items Additional items to add to the end of array1. */ - concat(...items: (T | ReadonlyArray)[]): T[]; + concat(...items: (T | T[] | ReadonlyArray)[]): T[]; /** * Adds all the elements of an array separated by the specified separator string. * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. diff --git a/tests/baselines/reference/arrayConcat2.types b/tests/baselines/reference/arrayConcat2.types index b63f33eb7b117..2e33d4cd023b3 100644 --- a/tests/baselines/reference/arrayConcat2.types +++ b/tests/baselines/reference/arrayConcat2.types @@ -5,17 +5,17 @@ var a: string[] = []; a.concat("hello", 'world'); >a.concat("hello", 'world') : string[] ->a.concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>a.concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >a : string[] ->concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >"hello" : "hello" >'world' : "world" a.concat('Hello'); >a.concat('Hello') : string[] ->a.concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>a.concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >a : string[] ->concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >'Hello' : "Hello" var b = new Array(); @@ -25,8 +25,8 @@ var b = new Array(); b.concat('hello'); >b.concat('hello') : string[] ->b.concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>b.concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >b : string[] ->concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >'hello' : "hello" diff --git a/tests/baselines/reference/arrayConcat3.js b/tests/baselines/reference/arrayConcat3.js new file mode 100644 index 0000000000000..90226797706e2 --- /dev/null +++ b/tests/baselines/reference/arrayConcat3.js @@ -0,0 +1,12 @@ +//// [arrayConcat3.ts] +// TODO: remove lib hack when https://github.com/Microsoft/TypeScript/issues/20454 is fixed +type Fn = (subj: U) => U +function doStuff(a: Array>, b: Array>) { + b.concat(a); +} + + +//// [arrayConcat3.js] +function doStuff(a, b) { + b.concat(a); +} diff --git a/tests/baselines/reference/arrayConcat3.symbols b/tests/baselines/reference/arrayConcat3.symbols new file mode 100644 index 0000000000000..373c8d7041b84 --- /dev/null +++ b/tests/baselines/reference/arrayConcat3.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/arrayConcat3.ts === +// TODO: remove lib hack when https://github.com/Microsoft/TypeScript/issues/20454 is fixed +type Fn = (subj: U) => U +>Fn : Symbol(Fn, Decl(arrayConcat3.ts, 0, 0)) +>T : Symbol(T, Decl(arrayConcat3.ts, 1, 8)) +>U : Symbol(U, Decl(arrayConcat3.ts, 1, 29)) +>T : Symbol(T, Decl(arrayConcat3.ts, 1, 8)) +>subj : Symbol(subj, Decl(arrayConcat3.ts, 1, 42)) +>U : Symbol(U, Decl(arrayConcat3.ts, 1, 29)) +>U : Symbol(U, Decl(arrayConcat3.ts, 1, 29)) + +function doStuff(a: Array>, b: Array>) { +>doStuff : Symbol(doStuff, Decl(arrayConcat3.ts, 1, 55)) +>T : Symbol(T, Decl(arrayConcat3.ts, 2, 17)) +>T1 : Symbol(T1, Decl(arrayConcat3.ts, 2, 34)) +>T : Symbol(T, Decl(arrayConcat3.ts, 2, 17)) +>a : Symbol(a, Decl(arrayConcat3.ts, 2, 49)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Fn : Symbol(Fn, Decl(arrayConcat3.ts, 0, 0)) +>T : Symbol(T, Decl(arrayConcat3.ts, 2, 17)) +>b : Symbol(b, Decl(arrayConcat3.ts, 2, 65)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Fn : Symbol(Fn, Decl(arrayConcat3.ts, 0, 0)) +>T1 : Symbol(T1, Decl(arrayConcat3.ts, 2, 34)) + + b.concat(a); +>b.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b : Symbol(b, Decl(arrayConcat3.ts, 2, 65)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(arrayConcat3.ts, 2, 49)) +} + diff --git a/tests/baselines/reference/arrayConcat3.types b/tests/baselines/reference/arrayConcat3.types new file mode 100644 index 0000000000000..2bfbe09a1765d --- /dev/null +++ b/tests/baselines/reference/arrayConcat3.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/arrayConcat3.ts === +// TODO: remove lib hack when https://github.com/Microsoft/TypeScript/issues/20454 is fixed +type Fn = (subj: U) => U +>Fn : Fn +>T : T +>U : U +>T : T +>subj : U +>U : U +>U : U + +function doStuff(a: Array>, b: Array>) { +>doStuff : (a: Fn[], b: Fn[]) => void +>T : T +>T1 : T1 +>T : T +>a : Fn[] +>Array : T[] +>Fn : Fn +>T : T +>b : Fn[] +>Array : T[] +>Fn : Fn +>T1 : T1 + + b.concat(a); +>b.concat(a) : Fn[] +>b.concat : { (...items: (Fn[] | ReadonlyArray>)[]): Fn[]; (...items: (Fn | Fn[] | ReadonlyArray>)[]): Fn[]; } +>b : Fn[] +>concat : { (...items: (Fn[] | ReadonlyArray>)[]): Fn[]; (...items: (Fn | Fn[] | ReadonlyArray>)[]): Fn[]; } +>a : Fn[] +} + diff --git a/tests/baselines/reference/arrayConcatMap.types b/tests/baselines/reference/arrayConcatMap.types index db5b3774db0b2..cbb30b8304ad6 100644 --- a/tests/baselines/reference/arrayConcatMap.types +++ b/tests/baselines/reference/arrayConcatMap.types @@ -4,9 +4,9 @@ var x = [].concat([{ a: 1 }], [{ a: 2 }]) >[].concat([{ a: 1 }], [{ a: 2 }]) .map(b => b.a) : any[] >[].concat([{ a: 1 }], [{ a: 2 }]) .map : (callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[] >[].concat([{ a: 1 }], [{ a: 2 }]) : any[] ->[].concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>[].concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >[] : undefined[] ->concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >[{ a: 1 }] : { a: number; }[] >{ a: 1 } : { a: number; } >a : number diff --git a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt index 7ffe8317d4228..87c8b59ee1e61 100644 --- a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt +++ b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt @@ -1,12 +1,12 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. - Type '{ (...items: ReadonlyArray[]): A[]; (...items: (A | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): B[]; (...items: (B | ReadonlyArray)[]): B[]; }'. + Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. Type 'A[]' is not assignable to type 'B[]'. Type 'A' is not assignable to type 'B'. Property 'b' is missing in type 'A'. tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. - Type '{ (...items: ReadonlyArray[]): A[]; (...items: (A | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): B[]; (...items: (B | ReadonlyArray)[]): B[]; }'. + Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. Type 'A[]' is not assignable to type 'B[]'. @@ -27,7 +27,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T ~~~ !!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. !!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ReadonlyArray[]): A[]; (...items: (A | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): B[]; (...items: (B | ReadonlyArray)[]): B[]; }'. +!!! error TS2322: Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. !!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. !!! error TS2322: Type 'A' is not assignable to type 'B'. !!! error TS2322: Property 'b' is missing in type 'A'. @@ -39,6 +39,6 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T ~~~ !!! error TS2322: Type 'C' is not assignable to type 'ReadonlyArray'. !!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ReadonlyArray[]): A[]; (...items: (A | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): B[]; (...items: (B | ReadonlyArray)[]): B[]; }'. +!!! error TS2322: Type '{ (...items: (A[] | ReadonlyArray)[]): A[]; (...items: (A | A[] | ReadonlyArray)[]): A[]; }' is not assignable to type '{ (...items: (B[] | ReadonlyArray)[]): B[]; (...items: (B | B[] | ReadonlyArray)[]): B[]; }'. !!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. \ No newline at end of file diff --git a/tests/baselines/reference/concatError.types b/tests/baselines/reference/concatError.types index 729704789074a..c7f07e4ea9605 100644 --- a/tests/baselines/reference/concatError.types +++ b/tests/baselines/reference/concatError.types @@ -15,9 +15,9 @@ fa = fa.concat([0]); >fa = fa.concat([0]) : number[] >fa : number[] >fa.concat([0]) : number[] ->fa.concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>fa.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >fa : number[] ->concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >[0] : number[] >0 : 0 @@ -25,9 +25,9 @@ fa = fa.concat(0); >fa = fa.concat(0) : number[] >fa : number[] >fa.concat(0) : number[] ->fa.concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>fa.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >fa : number[] ->concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >0 : 0 diff --git a/tests/baselines/reference/concatTuples.types b/tests/baselines/reference/concatTuples.types index 147d76efd0436..46c06357b998b 100644 --- a/tests/baselines/reference/concatTuples.types +++ b/tests/baselines/reference/concatTuples.types @@ -10,9 +10,9 @@ ijs = ijs.concat([[3, 4], [5, 6]]); >ijs = ijs.concat([[3, 4], [5, 6]]) : [number, number][] >ijs : [number, number][] >ijs.concat([[3, 4], [5, 6]]) : [number, number][] ->ijs.concat : { (...items: ReadonlyArray<[number, number]>[]): [number, number][]; (...items: ([number, number] | ReadonlyArray<[number, number]>)[]): [number, number][]; } +>ijs.concat : { (...items: ([number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; (...items: ([number, number] | [number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; } >ijs : [number, number][] ->concat : { (...items: ReadonlyArray<[number, number]>[]): [number, number][]; (...items: ([number, number] | ReadonlyArray<[number, number]>)[]): [number, number][]; } +>concat : { (...items: ([number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; (...items: ([number, number] | [number, number][] | ReadonlyArray<[number, number]>)[]): [number, number][]; } >[[3, 4], [5, 6]] : [number, number][] >[3, 4] : [number, number] >3 : 3 diff --git a/tests/baselines/reference/emitSkipsThisWithRestParameter.types b/tests/baselines/reference/emitSkipsThisWithRestParameter.types index f8a538acdc2dc..9d560a9e92f19 100644 --- a/tests/baselines/reference/emitSkipsThisWithRestParameter.types +++ b/tests/baselines/reference/emitSkipsThisWithRestParameter.types @@ -18,10 +18,10 @@ function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any >apply : (this: Function, thisArg: any, argArray?: any) => any >this : any >[ this ].concat(args) : any[] ->[ this ].concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>[ this ].concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >[ this ] : any[] >this : any ->concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >args : any[] }; diff --git a/tests/baselines/reference/intersectionTypeInference3.types b/tests/baselines/reference/intersectionTypeInference3.types index 9fca37af8c197..3e88e3b874a71 100644 --- a/tests/baselines/reference/intersectionTypeInference3.types +++ b/tests/baselines/reference/intersectionTypeInference3.types @@ -32,13 +32,13 @@ declare const b: Set; const c1 = Array.from(a).concat(Array.from(b)); >c1 : Nominal<"A", string>[] >Array.from(a).concat(Array.from(b)) : Nominal<"A", string>[] ->Array.from(a).concat : { (...items: ReadonlyArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ReadonlyArray>)[]): Nominal<"A", string>[]; } +>Array.from(a).concat : { (...items: (Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; } >Array.from(a) : Nominal<"A", string>[] >Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor >from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >a : Set> ->concat : { (...items: ReadonlyArray>[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | ReadonlyArray>)[]): Nominal<"A", string>[]; } +>concat : { (...items: (Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; (...items: (Nominal<"A", string> | Nominal<"A", string>[] | ReadonlyArray>)[]): Nominal<"A", string>[]; } >Array.from(b) : Nominal<"A", string>[] >Array.from : { (iterable: Iterable): T[]; (iterable: Iterable, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; (arrayLike: ArrayLike): T[]; (arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; } >Array : ArrayConstructor diff --git a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt index bb64374aaaed0..17738ba06d58f 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt @@ -1,10 +1,17 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | ReadonlyArray'. +tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[] | ReadonlyArray'. Type 'symbol[]' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. - Type '{ (...items: ReadonlyArray[]): symbol[]; (...items: (symbol | ReadonlyArray)[]): symbol[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. + Type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }' is not assignable to type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }'. Types of parameters 'items' and 'items' are incompatible. - Type 'ReadonlyArray' is not assignable to type 'ReadonlyArray'. - Type 'number' is not assignable to type 'symbol'. + Type 'number[] | ReadonlyArray' is not assignable to type 'symbol[] | ReadonlyArray'. + Type 'number[]' is not assignable to type 'symbol[] | ReadonlyArray'. + Type 'number[]' is not assignable to type 'ReadonlyArray'. + Types of property 'concat' are incompatible. + Type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }' is not assignable to type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }'. + Types of parameters 'items' and 'items' are incompatible. + Type 'symbol[] | ReadonlyArray' is not assignable to type 'number[] | ReadonlyArray'. + Type 'symbol[]' is not assignable to type 'number[] | ReadonlyArray'. + Type 'symbol[]' is not assignable to type 'ReadonlyArray'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts (1 errors) ==== @@ -24,10 +31,17 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS234 var array: number[] = [0, 1]; array.concat([...new SymbolIterator]); ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | ReadonlyArray'. +!!! error TS2345: Argument of type 'symbol[]' is not assignable to parameter of type 'number | number[] | ReadonlyArray'. !!! error TS2345: Type 'symbol[]' is not assignable to type 'ReadonlyArray'. !!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: ReadonlyArray[]): symbol[]; (...items: (symbol | ReadonlyArray)[]): symbol[]; }' is not assignable to type '{ (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; }'. +!!! error TS2345: Type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }' is not assignable to type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }'. !!! error TS2345: Types of parameters 'items' and 'items' are incompatible. -!!! error TS2345: Type 'ReadonlyArray' is not assignable to type 'ReadonlyArray'. -!!! error TS2345: Type 'number' is not assignable to type 'symbol'. \ No newline at end of file +!!! error TS2345: Type 'number[] | ReadonlyArray' is not assignable to type 'symbol[] | ReadonlyArray'. +!!! error TS2345: Type 'number[]' is not assignable to type 'symbol[] | ReadonlyArray'. +!!! error TS2345: Type 'number[]' is not assignable to type 'ReadonlyArray'. +!!! error TS2345: Types of property 'concat' are incompatible. +!!! error TS2345: Type '{ (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; }' is not assignable to type '{ (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; }'. +!!! error TS2345: Types of parameters 'items' and 'items' are incompatible. +!!! error TS2345: Type 'symbol[] | ReadonlyArray' is not assignable to type 'number[] | ReadonlyArray'. +!!! error TS2345: Type 'symbol[]' is not assignable to type 'number[] | ReadonlyArray'. +!!! error TS2345: Type 'symbol[]' is not assignable to type 'ReadonlyArray'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray6.types b/tests/baselines/reference/iteratorSpreadInArray6.types index 5ed866d78694c..dbf94611fabf6 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.types +++ b/tests/baselines/reference/iteratorSpreadInArray6.types @@ -38,9 +38,9 @@ var array: number[] = [0, 1]; array.concat([...new SymbolIterator]); >array.concat([...new SymbolIterator]) : any ->array.concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>array.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >array : number[] ->concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >[...new SymbolIterator] : symbol[] >...new SymbolIterator : symbol >new SymbolIterator : SymbolIterator diff --git a/tests/baselines/reference/iteratorSpreadInArray7.types b/tests/baselines/reference/iteratorSpreadInArray7.types index 3711fc9fed3d7..b0d9fbcc77cd5 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.types +++ b/tests/baselines/reference/iteratorSpreadInArray7.types @@ -35,9 +35,9 @@ var array: symbol[]; array.concat([...new SymbolIterator]); >array.concat([...new SymbolIterator]) : symbol[] ->array.concat : { (...items: ReadonlyArray[]): symbol[]; (...items: (symbol | ReadonlyArray)[]): symbol[]; } +>array.concat : { (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; } >array : symbol[] ->concat : { (...items: ReadonlyArray[]): symbol[]; (...items: (symbol | ReadonlyArray)[]): symbol[]; } +>concat : { (...items: (symbol[] | ReadonlyArray)[]): symbol[]; (...items: (symbol | symbol[] | ReadonlyArray)[]): symbol[]; } >[...new SymbolIterator] : symbol[] >...new SymbolIterator : symbol >new SymbolIterator : SymbolIterator diff --git a/tests/baselines/reference/parserRealSource4.types b/tests/baselines/reference/parserRealSource4.types index 2353d4720f2a5..cc16886c3d549 100644 --- a/tests/baselines/reference/parserRealSource4.types +++ b/tests/baselines/reference/parserRealSource4.types @@ -424,14 +424,14 @@ module TypeScript { return this.primaryTable.getAllKeys().concat(this.secondaryTable.getAllKeys()); >this.primaryTable.getAllKeys().concat(this.secondaryTable.getAllKeys()) : string[] ->this.primaryTable.getAllKeys().concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>this.primaryTable.getAllKeys().concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >this.primaryTable.getAllKeys() : string[] >this.primaryTable.getAllKeys : () => string[] >this.primaryTable : IHashTable >this : this >primaryTable : IHashTable >getAllKeys : () => string[] ->concat : { (...items: ReadonlyArray[]): string[]; (...items: (string | ReadonlyArray)[]): string[]; } +>concat : { (...items: (string[] | ReadonlyArray)[]): string[]; (...items: (string | string[] | ReadonlyArray)[]): string[]; } >this.secondaryTable.getAllKeys() : string[] >this.secondaryTable.getAllKeys : () => string[] >this.secondaryTable : IHashTable diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 7cfb8ff7816a2..284eb887dd484 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -4868,9 +4868,9 @@ module Harness { >lines = lines.concat(v.file.lines) : any[] >lines : any[] >lines.concat(v.file.lines) : any[] ->lines.concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>lines.concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >lines : any[] ->concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >v.file.lines : string[] >v.file : WriterAggregator >v : { filename: string; file: WriterAggregator; } diff --git a/tests/baselines/reference/restInvalidArgumentType.types b/tests/baselines/reference/restInvalidArgumentType.types index 39495008877a7..389e9a070aaf1 100644 --- a/tests/baselines/reference/restInvalidArgumentType.types +++ b/tests/baselines/reference/restInvalidArgumentType.types @@ -87,7 +87,7 @@ function f(p1: T, p2: T[]) { >p1 : T var {...r2} = p2; // OK ->r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: (T[] | ReadonlyArray)[]): T[]; concat(...items: (T | T[] | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >p2 : T[] var {...r3} = t; // Error, generic type paramter diff --git a/tests/baselines/reference/spreadInvalidArgumentType.types b/tests/baselines/reference/spreadInvalidArgumentType.types index ae85189962215..49d5bc962611d 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.types +++ b/tests/baselines/reference/spreadInvalidArgumentType.types @@ -89,8 +89,8 @@ function f(p1: T, p2: T[]) { >p1 : T var o2 = { ...p2 }; // OK ->o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } ->{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: (T[] | ReadonlyArray)[]): T[]; concat(...items: (T | T[] | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: (T[] | ReadonlyArray)[]): T[]; concat(...items: (T | T[] | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >p2 : T[] var o3 = { ...t }; // Error, generic type paramter diff --git a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types index 9cd8571bf6129..e4dc5df9449f9 100644 --- a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types +++ b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types @@ -348,9 +348,9 @@ class ListWrapper { >a : any[] >b : any[] >a.concat(b) : any[] ->a.concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>a.concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >a : any[] ->concat : { (...items: ReadonlyArray[]): any[]; (...items: any[]): any[]; } +>concat : { (...items: (any[] | ReadonlyArray)[]): any[]; (...items: any[]): any[]; } >b : any[] static insert(dit: typeof ListWrapper, list: T[], index: number, value: T) { list.splice(index, 0, value); } diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 1871865884de7..8c6b2691e4ed6 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -124,9 +124,9 @@ var flat = _.reduceRight(list, (a, b) => a.concat(b), []); >a : number[] >b : number[] >a.concat(b) : number[] ->a.concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>a.concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >a : number[] ->concat : { (...items: ReadonlyArray[]): number[]; (...items: (number | ReadonlyArray)[]): number[]; } +>concat : { (...items: (number[] | ReadonlyArray)[]): number[]; (...items: (number | number[] | ReadonlyArray)[]): number[]; } >b : number[] >[] : undefined[] diff --git a/tests/cases/compiler/arrayConcat3.ts b/tests/cases/compiler/arrayConcat3.ts new file mode 100644 index 0000000000000..d66d488a20d64 --- /dev/null +++ b/tests/cases/compiler/arrayConcat3.ts @@ -0,0 +1,5 @@ +// TODO: remove lib hack when https://github.com/Microsoft/TypeScript/issues/20454 is fixed +type Fn = (subj: U) => U +function doStuff(a: Array>, b: Array>) { + b.concat(a); +}