From 684b03983540b04755b9f21ef206dc87b2b06858 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 15 Mar 2021 14:37:59 -0700 Subject: [PATCH 1/2] Types that extend Array or ReadonlyArray are automatically array-like --- src/compiler/checker.ts | 8 +++++- .../reference/excessiveStackDepthFlatArray.js | 19 ++++++++++++++ .../excessiveStackDepthFlatArray.symbols | 26 +++++++++++++++++++ .../excessiveStackDepthFlatArray.types | 23 ++++++++++++++++ .../compiler/excessiveStackDepthFlatArray.ts | 9 +++++++ 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.js create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.symbols create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.types create mode 100644 tests/cases/compiler/excessiveStackDepthFlatArray.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 625cfabd99b72..a5260871b5271 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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 - 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 { diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.js b/tests/baselines/reference/excessiveStackDepthFlatArray.js new file mode 100644 index 0000000000000..a8e7017146612 --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.js @@ -0,0 +1,19 @@ +//// [excessiveStackDepthFlatArray.ts] +interface MiddlewareArray extends Array {} +declare function configureStore(options: { middleware: MiddlewareArray }): void; + +declare const defaultMiddleware: MiddlewareArray; +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) +}); diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.symbols b/tests/baselines/reference/excessiveStackDepthFlatArray.symbols new file mode 100644 index 0000000000000..9d05616763fd4 --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/excessiveStackDepthFlatArray.ts === +interface MiddlewareArray extends Array {} +>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 }): 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; +>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)) + +}); + diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.types b/tests/baselines/reference/excessiveStackDepthFlatArray.types new file mode 100644 index 0000000000000..ad02a8e74b664 --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/excessiveStackDepthFlatArray.ts === +interface MiddlewareArray extends Array {} +declare function configureStore(options: { middleware: MiddlewareArray }): void; +>configureStore : (options: { middleware: MiddlewareArray;}) => void +>options : { middleware: MiddlewareArray; } +>middleware : MiddlewareArray + +declare const defaultMiddleware: MiddlewareArray; +>defaultMiddleware : MiddlewareArray + +configureStore({ +>configureStore({ middleware: [...defaultMiddleware], // Should not error}) : void +>configureStore : (options: { middleware: MiddlewareArray; }) => void +>{ middleware: [...defaultMiddleware], // Should not error} : { middleware: any[]; } + + middleware: [...defaultMiddleware], // Should not error +>middleware : any[] +>[...defaultMiddleware] : any[] +>...defaultMiddleware : any +>defaultMiddleware : MiddlewareArray + +}); + diff --git a/tests/cases/compiler/excessiveStackDepthFlatArray.ts b/tests/cases/compiler/excessiveStackDepthFlatArray.ts new file mode 100644 index 0000000000000..fd16b622199da --- /dev/null +++ b/tests/cases/compiler/excessiveStackDepthFlatArray.ts @@ -0,0 +1,9 @@ +// @lib: es2019 + +interface MiddlewareArray extends Array {} +declare function configureStore(options: { middleware: MiddlewareArray }): void; + +declare const defaultMiddleware: MiddlewareArray; +configureStore({ + middleware: [...defaultMiddleware], // Should not error +}); From 63c63467376dc14bbb57342ad9a4e62d2c14a607 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 16 Mar 2021 09:30:02 -0700 Subject: [PATCH 2/2] Add React repro to test --- .../excessiveStackDepthFlatArray.errors.txt | 48 +++++++ .../reference/excessiveStackDepthFlatArray.js | 43 +++++- .../excessiveStackDepthFlatArray.symbols | 128 ++++++++++++++++-- .../excessiveStackDepthFlatArray.types | 87 +++++++++++- .../compiler/excessiveStackDepthFlatArray.ts | 36 ++++- 5 files changed, 325 insertions(+), 17 deletions(-) create mode 100644 tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt b/tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt new file mode 100644 index 0000000000000..825a402ca02c4 --- /dev/null +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.errors.txt @@ -0,0 +1,48 @@ +tests/cases/compiler/index.tsx(35,13): error TS2322: Type '{ key: string; }' is not assignable to type 'HTMLAttributes'. + Property 'key' does not exist on type 'HTMLAttributes'. + + +==== tests/cases/compiler/index.tsx (1 errors) ==== + interface MiddlewareArray extends Array {} + declare function configureStore(options: { middleware: MiddlewareArray }): void; + + declare const defaultMiddleware: MiddlewareArray; + configureStore({ + middleware: [...defaultMiddleware], // Should not error + }); + + declare namespace React { + type DetailedHTMLProps, T> = E; + interface HTMLAttributes { + children?: ReactNode; + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactText = string | number; + type ReactChild = ReactText; + type ReactFragment = {} | ReactNodeArray; + interface ReactNodeArray extends Array {} + } + declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; + li: React.DetailedHTMLProps, HTMLLIElement>; + } + } + declare var React: any; + + const Component = () => { + const categories = ['Fruit', 'Vegetables']; + + return ( +
    +
  • All
  • + {categories.map((category) => ( +
  • {category}
  • // Error about 'key' only + ~~~ +!!! error TS2322: Type '{ key: string; }' is not assignable to type 'HTMLAttributes'. +!!! error TS2322: Property 'key' does not exist on type 'HTMLAttributes'. + ))} +
+ ); + }; + \ No newline at end of file diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.js b/tests/baselines/reference/excessiveStackDepthFlatArray.js index a8e7017146612..4578612b4a630 100644 --- a/tests/baselines/reference/excessiveStackDepthFlatArray.js +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.js @@ -1,4 +1,4 @@ -//// [excessiveStackDepthFlatArray.ts] +//// [index.tsx] interface MiddlewareArray extends Array {} declare function configureStore(options: { middleware: MiddlewareArray }): void; @@ -6,9 +6,41 @@ declare const defaultMiddleware: MiddlewareArray; configureStore({ middleware: [...defaultMiddleware], // Should not error }); + +declare namespace React { + type DetailedHTMLProps, T> = E; + interface HTMLAttributes { + children?: ReactNode; + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactText = string | number; + type ReactChild = ReactText; + type ReactFragment = {} | ReactNodeArray; + interface ReactNodeArray extends Array {} +} +declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; + li: React.DetailedHTMLProps, HTMLLIElement>; + } +} +declare var React: any; + +const Component = () => { + const categories = ['Fruit', 'Vegetables']; + + return ( +
    +
  • All
  • + {categories.map((category) => ( +
  • {category}
  • // Error about 'key' only + ))} +
+ ); +}; -//// [excessiveStackDepthFlatArray.js] +//// [index.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]; @@ -17,3 +49,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from) { configureStore({ middleware: __spreadArray([], defaultMiddleware) }); +var Component = function () { + var categories = ['Fruit', 'Vegetables']; + return (React.createElement("ul", null, + React.createElement("li", null, "All"), + categories.map(function (category) { return (React.createElement("li", { key: category }, category) // Error about 'key' only + ); }))); +}; diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.symbols b/tests/baselines/reference/excessiveStackDepthFlatArray.symbols index 9d05616763fd4..08fe546e6da06 100644 --- a/tests/baselines/reference/excessiveStackDepthFlatArray.symbols +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.symbols @@ -1,26 +1,128 @@ -=== tests/cases/compiler/excessiveStackDepthFlatArray.ts === +=== tests/cases/compiler/index.tsx === interface MiddlewareArray extends Array {} ->MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0)) ->T : Symbol(T, Decl(excessiveStackDepthFlatArray.ts, 0, 26)) +>MiddlewareArray : Symbol(MiddlewareArray, Decl(index.tsx, 0, 0)) +>T : Symbol(T, Decl(index.tsx, 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)) +>T : Symbol(T, Decl(index.tsx, 0, 26)) declare function configureStore(options: { middleware: MiddlewareArray }): 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)) +>configureStore : Symbol(configureStore, Decl(index.tsx, 0, 48)) +>options : Symbol(options, Decl(index.tsx, 1, 32)) +>middleware : Symbol(middleware, Decl(index.tsx, 1, 42)) +>MiddlewareArray : Symbol(MiddlewareArray, Decl(index.tsx, 0, 0)) declare const defaultMiddleware: MiddlewareArray; ->defaultMiddleware : Symbol(defaultMiddleware, Decl(excessiveStackDepthFlatArray.ts, 3, 13)) ->MiddlewareArray : Symbol(MiddlewareArray, Decl(excessiveStackDepthFlatArray.ts, 0, 0)) +>defaultMiddleware : Symbol(defaultMiddleware, Decl(index.tsx, 3, 13)) +>MiddlewareArray : Symbol(MiddlewareArray, Decl(index.tsx, 0, 0)) configureStore({ ->configureStore : Symbol(configureStore, Decl(excessiveStackDepthFlatArray.ts, 0, 48)) +>configureStore : Symbol(configureStore, Decl(index.tsx, 0, 48)) middleware: [...defaultMiddleware], // Should not error ->middleware : Symbol(middleware, Decl(excessiveStackDepthFlatArray.ts, 4, 16)) ->defaultMiddleware : Symbol(defaultMiddleware, Decl(excessiveStackDepthFlatArray.ts, 3, 13)) +>middleware : Symbol(middleware, Decl(index.tsx, 4, 16)) +>defaultMiddleware : Symbol(defaultMiddleware, Decl(index.tsx, 3, 13)) }); +declare namespace React { +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) + + type DetailedHTMLProps, T> = E; +>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.tsx, 8, 25)) +>E : Symbol(E, Decl(index.tsx, 9, 25)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.tsx, 9, 61)) +>T : Symbol(T, Decl(index.tsx, 9, 53)) +>T : Symbol(T, Decl(index.tsx, 9, 53)) +>E : Symbol(E, Decl(index.tsx, 9, 25)) + + interface HTMLAttributes { +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.tsx, 9, 61)) +>T : Symbol(T, Decl(index.tsx, 10, 27)) + + children?: ReactNode; +>children : Symbol(HTMLAttributes.children, Decl(index.tsx, 10, 31)) +>ReactNode : Symbol(ReactNode, Decl(index.tsx, 12, 3)) + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : Symbol(ReactNode, Decl(index.tsx, 12, 3)) +>ReactChild : Symbol(ReactChild, Decl(index.tsx, 14, 35)) +>ReactFragment : Symbol(ReactFragment, Decl(index.tsx, 15, 30)) + + type ReactText = string | number; +>ReactText : Symbol(ReactText, Decl(index.tsx, 13, 75)) + + type ReactChild = ReactText; +>ReactChild : Symbol(ReactChild, Decl(index.tsx, 14, 35)) +>ReactText : Symbol(ReactText, Decl(index.tsx, 13, 75)) + + type ReactFragment = {} | ReactNodeArray; +>ReactFragment : Symbol(ReactFragment, Decl(index.tsx, 15, 30)) +>ReactNodeArray : Symbol(ReactNodeArray, Decl(index.tsx, 16, 43)) + + interface ReactNodeArray extends Array {} +>ReactNodeArray : Symbol(ReactNodeArray, Decl(index.tsx, 16, 43)) +>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) +>ReactNode : Symbol(ReactNode, Decl(index.tsx, 12, 3)) +} +declare namespace JSX { +>JSX : Symbol(JSX, Decl(index.tsx, 18, 1)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.tsx, 19, 23)) + + ul: React.DetailedHTMLProps, HTMLUListElement>; +>ul : Symbol(IntrinsicElements.ul, Decl(index.tsx, 20, 31)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.tsx, 8, 25)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>HTMLAttributes : Symbol(React.HTMLAttributes, Decl(index.tsx, 9, 61)) +>HTMLUListElement : Symbol(HTMLUListElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLUListElement : Symbol(HTMLUListElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + li: React.DetailedHTMLProps, HTMLLIElement>; +>li : Symbol(IntrinsicElements.li, Decl(index.tsx, 21, 90)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.tsx, 8, 25)) +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) +>HTMLAttributes : Symbol(React.HTMLAttributes, Decl(index.tsx, 9, 61)) +>HTMLLIElement : Symbol(HTMLLIElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLLIElement : Symbol(HTMLLIElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + } +} +declare var React: any; +>React : Symbol(React, Decl(index.tsx, 6, 3), Decl(index.tsx, 25, 11)) + +const Component = () => { +>Component : Symbol(Component, Decl(index.tsx, 27, 5)) + + const categories = ['Fruit', 'Vegetables']; +>categories : Symbol(categories, Decl(index.tsx, 28, 7)) + + return ( +
    +>ul : Symbol(JSX.IntrinsicElements.ul, Decl(index.tsx, 20, 31)) + +
  • All
  • +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) + + {categories.map((category) => ( +>categories.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>categories : Symbol(categories, Decl(index.tsx, 28, 7)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>category : Symbol(category, Decl(index.tsx, 33, 23)) + +
  • {category}
  • // Error about 'key' only +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) +>key : Symbol(key, Decl(index.tsx, 34, 11)) +>category : Symbol(category, Decl(index.tsx, 33, 23)) +>category : Symbol(category, Decl(index.tsx, 33, 23)) +>li : Symbol(JSX.IntrinsicElements.li, Decl(index.tsx, 21, 90)) + + ))} +
+>ul : Symbol(JSX.IntrinsicElements.ul, Decl(index.tsx, 20, 31)) + + ); +}; + diff --git a/tests/baselines/reference/excessiveStackDepthFlatArray.types b/tests/baselines/reference/excessiveStackDepthFlatArray.types index ad02a8e74b664..ae346a034fa67 100644 --- a/tests/baselines/reference/excessiveStackDepthFlatArray.types +++ b/tests/baselines/reference/excessiveStackDepthFlatArray.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/excessiveStackDepthFlatArray.ts === +=== tests/cases/compiler/index.tsx === interface MiddlewareArray extends Array {} declare function configureStore(options: { middleware: MiddlewareArray }): void; >configureStore : (options: { middleware: MiddlewareArray;}) => void @@ -21,3 +21,88 @@ configureStore({ }); +declare namespace React { + type DetailedHTMLProps, T> = E; +>DetailedHTMLProps : E + + interface HTMLAttributes { + children?: ReactNode; +>children : ReactNode + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : ReactNode +>null : null + + type ReactText = string | number; +>ReactText : ReactText + + type ReactChild = ReactText; +>ReactChild : ReactText + + type ReactFragment = {} | ReactNodeArray; +>ReactFragment : ReactFragment + + interface ReactNodeArray extends Array {} +} +declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; +>ul : React.HTMLAttributes +>React : any +>React : any + + li: React.DetailedHTMLProps, HTMLLIElement>; +>li : React.HTMLAttributes +>React : any +>React : any + } +} +declare var React: any; +>React : any + +const Component = () => { +>Component : () => any +>() => { const categories = ['Fruit', 'Vegetables']; return (
  • All
  • {categories.map((category) => (
  • {category}
  • // Error about 'key' only ))}
);} : () => any + + const categories = ['Fruit', 'Vegetables']; +>categories : string[] +>['Fruit', 'Vegetables'] : string[] +>'Fruit' : "Fruit" +>'Vegetables' : "Vegetables" + + return ( +>(
  • All
  • {categories.map((category) => (
  • {category}
  • // Error about 'key' only ))}
) : any + +
    +>
    • All
    • {categories.map((category) => (
    • {category}
    • // Error about 'key' only ))}
    : any +>ul : any + +
  • All
  • +>
  • All
  • : any +>li : any +>li : any + + {categories.map((category) => ( +>categories.map((category) => (
  • {category}
  • // Error about 'key' only )) : any[] +>categories.map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>categories : string[] +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>(category) => (
  • {category}
  • // Error about 'key' only ) : (category: string) => any +>category : string +>(
  • {category}
  • // Error about 'key' only ) : any + +
  • {category}
  • // Error about 'key' only +>
  • {category}
  • : any +>li : any +>key : string +>category : string +>category : string +>li : any + + ))} +
+>ul : any + + ); +}; + diff --git a/tests/cases/compiler/excessiveStackDepthFlatArray.ts b/tests/cases/compiler/excessiveStackDepthFlatArray.ts index fd16b622199da..b8ad99e287d5a 100644 --- a/tests/cases/compiler/excessiveStackDepthFlatArray.ts +++ b/tests/cases/compiler/excessiveStackDepthFlatArray.ts @@ -1,5 +1,7 @@ -// @lib: es2019 +// @lib: es2019,dom +// @jsx: react +// @Filename: index.tsx interface MiddlewareArray extends Array {} declare function configureStore(options: { middleware: MiddlewareArray }): void; @@ -7,3 +9,35 @@ declare const defaultMiddleware: MiddlewareArray; configureStore({ middleware: [...defaultMiddleware], // Should not error }); + +declare namespace React { + type DetailedHTMLProps, T> = E; + interface HTMLAttributes { + children?: ReactNode; + } + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactText = string | number; + type ReactChild = ReactText; + type ReactFragment = {} | ReactNodeArray; + interface ReactNodeArray extends Array {} +} +declare namespace JSX { + interface IntrinsicElements { + ul: React.DetailedHTMLProps, HTMLUListElement>; + li: React.DetailedHTMLProps, HTMLLIElement>; + } +} +declare var React: any; + +const Component = () => { + const categories = ['Fruit', 'Vegetables']; + + return ( +
    +
  • All
  • + {categories.map((category) => ( +
  • {category}
  • // Error about 'key' only + ))} +
+ ); +};