I am facing an issue while writing the type for the pick function. Everything works smoothly when picking only one key or multiple keys with values of the same type. However, if I attempt to pick a few keys and their values are of different types, I encounter an error. I am uncertain about where I might have made a mistake.
Thank you for taking the time.
export interface Mapper<T = any, R = any> {
(arg: T): R;
}
export function pick<O, T extends keyof O>(keys: T[], obj?: O): { [K in T]: O[T] };
export function pick<T>(keys: T[], obj?: never): Mapper;
export function pick<O, T extends keyof O>(keys: T[], obj?: O) {
const picker: Mapper<O, { [K in T]: O[T] }> = _obj =>
keys.reduce((acc, key) => {
if (key in _obj) {
acc[key] = _obj[key];
}
return acc;
}, {} as O);
return obj ? picker(obj) : picker;
}
const obj = { someKey: 'value', otherKey: 42, moreKey: ['array value'] };
const newObj = pick(['otherKey'], obj);
//OK. TS type for newObj is {otherKey: number}
const n: number = newObj.otherKey;
// OK
const otherNewObj = pick(['otherKey', 'someKey'], obj);
//not really OK. TS type for otherNewObj is {otherKey: number | string, someKey: number | string}
const m: number = otherNewObj.someKey;
// Error. Type string | number is not assignable to the number