将键 - 值对接口列表转换为单个映射类型

时间:2017-06-16 00:02:37

标签: typescript

我有一组接口如下:

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",
}

有没有办法用映射类型做到这一点?映射类型似乎不允许您引用当前索引类型,只是类型作为整体,这意味着您不能将来自同一接口的字段绑定在一起。

1 个答案:

答案 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