Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions src/lib/es2015.iterable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ interface Array<T> {
}

interface ArrayConstructor {
isArray<T>(arg: Iterable<T>): arg is readonly T[];

/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
Expand Down
3 changes: 2 additions & 1 deletion src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,8 @@ interface ArrayConstructor {
(arrayLength?: number): any[];
<T>(arrayLength: number): T[];
<T>(...items: T[]): T[];
isArray(arg: any): arg is any[];
isArray<T>(arg: ArrayLike<T>): arg is readonly T[];
isArray(arg: unknown): arg is any[];
Comment thread
jakebailey marked this conversation as resolved.
readonly prototype: any[];
}

Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/arrayDestructuringInSwitch1.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export function evaluate(expression: Expression): boolean {
>Expression : Symbol(Expression, Decl(arrayDestructuringInSwitch1.ts, 0, 0))

if (Array.isArray(expression)) {
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>expression : Symbol(expression, Decl(arrayDestructuringInSwitch1.ts, 3, 25))

const [operator, ...operands] = expression;
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/arrayDestructuringInSwitch1.types
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export function evaluate(expression: Expression): boolean {

if (Array.isArray(expression)) {
>Array.isArray(expression) : boolean
>Array.isArray : (arg: any) => arg is any[]
>Array.isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; }
>Array : ArrayConstructor
>isArray : (arg: any) => arg is any[]
>isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; }
>expression : Expression

const [operator, ...operands] = expression;
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/arrayTypeOfTypeOf.types
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ var xs2: typeof Array;
>Array : ArrayConstructor

var xs3: typeof Array<number>;
>xs3 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
>xs3 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray<T>(arg: ArrayLike<T>): arg is readonly T[]; isArray(arg: unknown): arg is any[]; readonly prototype: any[]; }
>Array : ArrayConstructor

var xs4: typeof Array<typeof x>;
>xs4 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
>xs4 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray<T>(arg: ArrayLike<T>): arg is readonly T[]; isArray(arg: unknown): arg is any[]; readonly prototype: any[]; }
>Array : ArrayConstructor
>x : number

Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ export const updateIfChanged = <T>(t: T) => {
>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
>[key] : Symbol([key], Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 12, 80))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ export const updateIfChanged = <T>(t: T) => {
>assign : { <T extends {}, U>(target: T, source: U): T & U; <T extends {}, U, V>(target: T, source1: U, source2: V): T & U & V; <T extends {}, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
>Array.isArray(u) ? [] : {} : undefined[] | {}
>Array.isArray(u) : boolean
>Array.isArray : (arg: any) => arg is any[]
>Array.isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; <T>(arg: Iterable<T>): arg is readonly T[]; }
>Array : ArrayConstructor
>isArray : (arg: any) => arg is any[]
>isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; <T>(arg: Iterable<T>): arg is readonly T[]; }
>u : U
>[] : undefined[]
>{} : {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
a1(...array2); // Error parameter type is (number|string)[]
~~~~~~
!!! error TS2552: Cannot find name 'array2'. Did you mean 'Array'?
!!! related TS2728 /.ts/lib.es5.d.ts:1470:13: 'Array' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1471:13: 'Array' is declared here.
Comment thread
jakebailey marked this conversation as resolved.
Outdated
a5([1, 2, "string", false, true]); // Error, parameter type is [any, any, [[any]]]
~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type '[[any]]'.
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/fixSignatureCaching.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,9 @@ define(function () {
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>value : Symbol(value, Decl(fixSignatureCaching.ts, 297, 34))
>Object.prototype.toString.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --))
>Object.prototype.toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --))
Expand All @@ -825,9 +825,9 @@ define(function () {
>value : Symbol(value, Decl(fixSignatureCaching.ts, 299, 20))

: Array.isArray;
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

function equalIC(a, b) {
>equalIC : Symbol(equalIC, Decl(fixSignatureCaching.ts, 300, 24))
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/fixSignatureCaching.types
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,9 @@ define(function () {
>Array : ArrayConstructor

Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
>Array.isArray : (arg: any) => arg is any[]
>Array.isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; }
>Array : ArrayConstructor
>isArray : (arg: any) => arg is any[]
>isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; }
>function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : (value: any) => boolean
>value : any
>Object.prototype.toString.call(value) === '[object Array]' : boolean
Expand Down Expand Up @@ -1150,9 +1150,9 @@ define(function () {
>'[object Array]' : "[object Array]"

: Array.isArray;
>Array.isArray : (arg: any) => arg is any[]
>Array.isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; }
>Array : ArrayConstructor
>isArray : (arg: any) => arg is any[]
>isArray : { <T>(arg: ArrayLike<T>): arg is readonly T[]; (arg: unknown): arg is any[]; }

function equalIC(a, b) {
>equalIC : (a: any, b: any) => boolean
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/instantiationExpressions.types
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ function f2() {
>Array : ArrayConstructor

const A1 = Array<string>; // new (...) => string[]
>A1 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
>A1 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray<T>(arg: ArrayLike<T>): arg is readonly T[]; isArray(arg: unknown): arg is any[]; readonly prototype: any[]; }
>Array : ArrayConstructor

const A2 = Array<string, number>; // Error
>A2 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; }
>A2 : { isArray<T>(arg: ArrayLike<T>): arg is readonly T[]; isArray(arg: unknown): arg is any[]; readonly prototype: any[]; }
>Array : ArrayConstructor
}

Expand All @@ -69,11 +69,11 @@ type T20 = typeof Array<>; // Error
>Array : ArrayConstructor

type T21 = typeof Array<string>; // new (...) => string[]
>T21 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
>T21 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray<T>(arg: ArrayLike<T>): arg is readonly T[]; isArray(arg: unknown): arg is any[]; readonly prototype: any[]; }
>Array : ArrayConstructor

type T22 = typeof Array<string, number>; // Error
>T22 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; }
>T22 : { isArray<T>(arg: ArrayLike<T>): arg is readonly T[]; isArray(arg: unknown): arg is any[]; readonly prototype: any[]; }
>Array : ArrayConstructor

declare class C<T> {
Expand Down
69 changes: 69 additions & 0 deletions tests/baselines/reference/isArray.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
tests/cases/compiler/isArray.ts(15,9): error TS4104: The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.
tests/cases/compiler/isArray.ts(26,9): error TS2322: Type 'readonly string[]' is not assignable to type 'readonly void[]'.
Type 'string' is not assignable to type 'void'.
tests/cases/compiler/isArray.ts(32,9): error TS2322: Type 'readonly string[]' is not assignable to type 'readonly void[]'.
tests/cases/compiler/isArray.ts(41,9): error TS2322: Type 'any[]' is not assignable to type 'void'.
tests/cases/compiler/isArray.ts(47,9): error TS2322: Type 'any[]' is not assignable to type 'void'.


==== tests/cases/compiler/isArray.ts (5 errors) ====
/// @errors: 2322 4104

// https://github.com/microsoft/TypeScript/issues/17002
// Preserves mutability, false branch removes arrays, mutable or not

declare const mutable: string | string[];
if (Array.isArray(mutable)) {
const stillMutable: string[] = mutable;
} else {
const narrowed: string = mutable;
}

declare const immutable: string | readonly string[];
if (Array.isArray(immutable)) {
const notMutable: string[] = immutable; // Should fail: readonly string[] isn't assignable to string[]
~~~~~~~~~~
!!! error TS4104: The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.
} else {
const narrowed: string = immutable;
}

// https://github.com/microsoft/TypeScript/issues/33700
// Preserves element or iterated type of wider types

declare const arrayLike: string | ArrayLike<string>;
if (Array.isArray(arrayLike)) {
const arrayOfElementType: readonly string[] = arrayLike;
const notArrayOfAny: readonly void[] = arrayLike; // Should fail: string isn't assignable to void
~~~~~~~~~~~~~
!!! error TS2322: Type 'readonly string[]' is not assignable to type 'readonly void[]'.
!!! error TS2322: Type 'string' is not assignable to type 'void'.
}

declare const iterable: string | Iterable<string>;
if (Array.isArray(iterable)) {
const arrayOfIteratedType: readonly string[] = iterable;
const notArrayOfAny: readonly void[] = iterable; // Should fail: string isn't assignable to void
~~~~~~~~~~~~~
!!! error TS2322: Type 'readonly string[]' is not assignable to type 'readonly void[]'.
}

// https://github.com/microsoft/TypeScript/pull/42316#discussion_r823218462
// any and unknown backward compatibility

declare const any: any;
if (Array.isArray(any)) {
const mutableArrayOfAny: void[] = any;
const notAny: void = any; // Should fail: any[] isn't assignable to void
~~~~~~
!!! error TS2322: Type 'any[]' is not assignable to type 'void'.
}

declare const unknown: unknown;
if (Array.isArray(unknown)) {
const mutableArrayOfAny: void[] = unknown;
const notAny: void = unknown; // Should fail: any[] isn't assignable to void
~~~~~~
!!! error TS2322: Type 'any[]' is not assignable to type 'void'.
}

82 changes: 72 additions & 10 deletions tests/baselines/reference/isArray.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,81 @@
//// [isArray.ts]
var maybeArray: number | number[];
/// @errors: 2322 4104

// https://github.com/microsoft/TypeScript/issues/17002
// Preserves mutability, false branch removes arrays, mutable or not

if (Array.isArray(maybeArray)) {
maybeArray.length; // OK
declare const mutable: string | string[];
if (Array.isArray(mutable)) {
const stillMutable: string[] = mutable;
} else {
const narrowed: string = mutable;
}
else {
maybeArray.toFixed(); // OK
}

declare const immutable: string | readonly string[];
if (Array.isArray(immutable)) {
const notMutable: string[] = immutable; // Should fail: readonly string[] isn't assignable to string[]
} else {
const narrowed: string = immutable;
}

// https://github.com/microsoft/TypeScript/issues/33700
// Preserves element or iterated type of wider types

declare const arrayLike: string | ArrayLike<string>;
if (Array.isArray(arrayLike)) {
const arrayOfElementType: readonly string[] = arrayLike;
const notArrayOfAny: readonly void[] = arrayLike; // Should fail: string isn't assignable to void
}

declare const iterable: string | Iterable<string>;
if (Array.isArray(iterable)) {
const arrayOfIteratedType: readonly string[] = iterable;
const notArrayOfAny: readonly void[] = iterable; // Should fail: string isn't assignable to void
}

// https://github.com/microsoft/TypeScript/pull/42316#discussion_r823218462
// any and unknown backward compatibility

declare const any: any;
if (Array.isArray(any)) {
const mutableArrayOfAny: void[] = any;
const notAny: void = any; // Should fail: any[] isn't assignable to void
}

declare const unknown: unknown;
if (Array.isArray(unknown)) {
const mutableArrayOfAny: void[] = unknown;
const notAny: void = unknown; // Should fail: any[] isn't assignable to void
}


//// [isArray.js]
var maybeArray;
if (Array.isArray(maybeArray)) {
maybeArray.length; // OK
/// @errors: 2322 4104
if (Array.isArray(mutable)) {
const stillMutable = mutable;
}
else {
const narrowed = mutable;
}
if (Array.isArray(immutable)) {
const notMutable = immutable; // Should fail: readonly string[] isn't assignable to string[]
}
else {
maybeArray.toFixed(); // OK
const narrowed = immutable;
}
if (Array.isArray(arrayLike)) {
const arrayOfElementType = arrayLike;
const notArrayOfAny = arrayLike; // Should fail: string isn't assignable to void
}
if (Array.isArray(iterable)) {
const arrayOfIteratedType = iterable;
const notArrayOfAny = iterable; // Should fail: string isn't assignable to void
}
if (Array.isArray(any)) {
const mutableArrayOfAny = any;
const notAny = any; // Should fail: any[] isn't assignable to void
}
if (Array.isArray(unknown)) {
const mutableArrayOfAny = unknown;
const notAny = unknown; // Should fail: any[] isn't assignable to void
}
Loading