Reputation: 1465
Is there a way in typescript to express the typings of a function that takes in a list of strings, and creates an object where each key's value is the key itself:
const createActionTypes = (types: string[]) => {
return types.reduce((typesMap, type) => {
typesMap[type] = type
return typesMap
}, {})
}
// Input
createActionTypes(['a', 'b'])
// Output
{ a: 'a', b: 'b' }
Here's what I've tried, without luck:
const createActionTypes = <T extends readonly string[], U extends T[number]>(
types: T
): { [key in U]: U } => {
return types.reduce((typesMap, type) => {
typesMap[type] = type
return typesMap
}, {})
}
const x = createActionTypes(['a', 'b'] as const)
// Typings for x get resolved to:
{
a: "a" | "b";
b: "a" | "b";
}
Upvotes: 0
Views: 52
Reputation: 55856
You are really close. You need to specify that the value is same type as key
and not the whole set "a"|"b"
which is U
.
const createActionTypes = <T extends readonly string[], U extends T[number]>(
types: T
): { [key in U]: key } => {
return types.reduce((typesMap, type) => {
typesMap[type] = type
return typesMap
}, {} as any)
}
const x = createActionTypes(['a', 'b'] as const)
Also, just for clarity, I would avoid using reserved words like type
as a variable or function parameter. It required me to look twice to ensure type
is not type, but a value.
Upvotes: 2