Skip to content

Commit 50b61b8

Browse files
Array.isArray for readonly array
1 parent 9439e2f commit 50b61b8

40 files changed

+208
-178
lines changed

src/harness/fourslashInterfaceImpl.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,7 @@ namespace FourSlashInterface {
11731173
typeEntry("Record"),
11741174
typeEntry("Exclude"),
11751175
typeEntry("Extract"),
1176+
typeEntry("Cast"),
11761177
typeEntry("Omit"),
11771178
typeEntry("NonNullable"),
11781179
typeEntry("Parameters"),

src/lib/es2015.iterable.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,19 @@ interface Array<T> {
5656
}
5757

5858
interface ArrayConstructor {
59+
/**
60+
* Determines whether an object is an array.
61+
* @param arg The object to test.
62+
*/
63+
isArray<T>(arg: T): arg is Cast<
64+
T extends readonly any[] ? T :
65+
T extends string ? never :
66+
T extends Iterable<infer U> | ArrayLike<infer U> ? U[] :
67+
unknown extends T ? any[] :
68+
never,
69+
T & {}
70+
>;
71+
5972
/**
6073
* Creates an array from an array-like or iterable object.
6174
* @param source An array-like or iterable object to convert to an array.

src/lib/es2017.object.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ interface ObjectConstructor {
2727
* Returns an object containing all own property descriptors of an object
2828
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
2929
*/
30-
getOwnPropertyDescriptors<T extends {}>(o: T): { [P in keyof T]: TypedPropertyDescriptor<T[P]> } & { [x: string]: PropertyDescriptor };
30+
getOwnPropertyDescriptors<T extends {}>(o: T): { [P in keyof T]: TypedPropertyDescriptor<T[P]> } & PropertyDescriptorMap;
3131
}

src/lib/es2019.object.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ interface ObjectConstructor {
55
* Returns an object created by key-value entries for properties and methods
66
* @param entries An iterable object that contains key-value entries for properties and methods.
77
*/
8-
fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T };
8+
fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: PropertyKey]: T };
99

1010
/**
1111
* Returns an object created by key-value entries for properties and methods

src/lib/es5.d.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,18 @@ interface ArrayConstructor {
14951495
(arrayLength?: number): any[];
14961496
<T>(arrayLength: number): T[];
14971497
<T>(...items: T[]): T[];
1498-
isArray(arg: any): arg is any[];
1498+
/**
1499+
* Determines whether an object is an array.
1500+
* @param arg The object to test.
1501+
*/
1502+
isArray<T>(arg: T): arg is Cast<
1503+
T extends readonly any[] ? T :
1504+
T extends string ? never :
1505+
T extends ArrayLike<infer U> ? U[] :
1506+
unknown extends T ? any[] :
1507+
never,
1508+
T & {}
1509+
>;
14991510
readonly prototype: any[];
15001511
}
15011512

@@ -1615,6 +1626,11 @@ type Exclude<T, U> = T extends U ? never : T;
16151626
*/
16161627
type Extract<T, U> = T extends U ? T : never;
16171628

1629+
/**
1630+
* Make sure T is at least assignable to U
1631+
*/
1632+
type Cast<T, U> = T extends U ? T : U;
1633+
16181634
/**
16191635
* Construct a type with the properties of T except for those in type K.
16201636
*/

tests/baselines/reference/arrayDestructuringInSwitch1.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ export function evaluate(expression: Expression): boolean {
1111

1212
if (Array.isArray(expression)) {
1313
>Array.isArray(expression) : boolean
14-
>Array.isArray : (arg: any) => arg is any[]
14+
>Array.isArray : <T>(arg: T) => arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>
1515
>Array : ArrayConstructor
16-
>isArray : (arg: any) => arg is any[]
16+
>isArray : <T>(arg: T) => arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>
1717
>expression : Expression
1818

1919
const [operator, ...operands] = expression;

tests/baselines/reference/arrayTypeOfTypeOf.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ var xs2: typeof Array;
1414
>Array : ArrayConstructor
1515

1616
var xs3: typeof Array<number>;
17-
>xs3 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
17+
>xs3 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray<T>(arg: T): arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>; readonly prototype: any[]; }
1818
>Array : ArrayConstructor
1919

2020
var xs4: typeof Array<typeof x>;
21-
>xs4 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; }
21+
>xs4 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray<T>(arg: T): arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>; readonly prototype: any[]; }
2222
>Array : ArrayConstructor
2323
>x : number
2424

tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ export const updateIfChanged = <T>(t: T) => {
7979
>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, --, --), Decl(lib.es2015.core.d.ts, --, --))
8080
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
8181
>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, --, --), Decl(lib.es2015.core.d.ts, --, --))
82-
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
82+
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
8383
>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, --, --))
84-
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
84+
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --))
8585
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
8686
>u : Symbol(u, Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 7, 23))
8787
>[key] : Symbol([key], Decl(declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.ts, 12, 80))

tests/baselines/reference/declarationsWithRecursiveInternalTypesProduceUniqueTypeParams.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ export const updateIfChanged = <T>(t: T) => {
6767
>assign : { <T extends {}>(target: T): T; <T extends {}, U>(target: T, source: U): T & Writable<U>; <T extends {}, U, V>(target: T, source1: U, source2: V): T & Writable<U> & Writable<V>; <T extends {}, U, V, W>(target: T, source1: U, source2: V, source3: W): T & Writable<U> & Writable<V> & Writable<W>; (target: {}, ...sources: any[]): any; }
6868
>Array.isArray(u) ? [] : {} : undefined[] | {}
6969
>Array.isArray(u) : boolean
70-
>Array.isArray : (arg: any) => arg is any[]
70+
>Array.isArray : { <T>(arg: T): arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>; <T>(arg: T): arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends Iterable<infer U> | ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>; }
7171
>Array : ArrayConstructor
72-
>isArray : (arg: any) => arg is any[]
72+
>isArray : { <T>(arg: T): arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>; <T>(arg: T): arg is Cast<T extends readonly any[] ? T : T extends string ? never : T extends Iterable<infer U> | ArrayLike<infer U> ? U[] : unknown extends T ? any[] : never, T & {}>; }
7373
>u : U
7474
>[] : undefined[]
7575
>{} : {}

tests/baselines/reference/destructuringParameterDeclaration4.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
4141
a1(...array2); // Error parameter type is (number|string)[]
4242
~~~~~~
4343
!!! error TS2552: Cannot find name 'array2'. Did you mean 'Array'?
44-
!!! related TS2728 /.ts/lib.es5.d.ts:1522:13: 'Array' is declared here.
44+
!!! related TS2728 /.ts/lib.es5.d.ts:1533:13: 'Array' is declared here.
4545
a5([1, 2, "string", false, true]); // Error, parameter type is [any, any, [[any]]]
4646
~~~~~~~~
4747
!!! error TS2322: Type 'string' is not assignable to type '[[any]]'.

0 commit comments

Comments
 (0)