diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 1f352cd6f3913..b777e534f2658 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1253,7 +1253,7 @@ interface ArrayConstructor { (arrayLength?: number): any[]; (arrayLength: number): T[]; (...items: T[]): T[]; - isArray(arg: any): arg is Array; + isArray(arg: any): arg is ReadonlyArray; readonly prototype: Array; } diff --git a/tests/baselines/reference/fixSignatureCaching.types b/tests/baselines/reference/fixSignatureCaching.types index c3f4dbc152248..5ff819439e2e5 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: any) => arg is ReadonlyArray >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: any) => arg is ReadonlyArray >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..4846c42f3484f --- /dev/null +++ b/tests/baselines/reference/isArray.errors.txt @@ -0,0 +1,33 @@ +tests/cases/compiler/isArray.ts(7,11): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/compiler/isArray.ts(17,11): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/compiler/isArray.ts(18,24): error TS2339: Property 'push' does not exist on type 'ReadonlyArray'. + + +==== tests/cases/compiler/isArray.ts (3 errors) ==== + var maybeArray: number | number[]; + + + if (Array.isArray(maybeArray)) { + maybeArray.length; // OK + maybeArray.push(0); // OK + const str: string = maybeArray[0]; // Expect error + ~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + } + else { + maybeArray.toFixed(); // OK + } + + var maybeReadonlyArray: number | ReadonlyArray; + if (Array.isArray(maybeReadonlyArray)) { + maybeReadonlyArray.length; // OK + const num = maybeReadonlyArray[0]; // OK, expect typeof num = number + const str: string = maybeReadonlyArray[0]; // Expect error + ~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + maybeReadonlyArray.push(0); // Expect error + ~~~~ +!!! error TS2339: Property 'push' does not exist on type 'ReadonlyArray'. + } else { + maybeReadonlyArray.toFixed(); + } \ No newline at end of file diff --git a/tests/baselines/reference/isArray.js b/tests/baselines/reference/isArray.js index a90898fd65b26..d16a46f41a7a8 100644 --- a/tests/baselines/reference/isArray.js +++ b/tests/baselines/reference/isArray.js @@ -4,16 +4,40 @@ var maybeArray: number | number[]; if (Array.isArray(maybeArray)) { maybeArray.length; // OK + maybeArray.push(0); // OK + const str: string = maybeArray[0]; // Expect error } else { maybeArray.toFixed(); // OK +} + +var maybeReadonlyArray: number | ReadonlyArray; +if (Array.isArray(maybeReadonlyArray)) { + maybeReadonlyArray.length; // OK + const num = maybeReadonlyArray[0]; // OK, expect typeof num = number + const str: string = maybeReadonlyArray[0]; // Expect error + maybeReadonlyArray.push(0); // Expect error +} else { + maybeReadonlyArray.toFixed(); } //// [isArray.js] var maybeArray; if (Array.isArray(maybeArray)) { maybeArray.length; // OK + maybeArray.push(0); // OK + var str = maybeArray[0]; // Expect error } else { maybeArray.toFixed(); // OK } +var maybeReadonlyArray; +if (Array.isArray(maybeReadonlyArray)) { + maybeReadonlyArray.length; // OK + var num = maybeReadonlyArray[0]; // OK, expect typeof num = number + var str = maybeReadonlyArray[0]; // Expect error + maybeReadonlyArray.push(0); // Expect error +} +else { + maybeReadonlyArray.toFixed(); +} diff --git a/tests/baselines/reference/isArray.symbols b/tests/baselines/reference/isArray.symbols index b60123e6b2eae..37986dd7c2762 100644 --- a/tests/baselines/reference/isArray.symbols +++ b/tests/baselines/reference/isArray.symbols @@ -13,6 +13,15 @@ if (Array.isArray(maybeArray)) { >maybeArray.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) >maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) >length : Symbol(Array.length, Decl(lib.d.ts, --, --)) + + maybeArray.push(0); // OK +>maybeArray.push : Symbol(Array.push, Decl(lib.d.ts, --, --)) +>maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) +>push : Symbol(Array.push, Decl(lib.d.ts, --, --)) + + const str: string = maybeArray[0]; // Expect error +>str : Symbol(str, Decl(isArray.ts, 6, 9)) +>maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) } else { maybeArray.toFixed(); // OK @@ -20,3 +29,36 @@ else { >maybeArray : Symbol(maybeArray, Decl(isArray.ts, 0, 3)) >toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) } + +var maybeReadonlyArray: number | ReadonlyArray; +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.d.ts, --, --)) + +if (Array.isArray(maybeReadonlyArray)) { +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, --, --)) +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) + + maybeReadonlyArray.length; // OK +>maybeReadonlyArray.length : Symbol(ReadonlyArray.length, Decl(lib.d.ts, --, --)) +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) +>length : Symbol(ReadonlyArray.length, Decl(lib.d.ts, --, --)) + + const num = maybeReadonlyArray[0]; // OK, expect typeof num = number +>num : Symbol(num, Decl(isArray.ts, 15, 9)) +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) + + const str: string = maybeReadonlyArray[0]; // Expect error +>str : Symbol(str, Decl(isArray.ts, 16, 9)) +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) + + maybeReadonlyArray.push(0); // Expect error +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) + +} else { + maybeReadonlyArray.toFixed(); +>maybeReadonlyArray.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>maybeReadonlyArray : Symbol(maybeReadonlyArray, Decl(isArray.ts, 12, 3)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +} diff --git a/tests/baselines/reference/isArray.types b/tests/baselines/reference/isArray.types index bc452b12bef01..fe2b7a1ab2ee6 100644 --- a/tests/baselines/reference/isArray.types +++ b/tests/baselines/reference/isArray.types @@ -5,15 +5,28 @@ var maybeArray: number | number[]; if (Array.isArray(maybeArray)) { >Array.isArray(maybeArray) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: any) => arg is ReadonlyArray >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: any) => arg is ReadonlyArray >maybeArray : number | number[] maybeArray.length; // OK >maybeArray.length : number >maybeArray : number[] >length : number + + maybeArray.push(0); // OK +>maybeArray.push(0) : number +>maybeArray.push : (...items: number[]) => number +>maybeArray : number[] +>push : (...items: number[]) => number +>0 : 0 + + const str: string = maybeArray[0]; // Expect error +>str : string +>maybeArray[0] : number +>maybeArray : number[] +>0 : 0 } else { maybeArray.toFixed(); // OK @@ -22,3 +35,46 @@ else { >maybeArray : number >toFixed : (fractionDigits?: number) => string } + +var maybeReadonlyArray: number | ReadonlyArray; +>maybeReadonlyArray : number | ReadonlyArray +>ReadonlyArray : ReadonlyArray + +if (Array.isArray(maybeReadonlyArray)) { +>Array.isArray(maybeReadonlyArray) : boolean +>Array.isArray : (arg: any) => arg is ReadonlyArray +>Array : ArrayConstructor +>isArray : (arg: any) => arg is ReadonlyArray +>maybeReadonlyArray : number | ReadonlyArray + + maybeReadonlyArray.length; // OK +>maybeReadonlyArray.length : number +>maybeReadonlyArray : ReadonlyArray +>length : number + + const num = maybeReadonlyArray[0]; // OK, expect typeof num = number +>num : number +>maybeReadonlyArray[0] : number +>maybeReadonlyArray : ReadonlyArray +>0 : 0 + + const str: string = maybeReadonlyArray[0]; // Expect error +>str : string +>maybeReadonlyArray[0] : number +>maybeReadonlyArray : ReadonlyArray +>0 : 0 + + maybeReadonlyArray.push(0); // Expect error +>maybeReadonlyArray.push(0) : any +>maybeReadonlyArray.push : any +>maybeReadonlyArray : ReadonlyArray +>push : any +>0 : 0 + +} else { + maybeReadonlyArray.toFixed(); +>maybeReadonlyArray.toFixed() : string +>maybeReadonlyArray.toFixed : (fractionDigits?: number) => string +>maybeReadonlyArray : number +>toFixed : (fractionDigits?: number) => string +} diff --git a/tests/baselines/reference/malformedTags.types b/tests/baselines/reference/malformedTags.types index c3af959586790..1ec38de5b9c28 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: any) => arg is ReadonlyArray >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: any) => arg is ReadonlyArray diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 505cfe67c8203..cb0a049f746c9 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -3131,27 +3131,27 @@ module Harness { >identifier : any public normalizeToArray(arg: any) { ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => ReadonlyArray >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: any) => arg is ReadonlyArray >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: any) => arg is ReadonlyArray >Array.isArray(arg) : boolean ->Array.isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: any) => arg is ReadonlyArray >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: any) => arg is ReadonlyArray >arg : any >arg instanceof Array : boolean >arg : any >Array : ArrayConstructor return arg; ->arg : any[] +>arg : ReadonlyArray return [arg]; >[arg] : any[] @@ -3311,12 +3311,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : ReadonlyArray >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : ReadonlyArray +>this.normalizeToArray : (arg: any) => ReadonlyArray >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => ReadonlyArray >others : any for (var i = 0; i < others.length; i++) { @@ -3365,12 +3365,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : ReadonlyArray >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : ReadonlyArray +>this.normalizeToArray : (arg: any) => ReadonlyArray >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => ReadonlyArray >others : any for (var i = 0; i < others.length; i++) { @@ -3521,12 +3521,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : ReadonlyArray >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : ReadonlyArray +>this.normalizeToArray : (arg: any) => ReadonlyArray >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => ReadonlyArray >others : any for (var i = 0; i < others.length; i++) { @@ -3577,12 +3577,12 @@ module Harness { >others : any others = this.normalizeToArray(others); ->others = this.normalizeToArray(others) : any[] +>others = this.normalizeToArray(others) : ReadonlyArray >others : any ->this.normalizeToArray(others) : any[] ->this.normalizeToArray : (arg: any) => any[] +>this.normalizeToArray(others) : ReadonlyArray +>this.normalizeToArray : (arg: any) => ReadonlyArray >this : this ->normalizeToArray : (arg: any) => any[] +>normalizeToArray : (arg: any) => ReadonlyArray >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 911c949373ba6..455b57b2186b9 100644 --- a/tests/baselines/reference/partiallyDiscriminantedUnions.types +++ b/tests/baselines/reference/partiallyDiscriminantedUnions.types @@ -96,9 +96,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: any) => arg is ReadonlyArray >Array : ArrayConstructor ->isArray : (arg: any) => arg is any[] +>isArray : (arg: any) => arg is ReadonlyArray >s : Shapes } diff --git a/tests/cases/compiler/isArray.ts b/tests/cases/compiler/isArray.ts index dbdd875e21ecc..e08fa99663dd4 100644 --- a/tests/cases/compiler/isArray.ts +++ b/tests/cases/compiler/isArray.ts @@ -3,7 +3,19 @@ var maybeArray: number | number[]; if (Array.isArray(maybeArray)) { maybeArray.length; // OK + maybeArray.push(0); // OK + const str: string = maybeArray[0]; // Expect error } else { maybeArray.toFixed(); // OK +} + +var maybeReadonlyArray: number | ReadonlyArray; +if (Array.isArray(maybeReadonlyArray)) { + maybeReadonlyArray.length; // OK + const num = maybeReadonlyArray[0]; // OK, expect typeof num = number + const str: string = maybeReadonlyArray[0]; // Expect error + maybeReadonlyArray.push(0); // Expect error +} else { + maybeReadonlyArray.toFixed(); } \ No newline at end of file