TypeScript: Is it possible to get Union Type of Array<keyof CustomObject> only containing the present keys?

36 views Asked by At

I want to create a function which uses a generic type to describe a object and accepts an array of Keys of the generic type. The function returns a function which accepts a object of the generic type and returns a slice only containing the keys passed to the factory function. So the function would look something like this:

function createSlicer<T extends object>(keys: Array<keyof T>) {
  return (obj: T) => keys.reduce((acc, key) => ({ ...acc, [key]: obj[key] }), {});
}

The function can be called like this:

interface Person { name: string; age: number; gender: string; } 

// (obj: Person) => Pick<Person, 'name'>
const nameSlicer = createSlicer<Person>(['name']);
// (obj: Person) => Pick<Person, 'age'>
const ageSlicer = createSlicer<Person>(['age']); 
// (obj: Person) => Pick<Person, 'name' | 'gender'>
const nameAndGenderSlicer = createSlicer<Person>(['name', 'gender']); 

Is it possible to get a union of the "keys" variables type that contains the present keys only to define a correct return type for the createSlicer method without using a second generic type?

When the keys are defined as K[] where K extends keyof T, it's possible to define the methods return type as Pick<T, K>:

function createSlicer<T extends object, K extends keyof T>(keys: K[]): (obj: T) => Pick<T, K> {
  return (obj: T) => keys.reduce((acc, key) => ({ ...acc, [key]: obj[key] }), {});
}

But this requires to define either none or both generic types, it's not possible to call the function like showed above.

0

There are 0 answers