210 lines
10 KiB
Plaintext
210 lines
10 KiB
Plaintext
=== tests/cases/compiler/arrayFrom.ts ===
|
|
// Tests fix for #20432, ensures Array.from accepts all valid inputs
|
|
// Also tests for #19682
|
|
|
|
interface A {
|
|
>A : A
|
|
|
|
a: string;
|
|
>a : string
|
|
}
|
|
|
|
interface B {
|
|
>B : B
|
|
|
|
b: string;
|
|
>b : string
|
|
}
|
|
|
|
const inputA: A[] = [];
|
|
>inputA : A[]
|
|
>A : A
|
|
>[] : undefined[]
|
|
|
|
const inputB: B[] = [];
|
|
>inputB : B[]
|
|
>B : B
|
|
>[] : undefined[]
|
|
|
|
const inputALike: ArrayLike<A> = { length: 0 };
|
|
>inputALike : ArrayLike<A>
|
|
>ArrayLike : ArrayLike<T>
|
|
>A : A
|
|
>{ length: 0 } : { length: number; }
|
|
>length : number
|
|
>0 : 0
|
|
|
|
const inputARand = getEither(inputA, inputALike);
|
|
>inputARand : ArrayLike<A> | Iterable<A>
|
|
>getEither(inputA, inputALike) : ArrayLike<A> | Iterable<A>
|
|
>getEither : <T>(in1: Iterable<T>, in2: ArrayLike<T>) => Iterable<T> | ArrayLike<T>
|
|
>inputA : A[]
|
|
>inputALike : ArrayLike<A>
|
|
|
|
const inputASet = new Set<A>();
|
|
>inputASet : Set<A>
|
|
>new Set<A>() : Set<A>
|
|
>Set : SetConstructor
|
|
>A : A
|
|
|
|
const result1: A[] = Array.from(inputA);
|
|
>result1 : A[]
|
|
>A : A
|
|
>Array.from(inputA) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputA : A[]
|
|
|
|
const result2: A[] = Array.from(inputA.values());
|
|
>result2 : A[]
|
|
>A : A
|
|
>Array.from(inputA.values()) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputA.values() : IterableIterator<A>
|
|
>inputA.values : () => IterableIterator<A>
|
|
>inputA : A[]
|
|
>values : () => IterableIterator<A>
|
|
|
|
const result3: B[] = Array.from(inputA.values()); // expect error
|
|
>result3 : B[]
|
|
>B : B
|
|
>Array.from(inputA.values()) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputA.values() : IterableIterator<A>
|
|
>inputA.values : () => IterableIterator<A>
|
|
>inputA : A[]
|
|
>values : () => IterableIterator<A>
|
|
|
|
const result4: A[] = Array.from(inputB, ({ b }): A => ({ a: b }));
|
|
>result4 : A[]
|
|
>A : A
|
|
>Array.from(inputB, ({ b }): A => ({ a: b })) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputB : B[]
|
|
>({ b }): A => ({ a: b }) : ({ b }: B) => A
|
|
>b : string
|
|
>A : A
|
|
>({ a: b }) : { a: string; }
|
|
>{ a: b } : { a: string; }
|
|
>a : string
|
|
>b : string
|
|
|
|
const result5: A[] = Array.from(inputALike);
|
|
>result5 : A[]
|
|
>A : A
|
|
>Array.from(inputALike) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputALike : ArrayLike<A>
|
|
|
|
const result6: B[] = Array.from(inputALike); // expect error
|
|
>result6 : B[]
|
|
>B : B
|
|
>Array.from(inputALike) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputALike : ArrayLike<A>
|
|
|
|
const result7: B[] = Array.from(inputALike, ({ a }): B => ({ b: a }));
|
|
>result7 : B[]
|
|
>B : B
|
|
>Array.from(inputALike, ({ a }): B => ({ b: a })) : B[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputALike : ArrayLike<A>
|
|
>({ a }): B => ({ b: a }) : ({ a }: A) => B
|
|
>a : string
|
|
>B : B
|
|
>({ b: a }) : { b: string; }
|
|
>{ b: a } : { b: string; }
|
|
>b : string
|
|
>a : string
|
|
|
|
const result8: A[] = Array.from(inputARand);
|
|
>result8 : A[]
|
|
>A : A
|
|
>Array.from(inputARand) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputARand : ArrayLike<A> | Iterable<A>
|
|
|
|
const result9: B[] = Array.from(inputARand, ({ a }): B => ({ b: a }));
|
|
>result9 : B[]
|
|
>B : B
|
|
>Array.from(inputARand, ({ a }): B => ({ b: a })) : B[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputARand : ArrayLike<A> | Iterable<A>
|
|
>({ a }): B => ({ b: a }) : ({ a }: A) => B
|
|
>a : string
|
|
>B : B
|
|
>({ b: a }) : { b: string; }
|
|
>{ b: a } : { b: string; }
|
|
>b : string
|
|
>a : string
|
|
|
|
const result10: A[] = Array.from(new Set<A>());
|
|
>result10 : A[]
|
|
>A : A
|
|
>Array.from(new Set<A>()) : A[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>new Set<A>() : Set<A>
|
|
>Set : SetConstructor
|
|
>A : A
|
|
|
|
const result11: B[] = Array.from(inputASet, ({ a }): B => ({ b: a }));
|
|
>result11 : B[]
|
|
>B : B
|
|
>Array.from(inputASet, ({ a }): B => ({ b: a })) : B[]
|
|
>Array.from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>Array : ArrayConstructor
|
|
>from : { <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(iterable: Iterable<T> | ArrayLike<T>): T[]; <T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
|
>inputASet : Set<A>
|
|
>({ a }): B => ({ b: a }) : ({ a }: A) => B
|
|
>a : string
|
|
>B : B
|
|
>({ b: a }) : { b: string; }
|
|
>{ b: a } : { b: string; }
|
|
>b : string
|
|
>a : string
|
|
|
|
// if this is written inline, the compiler seems to infer
|
|
// the ?: as always taking the false branch, narrowing to ArrayLike<T>,
|
|
// even when the type is written as : Iterable<T>|ArrayLike<T>
|
|
function getEither<T> (in1: Iterable<T>, in2: ArrayLike<T>) {
|
|
>getEither : <T>(in1: Iterable<T>, in2: ArrayLike<T>) => Iterable<T> | ArrayLike<T>
|
|
>T : T
|
|
>in1 : Iterable<T>
|
|
>Iterable : Iterable<T>
|
|
>T : T
|
|
>in2 : ArrayLike<T>
|
|
>ArrayLike : ArrayLike<T>
|
|
>T : T
|
|
|
|
return Math.random() > 0.5 ? in1 : in2;
|
|
>Math.random() > 0.5 ? in1 : in2 : Iterable<T> | ArrayLike<T>
|
|
>Math.random() > 0.5 : boolean
|
|
>Math.random() : number
|
|
>Math.random : () => number
|
|
>Math : Math
|
|
>random : () => number
|
|
>0.5 : 0.5
|
|
>in1 : Iterable<T>
|
|
>in2 : ArrayLike<T>
|
|
}
|
|
|