首页 文章

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

提问于
浏览
2

我有一组接口如下:

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

  • 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版本> = 2.3

相关问题