typescript - TypeScript:如何从类型中仅提取类型数组的键和值
问题描述
我想提出一些条件来仅从值为数组的对象中提取属性。
例如:
type Person = {
name: string
addresses: Address[]
age: number
phoneNumbers: PhoneNumber[]
}
PullOutArrays<Person> => {
phoneNumbers: PhoneNumber[]
addresses: Address[]
}
我尝试过这样的事情无济于事:
type PulledOutArrays<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends unknown[] ? T[K] : never
}
解决方案
从这个 GitHub 问题中抄袭:
type FilteredKeys<T, U> = { [P in keyof T]: T[P] extends U ? P : never }[keyof T];
type FilteredProperties<T, U> = { [K in FilteredKeys<T, U>]: T[K]; };
type PullOutArrays<T> = FilteredProperties<T, unknown[]>;
type Person = {
name: string
addresses: string[]
age: number
phoneNumbers: number[]
}
type PersonKeys = FilteredKeys<Person, unknown[]>;
// "addresses" | "phoneNumbers"
type PersonArrays = PullOutArrays<Person>;
// {
// addresses: string[];
// phoneNumbers: number[];
// }
正如您可能从最初的尝试中看到的那样,映射条件后最终得到的结果是:
{ [P in keyof T]: T[P] extends U ? P : never }
是一个包含所有属性键的接口,但将非数组类型更改为never
,显然是因为 TS 最初并未检查分配给属性键的类型是什么。通过在末尾添加索引,您可以强制编译器读取属性的值并最终从结果中忽略它。
使用生成的联合,您可以在原始接口上从该联合创建新的映射类型。
推荐阅读
- javascript - Stencil.js - 事件监听器的解释
- swiftui - SwiftUI - 从外部调用视图中的函数
- python - 为什么 Google Cloud Dataflow 无法扩展到启用自动缩放且没有配额限制的目标工作人员
- javascript - 设计一个无法看到文本的透明标题栏
- php - API平台自定义get操作
- javascript - 子组件更新时反应不重新渲染
- git - 如何确保我的 git 预提交脚本不会被愚弄?
- r - 如何从线性模型中提取系数而不在 R 中重复我的代码?
- javascript - Ember 输入类型数字只允许在 Decimal 后输入 2 位数字
- flutter - 在合并请求中在 GitLab CI 上格式化 Flutter 代码库