Return type of array concat

Viewed 767

I have a method that makes an array of flattend objects from a nested object.

{a: 'b',
 c: {d: 'e'}
}

will be

[{a: 'b'}, {d:'e'}]

So the return type of this method is an array of objects (Record<string, any>[]). But Typescript gives the following error:

TS2769: No overload matches this call. ... Argument of type 'Record<string, any>[] | { [x: string]: any; }' is not assignable to parameter of type 'ConcatArray'. Type 'Record<string, any>[]' is not assignable to type 'ConcatArray'.

What would be the correct return type of the _flatten method:

const _flatten = (obj: Record<string, any>): Record<string, any>[] =>  
    [].concat(...Object.keys(obj)
             .map((key: string) => (
                   typeof obj[key] === 'object' ? _flatten(obj[key]) : { [key]: obj[key] }
             ))
         );
1 Answers

I guess the error message is this:

Type 'Record<string, any>[]' is not assignable to type 'ConcatArray<never>'

That's because you used [].concat and [] is type of never[].

Try to use Array.prototype.concat instead:

const _flatten = (obj: Record<string, any>): Record<string, any>[] =>  
    Array.prototype.concat(...Object.keys(obj)
             .map((key: string) => (
                   typeof obj[key] === 'object' ? _flatten(obj[key]) : { [key]: obj[key] }
             ))
         );

Typescript sandbox

Or you can typehint [] like this one:

([] as any[]).concat(/* omitted */)
Related