[英]Use object literal as TypeScript enum values
我有一個枚舉:
export enum PizzaSize {
SMALL = 0,
MEDIUM = 1,
LARGE = 2
}
但在這里我想使用一些值對:例如SMALL
我想說它的key
為0
, value
100
。 我努力使用:
export enum PizzaSize {
SMALL = { key: 0, value: 100 },
// ...
}
但是 TypeScript 不接受這個。 我怎樣才能做到這一點?
TypeScript 僅支持基於數字或字符串的枚舉,因此您必須使用類模擬對象枚舉(這將允許您將其用作函數聲明中的類型):
export class PizzaSize {
static readonly SMALL = new PizzaSize('SMALL', 'A small pizza');
static readonly MEDIUM = new PizzaSize('MEDIUM', 'A medium pizza');
static readonly LARGE = new PizzaSize('LARGE', 'A large pizza');
// private to disallow creating other instances of this type
private constructor(private readonly key: string, public readonly value: any) {
}
toString() {
return this.key;
}
}
然后您可以使用預定義的實例來訪問它們的value
:
const mediumVal = PizzaSize.MEDIUM.value;
或您可能想要在PizzaSize
中定義的任何其他屬性/屬性類型。
並且由於toString()
覆蓋,您還可以從對象中隱式打印枚舉名稱/鍵:
console.log(PizzaSize.MEDIUM); // prints 'MEDIUM'
如果您需要使用 Type,請嘗試添加一些代碼。 用法: getPizzSizeSpec(PizzaSize.small).value
enum PizzaSize {
small,
medium,
large
}
interface PizzaSizeSpec {
key: number,
value: number
}
function getPizzaSizeSpec(pizzaSize: PizzaSize): PizzaSizeSpec {
switch (pizzaSize) {
case PizzaSize.small:
return {key:0, value: 25};
case PizzaSize.medium:
return {key:0, value: 35};
case PizzaSize.large:
return {key:0, value: 50};
}
}
從Typescript 3.4 開始,您可以使用keyof typeof
和const
斷言的組合來創建可以與枚舉具有相同類型安全性的對象,並且仍然可以保存復雜的值。
通過創建與const
同名的type
,您可以進行與普通枚舉相同的詳盡檢查。
唯一的缺點是您需要復雜對象中的一些鍵(我在這里使用value
)來保存枚舉成員的名稱(如果有人能找出一個可以以類型安全方式構建這些對象的輔助函數,我我很想看到它!我無法讓一個工作)。
export const PizzaSize = {
small: { value: 'small', key: 0, size: 25 },
medium: { value: 'medium', key: 1, size: 35 },
large: { value: 'large', key: 2, size: 50 },
} as const
export type PizzaSize = keyof typeof PizzaSize
// if you remove any of these cases, the function won't compile
// because it can't guarantee that you've returned a string
export function order(p: PizzaSize): string {
switch (p) {
case PizzaSize.small.value: return 'just for show'
case PizzaSize.medium.value: return 'just for show'
case PizzaSize.large.value: return 'just for show'
}
}
// you can also just hardcode the strings,
// they'll be type checked
export function order(p: PizzaSize): string {
switch (p) {
case 'small': return 'just for show'
case 'medium': return 'just for show'
case 'large': return 'just for show'
}
}
在其他文件中,這可以簡單地使用,只需導入PizzaSize
。
import { PizzaSize } from './pizza'
console.log(PizzaSize.small.key)
type Order = { size: PizzaSize, person: string }
另請注意,即使是通常可變的對象也無法使用as const
語法進行變異。
const Thing = {
ONE: { one: [1, 2, 3] }
} as const
// this won't compile!! Yay!!
Thing.ONE.one.splice(1, 0, 0)
我認為要達到你想要的,這樣的事情會起作用
interface PizzaInfo {
name: string;
cost_multiplier: number;
}
enum PizzaSize {
SMALL,
MEDIUM,
LARGE,
}
const pizzas: Record<PizzaSize, PizzaInfo> = {
[PizzaSize.SMALL]: { name: "Small", cost_multiplier: 0.7 },
[PizzaSize.MEDIUM]: { name: "Medium", cost_multiplier: 1.0 },
[PizzaSize.LARGE]: { name: "Large", cost_multiplier: 1.5 },
};
const order = PizzaSize.SMALL;
console.log(pizzas[order].name); // "Small"
嘗試使用:
const pizzaSize = {
small: { key: 0, value: 25 },
medium: { key: 1, value: 35 },
large: { key: 2, value: 50 }
}
Object.freeze 使其只讀並防止添加更多屬性:
const pizzaSize = Object.freeze({
small: { key: 0, value: 25 },
medium: { key: 1, value: 35 },
large: { key: 2, value: 50 }
})
您可以使用類型化的 const 來實現此目的:
export const PizzaSize: {
[key: string]: { key: string, value: string };
} = {
SMALL: { key: 'key', value: 'value' }
};
您可以選擇將類型信息提取到單獨的接口聲明中:
interface PizzaSizeEnumInstance {
key: string;
value: string;
}
interface PizzaSizeEnum {
[key: string]: PizzaSizeEnumInstance;
}
export const PizzaSize: PizzaSizeEnum = {
SMALL: { key: 'key', value: 'value' }
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.