web-dev-qa-db-ja.com

TypeScript列挙型でオブジェクトを使用する

私は列挙型を持っています:

 export enum PizzaSize {
          SMALL =  0,
          MEDIUM = 1,
          LARGE = 2

    }

しかし、ここではいくつかの値のペアを使用したいと思います。 SMALL iには2つの値(0、100)があると言いたいです。これはどうすればできますか?

私は使用するよう努めます

export enum PizzaSize {
          SMALL =  {key:key, value: value},
         ...

    }

しかし、TypeScriptはこれを受け入れません。

30

更新:find @ Javarome's answer 以下、よりエレガントです。彼のやり方を使うことをお勧めします。

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};
    }
}
14
Joe Tse

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'
_
43
Javarome

使用してみてください:

const pizzaSize = {
    small: { key: 0, value: 25 },
    medium: { key: 1, value: 35 },
    large: { key: 2, value: 50 }
}
6
Jarek

TypeScript 3.4 の時点で、keyof typeofconstアサーション の組み合わせを使用して、enumと同じタイプセーフティを持つオブジェクトを作成できます。 、まだ複雑な値を保持しています。

typeと同じ名前のconstを作成することにより、通常の列挙型と同じ網羅性チェックを行うことができます。

唯一の欠点は、enumメンバーの名前を保持するために複雑なオブジェクト(ここではvalueを使用しています)にキーが必要なことです(誰かがこれらのオブジェクトをタイプセーフな方法、私はそれを見たいと思います!私は1つを働かせることができませんでした)。

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)
3
blaineh