【问题标题】:How to make TypeScript type key based on its value property如何根据其 value 属性制作 TypeScript 类型键
【发布时间】:2021-07-09 17:45:38
【问题描述】:

我想创建一种类型,该类型采用具有值的可索引对象的类型 (例如这个:)

const ENUMLIKE_WITH_METADATA = {
    a: {
        position: 1,
        value: 'str',
    },
    b: {
        position: 2,
        value: 'ng',
    },
} as const;

并基于此返回对象,value 属性作为对象键,位置作为值。 示例:

type transformedObject = {
    str: 1,
    ng: 2,
}

基础对象总是遵循这个结构

type EnumlikeWithMetadata = {
    [x: string]: {
        value: string;
        position: number;
    };
};

到目前为止,我取得了 2 种类型,它们都不能以自己的方式工作:

第一个匹配 value 属性到由所有 position 属性组成的联合类型:

type IntegerEnumlikeHelper<T extends EnumlikeWithMetadata> = {
    [J in T[keyof T]['value']]: T[keyof T]['position']
};

结果如下所示:

type H = {
  str: 2 | 1;
  ng: 2 | 1;
}

第二个将值映射到位置,但使其嵌套到原始键中

type IntegerEnumlikeHelper<T extends EnumlikeWithMetadata> = {
    [C in keyof T]: { [J in T[C]['value']]: T[C]['position'] };
};

type H = {
    readonly a: {
        str: 1;
    };
    readonly b: {
        ng: 2;
    };
}

将嵌套值映射为键和值的正确方法是什么?

【问题讨论】:

    标签: typescript typescript-typings type-inference typescript-generics


    【解决方案1】:

    最简单的方法是使用key remapping in mapped types,使用语法{[A in B as K]: V}

    type Transform<T extends Record<keyof T, { position: any, value: PropertyKey }>> =
        { -readonly [K in keyof T as T[K]['value']]: T[K]['position'] }
    

    这里我要求转换后的类型T 必须具有具有position 属性和value 属性的属性值,此外value 属性必须类似于键。然后我们遍历keyof T 中的每个K 并生成键值对。所需键为T[K]['value']K-keyed 属性为Tvalue 属性类型),所需值为T[K]['position']

    让我们验证它是否有效:

    type TransformedObject = Transform<typeof ENUMLIKE_WITH_METADATA>
    /* type TransformedObject = {
        str: 1;
        ng: 2;
    }*/
    

    看起来不错。

    Playground link to code

    【讨论】:

      猜你喜欢
      • 2021-06-28
      • 2021-12-20
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多