Использовать объект в typescript перечислении
У меня есть перечисление:
export enum PizzaSize {
SMALL = 0,
MEDIUM = 1,
LARGE = 2
}
Но здесь я хотел бы использовать пару значений: например. SMALL я бы хотел сказать, что он имеет 2 значения (0, 100). Как я могу сделать это?
Я стараюсь использовать
export enum PizzaSize {
SMALL = {key:key, value: value},
...
}
Но typescript не принимает этот.
Ответы
Ответ 1
Обновление: найдите ответ @Javarome ниже, что более элегантно. Я предлагаю использовать его путь.
Если вам нужно использовать 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};
}
}
Ответ 2
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()
вы также сможете неявно печатать имя/ключ enum из объекта:
console.log(PizzaSize.MEDIUM); // prints 'MEDIUM'
Ответ 3
Попробуйте использовать:
const pizzaSize = {
small: { key: 0, value: 25 },
medium: { key: 1, value: 35 },
large: { key: 2, value: 50 }
}
Ответ 4
Начиная с Typescript 3.4, вы можете использовать комбинацию утверждений keyof typeof
и const
для создания объектов, которые могут иметь такую же безопасность типов, что и перечисления, и при этом содержать сложные значения.
Создавая type
с тем же именем, что и const
, вы можете иметь те же проверки исчерпываемости, что и обычные перечисления.
Единственная проблема заключается в том, что вам нужен какой-то ключ в сложном объекте (здесь я использую value
) для хранения имени члена enum (если кто-то может выяснить вспомогательную функцию, которая может создавать эти объекты безопасным способом, Я хотел бы увидеть это! Я не мог заставить работать).
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)
Ответ 5
Object.freeze делает его доступным только для чтения и предотвращает добавление дополнительных свойств:
const pizzaSize = Object.freeze({
small: { key: 0, value: 25 },
medium: { key: 1, value: 35 },
large: { key: 2, value: 50 }
})