lodash
有拾取功能,使用方法如下:
var object = { 'a': 1, 'b': '2', 'c': 3 };
_.pick(object, ['a', 'c']);
// => { 'a': 1, 'c': 3 }
我想用打字稿写一个类型安全的版本。
这个函数的用法应该是
pick(object, o => o.a, o.b)
目标是不指定相同的键两次,同时保持类型安全。
这有可能实现吗?
听起来您可能正在寻找 Pick 类型。这样的事情对你有用吗?
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
const ret: any = {};
keys.forEach(key => {
ret[key] = obj[key];
})
return ret;
}
const o = {a: 1, b: '2', c: 3}
const picked = pick(o, 'b', 'c');
picked.a; // not allowed
picked.b // string
picked.c // number
Object.fromEntries
(es2019):
function pick<T extends object, K extends keyof T> (base: T, ...keys: K[]): Pick<T, K> {
const entries = keys.map(key => ([key, base[key]]));
return Object.fromEntries(entries);
}
这是我的,使用
Object.assign()
function pick<T, K extends keyof T>(object: T, keys: K[]): Pick<T, K> {
return Object.assign(
{},
...keys.map(key => {
if (object && Object.prototype.hasOwnProperty.call(object, key)) {
return { [key]: object[key] };
}
})
);
};
lodash 类型定义使用
Pick
传播道具,因此您不必手动定义它。只需使用 npm i --save-dev @types/lodash
或 yarn add -D @types/lodash
安装它们。
这是我的,扩展@Bayu Karnia 回答:
function pick<T extends Record<string | number | symbol, T>, K extends keyof T>(
object: T,
keys: K[]
): Pick<T, K> {
return Object.assign(
{},
...keys.map((key: K) => {
return { [key]: object[key] };
})
);
}
根据 Ethan.Roday 的回答,我做了一些修改。 使用
Array.reduce
并摆脱 any
类型。
export function pick<T, K extends keyof T>(obj: T, keys: K[]) {
return keys.reduce((acc, val) => {
return (acc[val] = obj[val]), acc;
}, {} as Pick<T, K>);
}
看起来我设法交换了参数 + 咖喱,最后类型就足够好了。 如果有人解释一下,将不胜感激:
const pick = <T, K extends keyof T>(keys: (keyof T)[]) => <R extends T>(obj: R) => keys.reduce<Pick<R, K>>((acc, key) => {
(acc as T)[key] = obj[key]
return acc;
}, {} as Pick<R, K>)