Daw*_*son 4 generics transformation typescript
如何定义一个transform<I, O>接受类型 I 的输入并返回类型 O 的输出的函数类型,然后将函数定义identity为 a 的特定实现transform?
例如
type transform<I, O> = (input: I) => O;
const identity = // ...
Run Code Online (Sandbox Code Playgroud)
这样我就可以定义一个函数
const mapToObject = <K, V, O>(
map: Map<K, V>,
transformValue: transform<V, O> = identity
) => Array.from(map.entries()).reduce((obj, [key, val]) => {
obj[key] = transformValue(value);
return obj;
}, {});
Run Code Online (Sandbox Code Playgroud)
该mapToObject函数应该采用MapandtransformValue函数并将映射转换为简单的 JS 对象,应用于transformValue映射中的每个值。transformValue应默认为identity函数v => v.
尽管我对严格类型的解决方案感兴趣,但恒等函数映射any是有效的。any
只有一种合理的方法来输入恒等函数,这并不奇怪
const identity = <T>(t: T) => t;
Run Code Online (Sandbox Code Playgroud)
但是严格类型的恒等函数不能分配给任意转换 - 编译器知道它返回与收到的类型相同的类型,因此您的输入mapToObject不一致 - 当您调用它时结果类型是什么
mapToObject<string, number, Date>(new Map<string, number>())
Run Code Online (Sandbox Code Playgroud)
Dates这需要表示为依赖类型 - 结果对象的类型取决于是否给出变换参数或使用默认值。在 TypeScript 中,您可以通过重载函数声明来做到这一点:
function mapToObject<K, V>(map: Map<K, V>)
: { [n: string]: V };
function mapToObject<K, V, O>(map: Map<K, V>, transformValue: transform<V, O>)
: { [n: string]: O };
function mapToObject<K, V, O>(map: Map<K, V>, transformValue?: transform<V, O>)
: { [n: string]: {} }
{
const transform: (v: V) => {} = transformValue || identity;
return Array.from(map.entries()).reduce((obj, [key, val]) => {
obj[key.toString()] = transform(val) ;
return obj;
}, {});
}
Run Code Online (Sandbox Code Playgroud)
由于实际值类型根本没有在实现中使用,因此它可以作为空对象类型给出{},它与 V 和 O 类型兼容(您可以使用联合类型V | O,因为它也是兼容的,但它更冗长并且可以让您购买这里没有什么)
通过这些声明,编译器可以检测到不一致的用法:
// error: Expected 1-2 arguments, but got 1
mapToObject<string, number, Date>(new Map<string, number>())
mapToObject<string, number>(new Map<string, number>()) // ok
mapToObject<string, number, Date>(new Map<string, number>(), n => new Date(n)) //ok
Run Code Online (Sandbox Code Playgroud)
结果类型按预期推断:
const o1 = mapToObject(new Map<string, number>())
// {[n: string]: number}
const o2 = mapToObject(new Map<string, number>(), n => new Date(n))
// {[n: string]: Date}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4059 次 |
| 最近记录: |