I want to have a nested array of Item
s
type Item = { name: string }
I've come across a few approaches and I'm trying the differences in them.
Using
type
type Item = { name: string } type NestedArray<T> = Array<T> | Array<NestedArray<T>>; type Items = NestedArray<Item>;
But with this approach it seems I can't have
Items
and a nested array ofItems
in the same array:const items: Items = [ // item, Error: Type '(Item | Item[][])[]' is not assignable to type 'Items'. [ // item, Error: Type 'Item' is not assignable to type 'NestedArray<Item>' [ // item, Error: Type '[Item, [any]]' is not assignable to type 'NestedArray<Item>' [ item, // Works only as long as there isn't a nested array alongside item ] ] ] ]
But at least it has normal Array functions:
items.map(i => i) // works
Using
interface
interface Items { [n: number]: Item | Items }
const items: Items = [ item [ item [ item [ item, // All Works! ] ] ] ]
But
interface Items
is no longer anArray
(that hasmap
etc functions)items.map(i => i) // Error: Property 'map' does not exist on type 'Items'.
How to get the best of both worlds?
- A deeply nested array that allows items and array of items side-by-side.
- Implements normal Array functions like map/filter etc.
CodePudding user response:
But with this approach it seems I can't have Items and a nested array of Items in the same array
That should suggest the change needed:
type NestedArray<T> = Array<T | NestedArray<T>>;
I.e. instead of "an array of T
or an array of NestedArray<T>
" make "an array of (T
or NestedArray<T>
)".
CodePudding user response:
Just extend Items
interface with Array
:
type Item = { name: string }
interface Items extends Array<Item | Items> { [n: number]: Item | Items }
const item = { name: 'John' }
const items: Items = [item, [item, [item, [item,],]]]
items.map(e => e) // ok
const x = items[0] // Item | Items