假设我有以下有效负载:{a: 1, b: 2, c: 3}
我想有一个函数,给定一个对象,选择一些键,并相应地返回一个类型。
function pick<T>(obj: any, ...keys: string[]): T {
return (
Object.fromEntries(
keys
.filter(key => key in obj)
.map(key => [key, obj[key]])
)
) as T;
}
const test = { a: 1, b: 2, c: 3 };
type Foo = {
a: number,
b: number
}
const result = pick<Foo>(test, 'a', 'b');
console.log(result);
有没有更好的方法来处理这个问题?我知道使用类型强制几乎就是关闭Typescript安全网。
例如,如果我这样做:
console.log(pick<Foo>(test, 'b'));
我告诉typescript函数pick返回一个Foo对象,但是它没有定义键a
。
使用案例是我们有API调用,我们:
1.必须键入
1.只想键入与我们的用例相关的键
1.按照TS最佳做法执行
2条答案
按热度按时间63lcw9qa1#
如果你不需要对
pick
进行类型检查,那么你至少可以让所有的类型排成一行。我们将要使用的超级方便的Typescript类型实际上叫做Pick
。函数实现完全相同,只是在最后我们通过
any
强制转换,这实际上告诉Typescript信任我们。Pick<T, K>
正是您需要的类型:K
是扩展keyof T
的任意类型。假设您将常量参数传递给此函数,您将得到一个文本类型的并集,如"a" | "b"
对K
。我不知道有什么方法可以让
Object.fromEntries
进行类型检查,除了像我们上面所做的那样通过any
进行强制转换。根据我的经验,当你开始在Object
原型上弄乱函数时,你必须稍微引导Typescript来获得正确的类型。jgovgodb2#
Silvio的答案与我在评论中发布的调整一起工作,但是如果你想依赖于
_.pick
的话,看起来Lodash支持这一点。https://lodash.com/docs/4.17.15#pick
它完全按照你(和我!)想要的方式工作。