Home > Enterprise >  Generic array type in Typescript
Generic array type in Typescript

Time:01-28

I have function with generic type.

But it return an error Type 'boolean' is not assignable to type 'string'.

function testing<K, V>(array: Array<{ key: K, value: V }>): Array<V> {
    return array.map(data => data.value)
}

testing([{ key: 1, value: "one" }, { key: 2, value: true }])

How can I fix this generic type issue with keeping the type generic. Because the array is unknown and the value may have different custom type.

CodePudding user response:

TS apparently isn't smart enough to infer V being an union type, so for tricky arguments like that you'll have to declare it explicitly.

function testing<K, V>(array: Array<{ key: K, value: V }>): Array<V> {
    return array.map(data => data.value)
}

testing<number, string | boolean>(
    [{ key: 1, value: "one" }, { key: 2, value: true }]
); // works, TS is told explicitly what V is

testing(
    [{ key: 1, value: "one" }, { key: 2, value: "two" }]
); // works, TS correctly infers string

CodePudding user response:

You don't really know the type of value is. You should use unknown to force users to type check it.

I also don't see why you need key and K since they are ignored.

function testing(array: Array<{value: unknown }>): Array<unknown> {
    return array.map(data => data.value);
}

testing([{ key: 1, value: "one" }, { key: 2, value: true }])

CodePudding user response:

This should work:

function testing<K, V>(array: Array<{ key: K, value: V }>): Array<V> {
    return array.map(data => data.value)
}

testing<number, string | boolean>([{ key: 1, value: "one" }, { key: 2, value: true }])

CodePudding user response:

The following will extract the type of each value and return the union:

type ArrayValueTypes<MyValueArray extends { value: unknown }[]> = {
    [K in keyof MyValueArray]: MyValueArray[K]['value']
}

const myArray = [{ key: 1, value: "one" }, { key: 2, value: true }]

function testing<T extends { value: any }[]>(array: T): ArrayValueTypes<T> {
    return array.map(data => data.value)
}

const result = testing(myArray)
// result is of type (string | boolean)[]

Typescript playground example!

  • Related