diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 0d1481dd7d26b..d39978f5c1a0b 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1341,7 +1341,7 @@ interface ArrayConstructor { (arrayLength?: number): any[]; (arrayLength: number): T[]; (...items: T[]): T[]; - isArray(arg: any): arg is Array; + isArray(arg: T): arg is T extends ReadonlyArray ? T : Array extends T ? (T & any[]) : never; readonly prototype: Array; } diff --git a/tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.types b/tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.types index 68e2e12c65dbb..8fce630fecb93 100644 --- a/tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.types +++ b/tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.types @@ -67,9 +67,9 @@ export const updateIfChanged = (t: T) => { >assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (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 : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >u : U >[] : undefined[] >{} : {} diff --git a/tests/baselines/reference/fixSignatureCaching.types b/tests/baselines/reference/fixSignatureCaching.types index 4fda03be7a901..914e651864670 100644 --- a/tests/baselines/reference/fixSignatureCaching.types +++ b/tests/baselines/reference/fixSignatureCaching.types @@ -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 : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : (value: any) => boolean >value : any >Object.prototype.toString.call(value) === '[object Array]' : boolean diff --git a/tests/baselines/reference/isArray.errors.txt b/tests/baselines/reference/isArray.errors.txt new file mode 100644 index 0000000000000..558c6b042be0c --- /dev/null +++ b/tests/baselines/reference/isArray.errors.txt @@ -0,0 +1,128 @@ +tests/cases/compiler/isArray.ts(21,33): error TS2339: Property 'push' does not exist on type 'readonly string[]'. +tests/cases/compiler/isArray.ts(22,33): error TS2339: Property 'push' does not exist on type 'readonly string[]'. +tests/cases/compiler/isArray.ts(28,38): error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. +tests/cases/compiler/isArray.ts(36,33): error TS2339: Property 'push' does not exist on type 'readonly string[] | number[]'. + Property 'push' does not exist on type 'readonly string[]'. +tests/cases/compiler/isArray.ts(40,33): error TS2339: Property 'push' does not exist on type 'readonly string[] | number[]'. + Property 'push' does not exist on type 'readonly string[]'. +tests/cases/compiler/isArray.ts(44,38): error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. +tests/cases/compiler/isArray.ts(50,33): error TS2339: Property 'push' does not exist on type 'MyReadOnlyArray'. +tests/cases/compiler/isArray.ts(51,41): error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. +tests/cases/compiler/isArray.ts(61,33): error TS2339: Property 'push' does not exist on type 'readonly T[]'. +tests/cases/compiler/isArray.ts(70,33): error TS2339: Property 'push' does not exist on type 'readonly [T]'. +tests/cases/compiler/isArray.ts(76,38): error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. +tests/cases/compiler/isArray.ts(83,15): error TS2345: Argument of type '"str"' is not assignable to parameter of type 'string[]'. + + +==== tests/cases/compiler/isArray.ts (12 errors) ==== + interface MyArray extends Array { manifest: any; } + interface MyReadOnlyArray extends ReadonlyArray { manifest: any; } + + function fn1(arg: string | string[]) { + if (Array.isArray(arg)) arg.push(""); // Should OK + } + + function fn2(arg: unknown) { + if (Array.isArray(arg)) arg.push(""); // Should OK + } + + function fn3(arg: object) { + if (Array.isArray(arg)) arg.push(""); // Should OK + } + + function fn4(arg: {}) { + if (Array.isArray(arg)) arg.push(""); // Should OK + } + + function fn5(arg: string | ReadonlyArray) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'readonly string[]'. + if (Array.isArray(arg)) arg.push(""); // Should FAIL + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'readonly string[]'. + if (Array.isArray(arg)) arg.indexOf(""); // Should OK + if (!Array.isArray(arg)) arg.toUpperCase(); // Should OK + } + + function fn6(arg: string | string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + ~~ +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. + } + + function fn7(arg: boolean | number[] | string[], stringAndNumber: string & number) { + if (Array.isArray(arg)) arg.push(stringAndNumber); // Should OK + } + + function fn8(arg: string | number[] | readonly string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'readonly string[] | number[]'. +!!! error TS2339: Property 'push' does not exist on type 'readonly string[]'. + } + + function fn9(arg: string | number[] | readonly string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'readonly string[] | number[]'. +!!! error TS2339: Property 'push' does not exist on type 'readonly string[]'. + } + + function fn10(arg: string | MyArray) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + ~~ +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. + if (Array.isArray(arg)) arg.push(""); // Should OK + if (Array.isArray(arg)) arg.manifest; // Should OK + } + + function fn11(arg: string | MyReadOnlyArray) { + if (Array.isArray(arg)) arg.push(""); // Should FAIL + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'MyReadOnlyArray'. + if (Array.isArray(arg)) arg.indexOf(10); // Should FAIL + ~~ +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. + if (Array.isArray(arg)) arg.indexOf(""); // Should OK + if (Array.isArray(arg)) arg.manifest; // Should OK + } + + function fn12(arg: T | T[], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should OK + } + + function fn13(arg: T | ReadonlyArray, t: T) { + if (Array.isArray(arg)) arg.push(t); // Should fail + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'readonly T[]'. + if (Array.isArray(arg)) arg.indexOf(t); // OK + } + + function fn14(arg: T | [T], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should OK + } + + function fn15(arg: T | readonly [T], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should fail + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'readonly [T]'. + if (Array.isArray(arg)) arg.indexOf(t); // Should OK + } + + function fn16(arg: T) { + if (Array.isArray(arg)) arg.push("10"); // Should OK + if (Array.isArray(arg)) arg.push(10); // Should fail + ~~ +!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'string'. + } + + function fn17() { + const s: Array = []; + const arrs = s.filter(Array.isArray); + arrs.push(["one"]); // Should OK + arrs.push("str"); // Should fail + ~~~~~ +!!! error TS2345: Argument of type '"str"' is not assignable to parameter of type 'string[]'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/isArray.js b/tests/baselines/reference/isArray.js index a90898fd65b26..e52ad526d7508 100644 --- a/tests/baselines/reference/isArray.js +++ b/tests/baselines/reference/isArray.js @@ -1,19 +1,180 @@ //// [isArray.ts] -var maybeArray: number | number[]; +interface MyArray extends Array { manifest: any; } +interface MyReadOnlyArray extends ReadonlyArray { manifest: any; } +function fn1(arg: string | string[]) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} -if (Array.isArray(maybeArray)) { - maybeArray.length; // OK +function fn2(arg: unknown) { + if (Array.isArray(arg)) arg.push(""); // Should OK } -else { - maybeArray.toFixed(); // OK -} + +function fn3(arg: object) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} + +function fn4(arg: {}) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} + +function fn5(arg: string | ReadonlyArray) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + if (Array.isArray(arg)) arg.push(""); // Should FAIL + if (Array.isArray(arg)) arg.indexOf(""); // Should OK + if (!Array.isArray(arg)) arg.toUpperCase(); // Should OK +} + +function fn6(arg: string | string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL +} + +function fn7(arg: boolean | number[] | string[], stringAndNumber: string & number) { + if (Array.isArray(arg)) arg.push(stringAndNumber); // Should OK +} + +function fn8(arg: string | number[] | readonly string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL +} + +function fn9(arg: string | number[] | readonly string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL +} + +function fn10(arg: string | MyArray) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + if (Array.isArray(arg)) arg.push(""); // Should OK + if (Array.isArray(arg)) arg.manifest; // Should OK +} + +function fn11(arg: string | MyReadOnlyArray) { + if (Array.isArray(arg)) arg.push(""); // Should FAIL + if (Array.isArray(arg)) arg.indexOf(10); // Should FAIL + if (Array.isArray(arg)) arg.indexOf(""); // Should OK + if (Array.isArray(arg)) arg.manifest; // Should OK +} + +function fn12(arg: T | T[], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should OK +} + +function fn13(arg: T | ReadonlyArray, t: T) { + if (Array.isArray(arg)) arg.push(t); // Should fail + if (Array.isArray(arg)) arg.indexOf(t); // OK +} + +function fn14(arg: T | [T], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should OK +} + +function fn15(arg: T | readonly [T], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should fail + if (Array.isArray(arg)) arg.indexOf(t); // Should OK +} + +function fn16(arg: T) { + if (Array.isArray(arg)) arg.push("10"); // Should OK + if (Array.isArray(arg)) arg.push(10); // Should fail +} + +function fn17() { + const s: Array = []; + const arrs = s.filter(Array.isArray); + arrs.push(["one"]); // Should OK + arrs.push("str"); // Should fail +} + //// [isArray.js] -var maybeArray; -if (Array.isArray(maybeArray)) { - maybeArray.length; // OK +function fn1(arg) { + if (Array.isArray(arg)) + arg.push(""); // Should OK +} +function fn2(arg) { + if (Array.isArray(arg)) + arg.push(""); // Should OK +} +function fn3(arg) { + if (Array.isArray(arg)) + arg.push(""); // Should OK +} +function fn4(arg) { + if (Array.isArray(arg)) + arg.push(""); // Should OK +} +function fn5(arg) { + if (Array.isArray(arg)) + arg.push(10); // Should FAIL + if (Array.isArray(arg)) + arg.push(""); // Should FAIL + if (Array.isArray(arg)) + arg.indexOf(""); // Should OK + if (!Array.isArray(arg)) + arg.toUpperCase(); // Should OK +} +function fn6(arg) { + if (Array.isArray(arg)) + arg.push(10); // Should FAIL +} +function fn7(arg, stringAndNumber) { + if (Array.isArray(arg)) + arg.push(stringAndNumber); // Should OK +} +function fn8(arg) { + if (Array.isArray(arg)) + arg.push(10); // Should FAIL +} +function fn9(arg) { + if (Array.isArray(arg)) + arg.push(10); // Should FAIL +} +function fn10(arg) { + if (Array.isArray(arg)) + arg.push(10); // Should FAIL + if (Array.isArray(arg)) + arg.push(""); // Should OK + if (Array.isArray(arg)) + arg.manifest; // Should OK +} +function fn11(arg) { + if (Array.isArray(arg)) + arg.push(""); // Should FAIL + if (Array.isArray(arg)) + arg.indexOf(10); // Should FAIL + if (Array.isArray(arg)) + arg.indexOf(""); // Should OK + if (Array.isArray(arg)) + arg.manifest; // Should OK +} +function fn12(arg, t) { + if (Array.isArray(arg)) + arg.push(t); // Should OK +} +function fn13(arg, t) { + if (Array.isArray(arg)) + arg.push(t); // Should fail + if (Array.isArray(arg)) + arg.indexOf(t); // OK +} +function fn14(arg, t) { + if (Array.isArray(arg)) + arg.push(t); // Should OK +} +function fn15(arg, t) { + if (Array.isArray(arg)) + arg.push(t); // Should fail + if (Array.isArray(arg)) + arg.indexOf(t); // Should OK +} +function fn16(arg) { + if (Array.isArray(arg)) + arg.push("10"); // Should OK + if (Array.isArray(arg)) + arg.push(10); // Should fail } -else { - maybeArray.toFixed(); // OK +function fn17() { + var s = []; + var arrs = s.filter(Array.isArray); + arrs.push(["one"]); // Should OK + arrs.push("str"); // Should fail } diff --git a/tests/baselines/reference/isArray.symbols b/tests/baselines/reference/isArray.symbols index 411cb42918daa..04a2fc1258f9b 100644 --- a/tests/baselines/reference/isArray.symbols +++ b/tests/baselines/reference/isArray.symbols @@ -1,22 +1,385 @@ === tests/cases/compiler/isArray.ts === -var maybeArray: number | number[]; ->maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) +interface MyArray extends Array { manifest: any; } +>MyArray : Symbol(MyArray, Decl(isArray.ts, 0, 0)) +>T : Symbol(T, Decl(isArray.ts, 0, 18)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(isArray.ts, 0, 18)) +>manifest : Symbol(MyArray.manifest, Decl(isArray.ts, 0, 39)) + +interface MyReadOnlyArray extends ReadonlyArray { manifest: any; } +>MyReadOnlyArray : Symbol(MyReadOnlyArray, Decl(isArray.ts, 0, 56)) +>T : Symbol(T, Decl(isArray.ts, 1, 26)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(isArray.ts, 1, 26)) +>manifest : Symbol(MyReadOnlyArray.manifest, Decl(isArray.ts, 1, 55)) +function fn1(arg: string | string[]) { +>fn1 : Symbol(fn1, Decl(isArray.ts, 1, 72)) +>arg : Symbol(arg, Decl(isArray.ts, 3, 13)) -if (Array.isArray(maybeArray)) { + if (Array.isArray(arg)) arg.push(""); // Should OK >Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) ->maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) +>arg : Symbol(arg, Decl(isArray.ts, 3, 13)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 3, 13)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} - maybeArray.length; // OK ->maybeArray.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) ->maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) ->length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +function fn2(arg: unknown) { +>fn2 : Symbol(fn2, Decl(isArray.ts, 5, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 7, 13)) + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 7, 13)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 7, 13)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) } -else { - maybeArray.toFixed(); // OK ->maybeArray.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) ->maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) ->toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) + +function fn3(arg: object) { +>fn3 : Symbol(fn3, Decl(isArray.ts, 9, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 11, 13)) + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 11, 13)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 11, 13)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) } + +function fn4(arg: {}) { +>fn4 : Symbol(fn4, Decl(isArray.ts, 13, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 15, 13)) + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 15, 13)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 15, 13)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function fn5(arg: string | ReadonlyArray) { +>fn5 : Symbol(fn5, Decl(isArray.ts, 17, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) + + if (Array.isArray(arg)) arg.push(""); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) + + if (Array.isArray(arg)) arg.indexOf(""); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>arg.indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) + + if (!Array.isArray(arg)) arg.toUpperCase(); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>arg.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 19, 13)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +} + +function fn6(arg: string | string[]) { +>fn6 : Symbol(fn6, Decl(isArray.ts, 24, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 26, 13)) + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 26, 13)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 26, 13)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function fn7(arg: boolean | number[] | string[], stringAndNumber: string & number) { +>fn7 : Symbol(fn7, Decl(isArray.ts, 28, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 30, 13)) +>stringAndNumber : Symbol(stringAndNumber, Decl(isArray.ts, 30, 48)) + + if (Array.isArray(arg)) arg.push(stringAndNumber); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 30, 13)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 30, 13)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>stringAndNumber : Symbol(stringAndNumber, Decl(isArray.ts, 30, 48)) +} + +function fn8(arg: string | number[] | readonly string[]) { +>fn8 : Symbol(fn8, Decl(isArray.ts, 32, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 34, 13)) + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 34, 13)) +>arg : Symbol(arg, Decl(isArray.ts, 34, 13)) +} + +function fn9(arg: string | number[] | readonly string[]) { +>fn9 : Symbol(fn9, Decl(isArray.ts, 36, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 38, 13)) + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 38, 13)) +>arg : Symbol(arg, Decl(isArray.ts, 38, 13)) +} + +function fn10(arg: string | MyArray) { +>fn10 : Symbol(fn10, Decl(isArray.ts, 40, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>MyArray : Symbol(MyArray, Decl(isArray.ts, 0, 0)) + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + + if (Array.isArray(arg)) arg.manifest; // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>arg.manifest : Symbol(MyArray.manifest, Decl(isArray.ts, 0, 39)) +>arg : Symbol(arg, Decl(isArray.ts, 42, 14)) +>manifest : Symbol(MyArray.manifest, Decl(isArray.ts, 0, 39)) +} + +function fn11(arg: string | MyReadOnlyArray) { +>fn11 : Symbol(fn11, Decl(isArray.ts, 46, 1)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>MyReadOnlyArray : Symbol(MyReadOnlyArray, Decl(isArray.ts, 0, 56)) + + if (Array.isArray(arg)) arg.push(""); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) + + if (Array.isArray(arg)) arg.indexOf(10); // Should FAIL +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>arg.indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) + + if (Array.isArray(arg)) arg.indexOf(""); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>arg.indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) + + if (Array.isArray(arg)) arg.manifest; // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>arg.manifest : Symbol(MyReadOnlyArray.manifest, Decl(isArray.ts, 1, 55)) +>arg : Symbol(arg, Decl(isArray.ts, 48, 14)) +>manifest : Symbol(MyReadOnlyArray.manifest, Decl(isArray.ts, 1, 55)) +} + +function fn12(arg: T | T[], t: T) { +>fn12 : Symbol(fn12, Decl(isArray.ts, 53, 1)) +>T : Symbol(T, Decl(isArray.ts, 55, 14)) +>arg : Symbol(arg, Decl(isArray.ts, 55, 17)) +>T : Symbol(T, Decl(isArray.ts, 55, 14)) +>T : Symbol(T, Decl(isArray.ts, 55, 14)) +>t : Symbol(t, Decl(isArray.ts, 55, 30)) +>T : Symbol(T, Decl(isArray.ts, 55, 14)) + + if (Array.isArray(arg)) arg.push(t); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 55, 17)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 55, 17)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>t : Symbol(t, Decl(isArray.ts, 55, 30)) +} + +function fn13(arg: T | ReadonlyArray, t: T) { +>fn13 : Symbol(fn13, Decl(isArray.ts, 57, 1)) +>T : Symbol(T, Decl(isArray.ts, 59, 14)) +>arg : Symbol(arg, Decl(isArray.ts, 59, 17)) +>T : Symbol(T, Decl(isArray.ts, 59, 14)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(isArray.ts, 59, 14)) +>t : Symbol(t, Decl(isArray.ts, 59, 43)) +>T : Symbol(T, Decl(isArray.ts, 59, 14)) + + if (Array.isArray(arg)) arg.push(t); // Should fail +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 59, 17)) +>arg : Symbol(arg, Decl(isArray.ts, 59, 17)) +>t : Symbol(t, Decl(isArray.ts, 59, 43)) + + if (Array.isArray(arg)) arg.indexOf(t); // OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 59, 17)) +>arg.indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 59, 17)) +>indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>t : Symbol(t, Decl(isArray.ts, 59, 43)) +} + +function fn14(arg: T | [T], t: T) { +>fn14 : Symbol(fn14, Decl(isArray.ts, 62, 1)) +>T : Symbol(T, Decl(isArray.ts, 64, 14)) +>arg : Symbol(arg, Decl(isArray.ts, 64, 17)) +>T : Symbol(T, Decl(isArray.ts, 64, 14)) +>T : Symbol(T, Decl(isArray.ts, 64, 14)) +>t : Symbol(t, Decl(isArray.ts, 64, 30)) +>T : Symbol(T, Decl(isArray.ts, 64, 14)) + + if (Array.isArray(arg)) arg.push(t); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 64, 17)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 64, 17)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>t : Symbol(t, Decl(isArray.ts, 64, 30)) +} + +function fn15(arg: T | readonly [T], t: T) { +>fn15 : Symbol(fn15, Decl(isArray.ts, 66, 1)) +>T : Symbol(T, Decl(isArray.ts, 68, 14)) +>arg : Symbol(arg, Decl(isArray.ts, 68, 17)) +>T : Symbol(T, Decl(isArray.ts, 68, 14)) +>T : Symbol(T, Decl(isArray.ts, 68, 14)) +>t : Symbol(t, Decl(isArray.ts, 68, 39)) +>T : Symbol(T, Decl(isArray.ts, 68, 14)) + + if (Array.isArray(arg)) arg.push(t); // Should fail +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 68, 17)) +>arg : Symbol(arg, Decl(isArray.ts, 68, 17)) +>t : Symbol(t, Decl(isArray.ts, 68, 39)) + + if (Array.isArray(arg)) arg.indexOf(t); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 68, 17)) +>arg.indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 68, 17)) +>indexOf : Symbol(ReadonlyArray.indexOf, Decl(lib.es5.d.ts, --, --)) +>t : Symbol(t, Decl(isArray.ts, 68, 39)) +} + +function fn16(arg: T) { +>fn16 : Symbol(fn16, Decl(isArray.ts, 71, 1)) +>T : Symbol(T, Decl(isArray.ts, 73, 14)) +>arg : Symbol(arg, Decl(isArray.ts, 73, 43)) +>T : Symbol(T, Decl(isArray.ts, 73, 14)) + + if (Array.isArray(arg)) arg.push("10"); // Should OK +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 73, 43)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 73, 43)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + + if (Array.isArray(arg)) arg.push(10); // Should fail +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 73, 43)) +>arg.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(isArray.ts, 73, 43)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function fn17() { +>fn17 : Symbol(fn17, Decl(isArray.ts, 76, 1)) + + const s: Array = []; +>s : Symbol(s, Decl(isArray.ts, 79, 9)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + const arrs = s.filter(Array.isArray); +>arrs : Symbol(arrs, Decl(isArray.ts, 80, 9)) +>s.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>s : Symbol(s, Decl(isArray.ts, 79, 9)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Array.isArray : Symbol(ArrayConstructor.isArray, 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, --, --)) + + arrs.push(["one"]); // Should OK +>arrs.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arrs : Symbol(arrs, Decl(isArray.ts, 80, 9)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + + arrs.push("str"); // Should fail +>arrs.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arrs : Symbol(arrs, Decl(isArray.ts, 80, 9)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/isArray.types b/tests/baselines/reference/isArray.types index bc452b12bef01..71a9af0a866ff 100644 --- a/tests/baselines/reference/isArray.types +++ b/tests/baselines/reference/isArray.types @@ -1,24 +1,445 @@ === tests/cases/compiler/isArray.ts === -var maybeArray: number | number[]; ->maybeArray : number | number[] +interface MyArray extends Array { manifest: any; } +>manifest : any +interface MyReadOnlyArray extends ReadonlyArray { manifest: any; } +>manifest : any -if (Array.isArray(maybeArray)) { ->Array.isArray(maybeArray) : boolean ->Array.isArray : (arg: any) => arg is any[] +function fn1(arg: string | string[]) { +>fn1 : (arg: string | string[]) => void +>arg : string | string[] + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | string[] +>arg.push("") : number +>arg.push : (...items: string[]) => number +>arg : string[] +>push : (...items: string[]) => number +>"" : "" +} + +function fn2(arg: unknown) { +>fn2 : (arg: unknown) => void +>arg : unknown + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : unknown +>arg.push("") : number +>arg.push : (...items: any[]) => number +>arg : any[] +>push : (...items: any[]) => number +>"" : "" +} + +function fn3(arg: object) { +>fn3 : (arg: object) => void +>arg : object + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] ->maybeArray : number | number[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : object +>arg.push("") : number +>arg.push : (...items: any[]) => number +>arg : object & any[] +>push : (...items: any[]) => number +>"" : "" +} + +function fn4(arg: {}) { +>fn4 : (arg: {}) => void +>arg : {} - maybeArray.length; // OK ->maybeArray.length : number ->maybeArray : number[] ->length : number + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : {} +>arg.push("") : number +>arg.push : (...items: any[]) => number +>arg : any[] +>push : (...items: any[]) => number +>"" : "" } -else { - maybeArray.toFixed(); // OK ->maybeArray.toFixed() : string ->maybeArray.toFixed : (fractionDigits?: number) => string ->maybeArray : number ->toFixed : (fractionDigits?: number) => string + +function fn5(arg: string | ReadonlyArray) { +>fn5 : (arg: string | readonly string[]) => void +>arg : string | readonly string[] + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | readonly string[] +>arg.push(10) : any +>arg.push : any +>arg : readonly string[] +>push : any +>10 : 10 + + if (Array.isArray(arg)) arg.push(""); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | readonly string[] +>arg.push("") : any +>arg.push : any +>arg : readonly string[] +>push : any +>"" : "" + + if (Array.isArray(arg)) arg.indexOf(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | readonly string[] +>arg.indexOf("") : number +>arg.indexOf : (searchElement: string, fromIndex?: number | undefined) => number +>arg : readonly string[] +>indexOf : (searchElement: string, fromIndex?: number | undefined) => number +>"" : "" + + if (!Array.isArray(arg)) arg.toUpperCase(); // Should OK +>!Array.isArray(arg) : boolean +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | readonly string[] +>arg.toUpperCase() : string +>arg.toUpperCase : () => string +>arg : string +>toUpperCase : () => string +} + +function fn6(arg: string | string[]) { +>fn6 : (arg: string | string[]) => void +>arg : string | string[] + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | string[] +>arg.push(10) : number +>arg.push : (...items: string[]) => number +>arg : string[] +>push : (...items: string[]) => number +>10 : 10 +} + +function fn7(arg: boolean | number[] | string[], stringAndNumber: string & number) { +>fn7 : (arg: boolean | string[] | number[], stringAndNumber: never) => void +>arg : boolean | string[] | number[] +>stringAndNumber : never + + if (Array.isArray(arg)) arg.push(stringAndNumber); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : boolean | string[] | number[] +>arg.push(stringAndNumber) : number +>arg.push : ((...items: string[]) => number) | ((...items: number[]) => number) +>arg : string[] | number[] +>push : ((...items: string[]) => number) | ((...items: number[]) => number) +>stringAndNumber : never +} + +function fn8(arg: string | number[] | readonly string[]) { +>fn8 : (arg: string | readonly string[] | number[]) => void +>arg : string | readonly string[] | number[] + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | readonly string[] | number[] +>arg.push(10) : any +>arg.push : any +>arg : readonly string[] | number[] +>push : any +>10 : 10 +} + +function fn9(arg: string | number[] | readonly string[]) { +>fn9 : (arg: string | readonly string[] | number[]) => void +>arg : string | readonly string[] | number[] + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | readonly string[] | number[] +>arg.push(10) : any +>arg.push : any +>arg : readonly string[] | number[] +>push : any +>10 : 10 +} + +function fn10(arg: string | MyArray) { +>fn10 : (arg: string | MyArray) => void +>arg : string | MyArray + + if (Array.isArray(arg)) arg.push(10); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyArray +>arg.push(10) : number +>arg.push : (...items: string[]) => number +>arg : MyArray +>push : (...items: string[]) => number +>10 : 10 + + if (Array.isArray(arg)) arg.push(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyArray +>arg.push("") : number +>arg.push : (...items: string[]) => number +>arg : MyArray +>push : (...items: string[]) => number +>"" : "" + + if (Array.isArray(arg)) arg.manifest; // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyArray +>arg.manifest : any +>arg : MyArray +>manifest : any } + +function fn11(arg: string | MyReadOnlyArray) { +>fn11 : (arg: string | MyReadOnlyArray) => void +>arg : string | MyReadOnlyArray + + if (Array.isArray(arg)) arg.push(""); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyReadOnlyArray +>arg.push("") : any +>arg.push : any +>arg : MyReadOnlyArray +>push : any +>"" : "" + + if (Array.isArray(arg)) arg.indexOf(10); // Should FAIL +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyReadOnlyArray +>arg.indexOf(10) : number +>arg.indexOf : (searchElement: string, fromIndex?: number | undefined) => number +>arg : MyReadOnlyArray +>indexOf : (searchElement: string, fromIndex?: number | undefined) => number +>10 : 10 + + if (Array.isArray(arg)) arg.indexOf(""); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyReadOnlyArray +>arg.indexOf("") : number +>arg.indexOf : (searchElement: string, fromIndex?: number | undefined) => number +>arg : MyReadOnlyArray +>indexOf : (searchElement: string, fromIndex?: number | undefined) => number +>"" : "" + + if (Array.isArray(arg)) arg.manifest; // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : string | MyReadOnlyArray +>arg.manifest : any +>arg : MyReadOnlyArray +>manifest : any +} + +function fn12(arg: T | T[], t: T) { +>fn12 : (arg: T | T[], t: T) => void +>arg : T | T[] +>t : T + + if (Array.isArray(arg)) arg.push(t); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T | T[] +>arg.push(t) : number +>arg.push : (...items: T[]) => number +>arg : T[] +>push : (...items: T[]) => number +>t : T +} + +function fn13(arg: T | ReadonlyArray, t: T) { +>fn13 : (arg: T | readonly T[], t: T) => void +>arg : T | readonly T[] +>t : T + + if (Array.isArray(arg)) arg.push(t); // Should fail +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T | readonly T[] +>arg.push(t) : any +>arg.push : any +>arg : readonly T[] +>push : any +>t : T + + if (Array.isArray(arg)) arg.indexOf(t); // OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T | readonly T[] +>arg.indexOf(t) : number +>arg.indexOf : (searchElement: T, fromIndex?: number | undefined) => number +>arg : readonly T[] +>indexOf : (searchElement: T, fromIndex?: number | undefined) => number +>t : T +} + +function fn14(arg: T | [T], t: T) { +>fn14 : (arg: T | [T], t: T) => void +>arg : T | [T] +>t : T + + if (Array.isArray(arg)) arg.push(t); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T | [T] +>arg.push(t) : number +>arg.push : (...items: T[]) => number +>arg : [T] +>push : (...items: T[]) => number +>t : T +} + +function fn15(arg: T | readonly [T], t: T) { +>fn15 : (arg: T | readonly [T], t: T) => void +>arg : T | readonly [T] +>t : T + + if (Array.isArray(arg)) arg.push(t); // Should fail +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T | readonly [T] +>arg.push(t) : any +>arg.push : any +>arg : readonly [T] +>push : any +>t : T + + if (Array.isArray(arg)) arg.indexOf(t); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T | readonly [T] +>arg.indexOf(t) : number +>arg.indexOf : (searchElement: T, fromIndex?: number | undefined) => number +>arg : readonly [T] +>indexOf : (searchElement: T, fromIndex?: number | undefined) => number +>t : T +} + +function fn16(arg: T) { +>fn16 : (arg: T) => void +>arg : T + + if (Array.isArray(arg)) arg.push("10"); // Should OK +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T +>arg.push("10") : number +>arg.push : (...items: string[]) => number +>arg : T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>push : (...items: string[]) => number +>"10" : "10" + + if (Array.isArray(arg)) arg.push(10); // Should fail +>Array.isArray(arg) : boolean +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>arg : T +>arg.push(10) : number +>arg.push : (...items: string[]) => number +>arg : T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>push : (...items: string[]) => number +>10 : 10 +} + +function fn17() { +>fn17 : () => void + + const s: Array = []; +>s : (string | string[])[] +>[] : never[] + + const arrs = s.filter(Array.isArray); +>arrs : string[][] +>s.filter(Array.isArray) : string[][] +>s.filter : { (callbackfn: (value: string | string[], index: number, array: (string | string[])[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: string | string[], index: number, array: (string | string[])[]) => unknown, thisArg?: any): (string | string[])[]; } +>s : (string | string[])[] +>filter : { (callbackfn: (value: string | string[], index: number, array: (string | string[])[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: string | string[], index: number, array: (string | string[])[]) => unknown, thisArg?: any): (string | string[])[]; } +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never +>Array : ArrayConstructor +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never + + arrs.push(["one"]); // Should OK +>arrs.push(["one"]) : number +>arrs.push : (...items: string[][]) => number +>arrs : string[][] +>push : (...items: string[][]) => number +>["one"] : string[] +>"one" : "one" + + arrs.push("str"); // Should fail +>arrs.push("str") : number +>arrs.push : (...items: string[][]) => number +>arrs : string[][] +>push : (...items: string[][]) => number +>"str" : "str" +} + diff --git a/tests/baselines/reference/literalFreshnessPropagationOnNarrowing.types b/tests/baselines/reference/literalFreshnessPropagationOnNarrowing.types index 8fb03bc413f30..5d6f68578070d 100644 --- a/tests/baselines/reference/literalFreshnessPropagationOnNarrowing.types +++ b/tests/baselines/reference/literalFreshnessPropagationOnNarrowing.types @@ -66,9 +66,9 @@ function f2() { >a4 : string | false | (string | false)[] >Array.isArray(elOrA) ? elOrA : [elOrA] : (string | false)[] >Array.isArray(elOrA) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >elOrA : string | false | (string | false)[] >elOrA : (string | false)[] >[elOrA] : (string | false)[] @@ -83,9 +83,9 @@ function f2() { >...Array.isArray(elOrA) ? elOrA : [elOrA] : string | false >Array.isArray(elOrA) ? elOrA : [elOrA] : (string | false)[] >Array.isArray(elOrA) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >elOrA : string | false | (string | false)[] >elOrA : (string | false)[] >[elOrA] : (string | false)[] diff --git a/tests/baselines/reference/malformedTags.types b/tests/baselines/reference/malformedTags.types index c3af959586790..1d3e2582bafa1 100644 --- a/tests/baselines/reference/malformedTags.types +++ b/tests/baselines/reference/malformedTags.types @@ -6,7 +6,7 @@ */ var isArray = Array.isArray; >isArray : Function ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 5fde386f90acf..55e4c1cbf1e8e 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -3061,27 +3061,27 @@ module Harness { >identifier : any public normalizeToArray(arg: any) { ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => any >arg : any if ((Array.isArray && Array.isArray(arg)) || arg instanceof Array) >(Array.isArray && Array.isArray(arg)) || arg instanceof Array : boolean >(Array.isArray && Array.isArray(arg)) : boolean >Array.isArray && Array.isArray(arg) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array.isArray(arg) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >arg : any >arg instanceof Array : boolean >arg : any >Array : ArrayConstructor return arg; ->arg : any[] +>arg : any return [arg]; >[arg] : any[] @@ -3240,12 +3240,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : any >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : any +>this.normalizeToArray : (arg: any) => any >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => any >others : any for (var i = 0; i < others.length; i++) { @@ -3294,12 +3294,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : any >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : any +>this.normalizeToArray : (arg: any) => any >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => any >others : any for (var i = 0; i < others.length; i++) { @@ -3449,12 +3449,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : any >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : any +>this.normalizeToArray : (arg: any) => any >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => any >others : any for (var i = 0; i < others.length; i++) { @@ -3505,12 +3505,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : any >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : any +>this.normalizeToArray : (arg: any) => any >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => any >others : any for (var i = 0; i < others.length; i++) { diff --git a/tests/baselines/reference/partiallyDiscriminantedUnions.types b/tests/baselines/reference/partiallyDiscriminantedUnions.types index f1d44249c0eb2..0530f42889ade 100644 --- a/tests/baselines/reference/partiallyDiscriminantedUnions.types +++ b/tests/baselines/reference/partiallyDiscriminantedUnions.types @@ -77,9 +77,9 @@ function isShape(s : Shapes): s is Shape { return !Array.isArray(s); >!Array.isArray(s) : boolean >Array.isArray(s) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >s : Shapes } diff --git a/tests/baselines/reference/spreadBooleanRespectsFreshness.types b/tests/baselines/reference/spreadBooleanRespectsFreshness.types index c607422b0629a..f3392084a6cab 100644 --- a/tests/baselines/reference/spreadBooleanRespectsFreshness.types +++ b/tests/baselines/reference/spreadBooleanRespectsFreshness.types @@ -22,9 +22,9 @@ foo1 = [...Array.isArray(foo2) ? foo2 : [foo2]]; >...Array.isArray(foo2) ? foo2 : [foo2] : FooBase >Array.isArray(foo2) ? foo2 : [foo2] : FooBase[] >Array.isArray(foo2) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: T) => arg is T extends readonly any[] ? T : any[] extends T ? T & any[] : never >foo2 : Foo >foo2 : FooBase[] >[foo2] : FooBase[] diff --git a/tests/cases/compiler/isArray.ts b/tests/cases/compiler/isArray.ts index dbdd875e21ecc..756634e12f80f 100644 --- a/tests/cases/compiler/isArray.ts +++ b/tests/cases/compiler/isArray.ts @@ -1,9 +1,86 @@ -var maybeArray: number | number[]; +// @strictNullChecks: true +interface MyArray extends Array { manifest: any; } +interface MyReadOnlyArray extends ReadonlyArray { manifest: any; } -if (Array.isArray(maybeArray)) { - maybeArray.length; // OK +function fn1(arg: string | string[]) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} + +function fn2(arg: unknown) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} + +function fn3(arg: object) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} + +function fn4(arg: {}) { + if (Array.isArray(arg)) arg.push(""); // Should OK +} + +function fn5(arg: string | ReadonlyArray) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + if (Array.isArray(arg)) arg.push(""); // Should FAIL + if (Array.isArray(arg)) arg.indexOf(""); // Should OK + if (!Array.isArray(arg)) arg.toUpperCase(); // Should OK +} + +function fn6(arg: string | string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL +} + +function fn7(arg: boolean | number[] | string[], stringAndNumber: string & number) { + if (Array.isArray(arg)) arg.push(stringAndNumber); // Should OK +} + +function fn8(arg: string | number[] | readonly string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL +} + +function fn9(arg: string | number[] | readonly string[]) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL +} + +function fn10(arg: string | MyArray) { + if (Array.isArray(arg)) arg.push(10); // Should FAIL + if (Array.isArray(arg)) arg.push(""); // Should OK + if (Array.isArray(arg)) arg.manifest; // Should OK +} + +function fn11(arg: string | MyReadOnlyArray) { + if (Array.isArray(arg)) arg.push(""); // Should FAIL + if (Array.isArray(arg)) arg.indexOf(10); // Should FAIL + if (Array.isArray(arg)) arg.indexOf(""); // Should OK + if (Array.isArray(arg)) arg.manifest; // Should OK +} + +function fn12(arg: T | T[], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should OK +} + +function fn13(arg: T | ReadonlyArray, t: T) { + if (Array.isArray(arg)) arg.push(t); // Should fail + if (Array.isArray(arg)) arg.indexOf(t); // OK +} + +function fn14(arg: T | [T], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should OK +} + +function fn15(arg: T | readonly [T], t: T) { + if (Array.isArray(arg)) arg.push(t); // Should fail + if (Array.isArray(arg)) arg.indexOf(t); // Should OK +} + +function fn16(arg: T) { + if (Array.isArray(arg)) arg.push("10"); // Should OK + if (Array.isArray(arg)) arg.push(10); // Should fail +} + +function fn17() { + const s: Array = []; + const arrs = s.filter(Array.isArray); + arrs.push(["one"]); // Should OK + arrs.push("str"); // Should fail } -else { - maybeArray.toFixed(); // OK -} \ No newline at end of file