typescript - 在元组中使用映射类型
问题描述
我将如何在 TypeScript 中输入:
function arrayToObject(array, mapper) {
const result = {};
for(const item of array) {
const [key, value] = mapper(item);
result[key] = value;
}
return result;
}
// returns { '1': 2, '2': 4, '3': 6 }
arrayToObject([1,2,3], v => [v, v * 2])
具体来说,我想让 TypeScript 确保 mapper 的元组结果是有效的键和值。这不起作用:
function arrayToObject<TItem, TObject>(
array: TItem[],
mapper: (t: TItem) => [P in keyof TObject, TObject[P]]
)
解决方案
假设 TS3.4 并使用const
assertions(可以更改该技术以支持 TS3.3 并且不需要此类断言,但这很乏味),我能想到的最强类型是:
function arrayToObject<A, K extends keyof any, V>
(array: readonly A[], mapper: (x: A) => readonly [K, V]): { [P in K]: V } {
const result = {} as { [P in K]: V };
for (const item of array) {
const [key, value] = mapper(item);
result[key] = value;
}
return result;
}
const obj1 = arrayToObject([1, 2, 3] as const, v => [v, v * 2] as const)
// const obj1: {1: number, 2: number, 3: number}
const obj2 = arrayToObject(["a", "b", "c"] as const, k => [k, 0] as const);
// const obj2: {a: 0, b: 0, c: 0}
这至少会保留编译器在映射器的返回类型中知道的任何文字键值。除了一些特定的通用函数改进之外,类型系统对更高级别的类型没有太多支持,所以我很难想出任何方法让编译器理解这一点,比如说,
const obj3 = arrayToObject(["a","b","c"] as const, k => [k, k] as const)
最终将作为 type{a: "a", b: "b", c: "c"}
而不是仍然正确但不是非常具体的 type {a: "a"|"b"|"c", b: "a"|"b"|"c", c: "a"|"b"|"c"}
。那好吧。
希望有帮助;祝你好运!
推荐阅读
- python - 计算来自 pandas groupby 的匹配值的数量
- c++ - MOVNTI 存储是否相对于同一线程创建的其他 MOVNTI 存储重新排序?
- f# - F# pattern matching with optional list of tuples
- c# - 声明 C# 构造函数时大括号不匹配
- dart - 更改检查映射键是否相等的方式
- reactjs - 如何将参数传递给历史推送
- java - 单击时,可展开列表视图不会展开列表。我试图设置可点击但仍然点击列表并没有展开任何东西
- arrays - 基于嵌套值从散列数组中干净地删除散列
- python - Keras 是否支持模型内的 if 语句?
- firebase - PERMISSION_DENIED:权限缺失或不足