Types that extend Array or ReadonlyArray are automatically array-like

This commit is contained in:
Andrew Branch
2021-03-15 14:37:59 -07:00
parent 322c70fd82
commit 684b039835
5 changed files with 84 additions and 1 deletions
+7 -1
View File
@@ -19703,7 +19703,13 @@ namespace ts {
function isArrayLikeType(type: Type): boolean {
// A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
// or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
return isArrayType(type) || hasArrayOrReadonlyArrayBaseType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
}
function hasArrayOrReadonlyArrayBaseType(type: Type): boolean {
return !!(getObjectFlags(type) & ObjectFlags.Reference)
&& !!(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)
&& some(getBaseTypes((type as TypeReference).target as InterfaceType), isArrayType);
}
function isEmptyArrayLiteralType(type: Type): boolean {
@@ -0,0 +1,19 @@
//// [excessiveStackDepthFlatArray.ts]
interface MiddlewareArray<T> extends Array<T> {}
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
declare const defaultMiddleware: MiddlewareArray<any>;
configureStore({
middleware: [...defaultMiddleware], // Should not error
});
//// [excessiveStackDepthFlatArray.js]
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
configureStore({
middleware: __spreadArray([], defaultMiddleware)
});
@@ -0,0 +1,26 @@
=== tests/cases/compiler/excessiveStackDepthFlatArray.ts ===
interface MiddlewareArray<T> extends Array<T> {}
>MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0))
>T : Symbol(T, Decl(excessiveStackDepthFlatArray.ts, 0, 26))
>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)
>T : Symbol(T, Decl(excessiveStackDepthFlatArray.ts, 0, 26))
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
>configureStore : Symbol(configureStore, Decl(excessiveStackDepthFlatArray.ts, 0, 48))
>options : Symbol(options, Decl(excessiveStackDepthFlatArray.ts, 1, 32))
>middleware : Symbol(middleware, Decl(excessiveStackDepthFlatArray.ts, 1, 42))
>MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0))
declare const defaultMiddleware: MiddlewareArray<any>;
>defaultMiddleware : Symbol(defaultMiddleware, Decl(excessiveStackDepthFlatArray.ts, 3, 13))
>MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0))
configureStore({
>configureStore : Symbol(configureStore, Decl(excessiveStackDepthFlatArray.ts, 0, 48))
middleware: [...defaultMiddleware], // Should not error
>middleware : Symbol(middleware, Decl(excessiveStackDepthFlatArray.ts, 4, 16))
>defaultMiddleware : Symbol(defaultMiddleware, Decl(excessiveStackDepthFlatArray.ts, 3, 13))
});
@@ -0,0 +1,23 @@
=== tests/cases/compiler/excessiveStackDepthFlatArray.ts ===
interface MiddlewareArray<T> extends Array<T> {}
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
>configureStore : (options: { middleware: MiddlewareArray<any>;}) => void
>options : { middleware: MiddlewareArray<any>; }
>middleware : MiddlewareArray<any>
declare const defaultMiddleware: MiddlewareArray<any>;
>defaultMiddleware : MiddlewareArray<any>
configureStore({
>configureStore({ middleware: [...defaultMiddleware], // Should not error}) : void
>configureStore : (options: { middleware: MiddlewareArray<any>; }) => void
>{ middleware: [...defaultMiddleware], // Should not error} : { middleware: any[]; }
middleware: [...defaultMiddleware], // Should not error
>middleware : any[]
>[...defaultMiddleware] : any[]
>...defaultMiddleware : any
>defaultMiddleware : MiddlewareArray<any>
});
@@ -0,0 +1,9 @@
// @lib: es2019
interface MiddlewareArray<T> extends Array<T> {}
declare function configureStore(options: { middleware: MiddlewareArray<any> }): void;
declare const defaultMiddleware: MiddlewareArray<any>;
configureStore({
middleware: [...defaultMiddleware], // Should not error
});