【问题标题】:How to create a Typescript type based on the keys/values of a dictionary?如何根据字典的键/值创建 Typescript 类型?
【发布时间】:2022-02-08 03:21:57
【问题描述】:

有没有办法根据字典值自动生成类型?例如。给定这个常量值字典:

export const SHIPMETHODS: OptionsMap<UpsShipMethodOption> = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
}

有没有办法自动生成这样的类型,而不必复制所有内容?

export type ShipMethodOptionMap = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
}

不幸的是 keyof 似乎不起作用,因为它是一个对象而不是一个类型,所以这不起作用:

export type UpsShipMethodOption = keyof SHIPMETHODS // Doesn't work

我也尝试使用映射类型和键的预声明联合类型,但它也不起作用:

/* 
  Type 'KeyOptions' is not assignable to type 'string | number | symbol'.
  Type 'KeyOptions' is not assignable to type 'symbol'.ts(2322)
*/
export type OptionsMap<KeyOptions> = {
    readonly [Property in KeyOptions]: string;
}

export const SHIPMETHODS: OptionsMap<UpsShipMethodOption> = {
    'UPS': 'GND',
    'UPS AIR2': '2DA',
    'UPS 3DAY SELECT': '3DS'
}
export type UpsShipMethodOption = 'UPS' | 'UPS AIR2' | 'UPS 3DAY SELECT'

我有一堆这样的字典,其中大多数都很大(30 多个键)。将字典复制到任何地方的类型都会使维护变得很痛苦,以防值发生变化,因此对此的任何帮助都会很棒!

【问题讨论】:

    标签: javascript typescript types mapped-types


    【解决方案1】:

    我认为您只需要 typeof 运算符。它只是获取值的类型。

    const SHIPMETHODS = {
        'UPS': 'GND',
        'UPS AIR2': '2DA',
        'UPS 3DAY SELECT': '3DS'
    } as const // as const is important.
    
    type ShipMethodOptionMap = typeof SHIPMETHODS 
    /*
    type ShipMethodOptionMap = {
        readonly UPS: "GND";
        readonly 'UPS AIR2': "2DA";
        readonly 'UPS 3DAY SELECT': "3DS";
    }
    */
    
    type UpsShipMethodOption = keyof ShipMethodOptionMap
    // type UpsShipMethodOption = "UPS" | "UPS AIR2" | "UPS 3DAY SELECT"
    

    请注意the as const on your object,它允许打字稿推断字符串文字,因此它们可以成为类型的一部分。

    Playground

    【讨论】:

    • 啊!这是完美的,谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多