简体   繁体   English

如何根据字典的键/值创建 Typescript 类型?

[英]How to create a Typescript type based on the keys/values of a dictionary?

Is there a way to automatically generate a type based on a dictionary value?有没有办法根据字典值自动生成类型? Eg given this dictionary of constant values:例如,给定这个常量值字典:

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

Is there a way to automatically generate a type like this, without having to duplicate everything?有没有办法自动生成这样的类型,而不必复制所有内容?

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

Unfortunately keyof doesn't seem to work since it's an object and not a type, so this doesn't work:不幸的是 keyof 似乎不起作用,因为它是 object 而不是类型,所以这不起作用:

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

I also tried using mapped types with a predeclared union type of the keys, but it doesn't work either:我还尝试将映射类型与键的预声明联合类型一起使用,但它也不起作用:

/* 
  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'

I have a bunch of such dictionaries, and most of them are quite large (30+ keys).我有一堆这样的词典,其中大部分都很大(30+键)。 Duplicating the dictionary into a type everywhere would make it a pain to maintain in case the values change, so any help with this would be great!将字典复制到任何地方都会使维护起来很痛苦,以防值发生变化,所以任何帮助都会很棒!

I think you just want the typeof operator.我认为您只需要typeof运算符。 It simply gets the type of a value.它只是获取值的类型。

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"

Just note the as const on your object which allows typescript to infer the string literals so they can become part of the type.只需注意object 上的as const它允许 typescript 推断字符串文字,以便它们成为类型的一部分。

Playground 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM