i want to ask is there any way to form a function in typescript that can enable autocomplete when using array.reduce?
ex:
function formObject<T>(arr: T[]): ?? {
return arr.reduce((memo, val) => {
memo[val] = 'test'
return memo
}, {})
}
const array = ["foo", "bar"]
const object = formObject(array);
const testObject2 = formObject(["another"])
hoping that i will get autocomplete for object like this
const a = object.foo // type string and foo is autocomplete
const b = object.bar // type string and bar is autocomplete
const c = testObject2.another // type string and another is autocomplete
const d = object.another // return type error because there's no another in object
CodePudding user response:
This is certainly possible. The question is if you really need this...
We can create a generic type StringArrToObject
which takes a tuple T
and creates an object with every element of T
as a key.
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
type StringArrToObject<T extends string[]> = Expand<{
[K in keyof T as T[K] extends string ? T[K] : never]: string
}>
Don't mind the Expand
type here. This is just there to make the type prettier.
We can now use this in the function formObject
.
function formObject<
T extends string[]
>(arr: readonly [...T]): StringArrToObject<T> {
return arr.reduce((memo, val) => {
memo[val] = 'test'
return memo
}, {} as Record<string, any>) as any
}
Let's see this function in action:
const array = ["foo", "bar"] as const
const obj = formObject(array);
// const obj: {
// foo: string;
// bar: string;
// }
const testObject2 = formObject(["another"])
// const testObject2: {
// another: string;
// }
Important detail here: See how we have to use as const
for the array
variable. Otherwise the type information about specific elements will be lost.
But keep in mind: This type implementation only works for this specific array.reduce()
implementation. If you change the logic inside the function, you will also have to change the type to reflect the changed behaviour. So this is not a generic type that would work for any reduce
implementation.