typescript - 过滤对象键时的“动态”类型
问题描述
假设我有以下有效负载:
{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 调用,我们:
- 必须打字
- 只想为我们的用例键入相关键
- 遵循 TS 最佳实践
解决方案
如果您对不进行类型检查的实现感到满意pick
,那么您至少可以使类型全部对齐。我们将为此使用的超级方便的 Typescript 类型实际上称为Pick
.
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
return (
Object.fromEntries(
keys
.filter(key => key in obj)
.map(key => [key, obj[key]])
)
) as any;
}
函数实现是完全相同的,除了最后我们通过 进行any
转换,这有效地告诉 Typescript 信任我们。Pick<T, K>
正是你想要的类型:它说“取 type T
,用 type 下标K
,看看我们得到了什么”。K
是扩展的任意类型keyof T
。假设你将常量参数传递给这个函数,你会得到一个类似"a" | "b"
for的文字类型的联合K
。
我不知道有一种方法可以进行类型检查,而不是像我们上面所做的那样Object.fromEntries
进行强制转换。any
以我的经验,当你开始弄乱Object
原型上的函数时,你必须稍微哄一下 Typescript 才能得到正确的类型。
推荐阅读
- unit-testing - 如何重写 gocov 命令去工具覆盖?
- java - 片段包
- c# - ASP.NET Core Web API 中的 Azure AD 仅应用身份验证
- reactjs - 在展示/容器模式中使用 PureComponents
- javascript - 如何自定义 vaadin-upload 聚合物组件的结果?
- javascript - 如何从角度通用构建中删除 sourceMappingURL?
- postgresql - PostgreSQL 本地时间
- mysql - 按组中的最大值排序
- c - 使用 C 编译 DLL
- python - Datetime Pandas 函数仅转换单个系列