Skip to content

Commit 684b039

Browse files
committed
Types that extend Array or ReadonlyArray are automatically array-like
1 parent 322c70f commit 684b039

File tree

5 files changed

+84
-1
lines changed

5 files changed

+84
-1
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19703,7 +19703,13 @@ namespace ts {
1970319703
function isArrayLikeType(type: Type): boolean {
1970419704
// A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
1970519705
// or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
19706-
return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
19706+
return isArrayType(type) || hasArrayOrReadonlyArrayBaseType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
19707+
}
19708+
19709+
function hasArrayOrReadonlyArrayBaseType(type: Type): boolean {
19710+
return !!(getObjectFlags(type) & ObjectFlags.Reference)
19711+
&& !!(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)
19712+
&& some(getBaseTypes((type as TypeReference).target as InterfaceType), isArrayType);
1970719713
}
1970819714

1970919715
function isEmptyArrayLiteralType(type: Type): boolean {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [excessiveStackDepthFlatArray.ts]
2+
interface MiddlewareArray<T> extends Array<T> {}
3+
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
4+
5+
declare const defaultMiddleware: MiddlewareArray<any>;
6+
configureStore({
7+
middleware: [...defaultMiddleware], // Should not error
8+
});
9+
10+
11+
//// [excessiveStackDepthFlatArray.js]
12+
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
13+
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
14+
to[j] = from[i];
15+
return to;
16+
};
17+
configureStore({
18+
middleware: __spreadArray([], defaultMiddleware)
19+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/excessiveStackDepthFlatArray.ts ===
2+
interface MiddlewareArray<T> extends Array<T> {}
3+
>MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0))
4+
>T : Symbol(T, Decl(excessiveStackDepthFlatArray.ts, 0, 26))
5+
>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, --, --) ... and 2 more)
6+
>T : Symbol(T, Decl(excessiveStackDepthFlatArray.ts, 0, 26))
7+
8+
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
9+
>configureStore : Symbol(configureStore, Decl(excessiveStackDepthFlatArray.ts, 0, 48))
10+
>options : Symbol(options, Decl(excessiveStackDepthFlatArray.ts, 1, 32))
11+
>middleware : Symbol(middleware, Decl(excessiveStackDepthFlatArray.ts, 1, 42))
12+
>MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0))
13+
14+
declare const defaultMiddleware: MiddlewareArray<any>;
15+
>defaultMiddleware : Symbol(defaultMiddleware, Decl(excessiveStackDepthFlatArray.ts, 3, 13))
16+
>MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0))
17+
18+
configureStore({
19+
>configureStore : Symbol(configureStore, Decl(excessiveStackDepthFlatArray.ts, 0, 48))
20+
21+
middleware: [...defaultMiddleware], // Should not error
22+
>middleware : Symbol(middleware, Decl(excessiveStackDepthFlatArray.ts, 4, 16))
23+
>defaultMiddleware : Symbol(defaultMiddleware, Decl(excessiveStackDepthFlatArray.ts, 3, 13))
24+
25+
});
26+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/excessiveStackDepthFlatArray.ts ===
2+
interface MiddlewareArray<T> extends Array<T> {}
3+
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
4+
>configureStore : (options: { middleware: MiddlewareArray<any>;}) => void
5+
>options : { middleware: MiddlewareArray<any>; }
6+
>middleware : MiddlewareArray<any>
7+
8+
declare const defaultMiddleware: MiddlewareArray<any>;
9+
>defaultMiddleware : MiddlewareArray<any>
10+
11+
configureStore({
12+
>configureStore({ middleware: [...defaultMiddleware], // Should not error}) : void
13+
>configureStore : (options: { middleware: MiddlewareArray<any>; }) => void
14+
>{ middleware: [...defaultMiddleware], // Should not error} : { middleware: any[]; }
15+
16+
middleware: [...defaultMiddleware], // Should not error
17+
>middleware : any[]
18+
>[...defaultMiddleware] : any[]
19+
>...defaultMiddleware : any
20+
>defaultMiddleware : MiddlewareArray<any>
21+
22+
});
23+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @lib: es2019
2+
3+
interface MiddlewareArray<T> extends Array<T> {}
4+
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
5+
6+
declare const defaultMiddleware: MiddlewareArray<any>;
7+
configureStore({
8+
middleware: [...defaultMiddleware], // Should not error
9+
});

0 commit comments

Comments
 (0)