typescript - 在 TypeScript 中选择并展平类型签名
问题描述
我正在查看标准库中包含的一些更酷的类型函数,然后开始玩。在 TypeScript 中这样的事情真的可能吗?
interface OriginalType {
A: { a : string }
B: { b1 : string, b2: number }
C: {}
D: {c: string}
}
const r : {a: string, b1: string, b2: string} = pickAndFlatten<OriginalType>(['A', 'B'])
解决方案
我们可以通过创建所选属性类型的交集来实现这一点。
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type PickAndFlatten<T, K extends keyof T> = UnionToIntersection<T[K]>;
UnionToIntersection
由@jcalz在这里提供,你应该在那里看到解释(不要忘记用upvote 来感谢他:))。T[K]
会给我们密钥的类型K
。IfK
是键的联合,T[K]
将是联合中所有属性类型的联合。
要在函数中使用它,我们需要两个类型参数,一个代表我们选择的类型,一个代表我们选择的键。
interface OriginalType {
A: { a: string };
B: { b1: string, b2: number };
C: {};
D: { c: string };
}
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type PickAndFlatten<T, K extends keyof T> = UnionToIntersection<T[K]>;
function pickAndFlatten<T, K extends keyof T>(o: T, keys: K[]): PickAndFlatten<T, K> {
// Untested implementation
const entries = Object.entries(o)
.filter(([k, v]) => keys.includes(k as K))
.map(([k, v]) => v);
return Object.assign({}, entries) as any;
}
let o: OriginalType;
const r = pickAndFlatten(o, ['A', 'B']); // { a: string; } & { b1: string; b2: number; }
推荐阅读
- javascript - 根据复选框选择过滤行
- javascript - 在没有 tabBarVisible 选项的情况下从 Stack Navigator 隐藏标签栏
- multithreading - 可以在 MTA 线程中使用 WaitForSingleObject/WaitForMultipleObjects 吗?
- c# - Microsoft.AnalysisServices.AdomdClient 在 .Net Core 应用程序中不起作用(身份验证问题)
- linear-probing - 谁能告诉我实际用途或现实生活中的线性探测示例?
- oracle - 通过 Azure 数据工厂连接 Oracle 数据库
- python - 具有 lambda 层的 tf 切片仅使用最后一个索引
- python - 重新格式化文本文件
- mysql - 无法将参数发送到 MySQL 存储过程窗口窗体
- c# - 如何检查一个类的属性(类的集合/枚举)是否与使用 linq 的另一个集合中的项目匹配?