Reputation: 5274
I want a write a simple utility function that takes any argument and if the arg is not already array return array with a single element, that arg.
examples:
toArray('hey') => ['hey']
toArray(['hey']) => ['hey']
implementation:
export type ToArr<T> = T extends any[] ? T : T[];
export const toArray = <T>(arg: T): ToArr<T> => {
return (Array.isArray(arg) ? arg : [arg]) as ToArr<T>;
};
that's works fine, as long as the arg passed to toArray
is not of type 'any':
type testType1 = ToArr<string>; // string[] - ok
type testType2 = ToArr<string[]>; // string[] - ok
type testType3 = ToArr<any[]>; // any[] - ok
type testType4 = ToArr<any>; // any - not ok! should be any[]
let myVar:any = 'test'
let myVarArr = toArray(myVar) // - type of myVarArr is any instead of any[]
what's wrong with my implementation of toArr
generic? why does any extends any[] (the condition in the generic function)? how can I modify this function to handle cases where arg is of type any?
for clarification: I want toArray
will always return a value with type of array.
export type ToArr<T> = T extends any[] ? T : T[];
Upvotes: 1
Views: 1440
Reputation: 16623
I think you may be overcomplicating things. A simple union type should work.
const toArray = <T>(arg: T | T[]): T[] => {
return Array.isArray(arg) ? arg : [arg];
};
let myVar: any = 'test'
let myVarArr = toArray(myVar) // type is any[]
Upvotes: 4