我有一组接口如下:
interface Foo {
key: "fooKeyType",
value: "fooValueType",
}
interface Bar {
key: "barKeyType",
value: "barValueType",
}
interface Baz {
key: "bazKeyType",
value: "bazValueType",
}
type FooBarBaz = Foo | Bar | Baz;
type FooBarBazKey = FooBarBaz["key"];
type FooBarBazValue = FooBarBaz["value"];
其中*keyType
总是const字符串(因此它们是有效键),但*valueType
只是可能是实际类型的替身(例如数字,日期,自定义类等)
我想将这些接口转换为映射键的单一类型映射 - >值,如下所示:
/* Can I generate this from the above? */
type FooBarBazMap = {
fooKeyType: "fooValueType",
barKeyType: "barValueType",
bazKeyType: "bazValueType",
}
有没有办法用映射类型做到这一点?映射类型似乎不允许您引用当前索引类型,只是类型作为整体,这意味着您不能将来自同一接口的字段绑定在一起。
答案 0 :(得分:1)
是的。这一切都归结为改变这种类型:
type KeyValue<K extends string, V> = {
key: K,
value: V,
};
......对此:
type Desired<K extends string, V> = {
[key in K]: V;
};
理想情况下,我们想输入类似的内容:
type TransformKeyValueWrong<T extends KeyValue<T["key"], T["value"]>> = {
[key in T["key"]]: T["value"];
};
但是打字稿编译器会对我们大喊“[ts]类型参数'key'有一个循环约束。”,这是真的,但不会阻止我们,因为我们有通用参数默认值!
type TransformKeyValue<T extends KeyValue<K, T["value"]>, K extends string = T["key"]> = {
[key in K]: T["value"];
};
现在我们要做的就是为Foo,Bar,Baz声明交集类型:
type SuperDuperType =
& TransformKeyValue<Foo>
& TransformKeyValue<Bar>
& TransformKeyValue<Baz>
;
验证它是否有效:
type Test = SuperDuperType["barKeyType"]; // type Test = "barValueType";
请注意,通用参数默认值需要TypeScript版本&gt; = 2.3