簡體   English   中英

在打字稿中使用枚舉作為接口鍵

[英]Using enum as interface key in typescript

我想知道我是否可以在接口中使用 enum 作為對象鍵。我已經為它做了一個小測試:

export enum colorsEnum{
red,blue,green
}

export interface colorsInterface{
[colorsEnum.red]:boolean,
[colorsEnum.blue]:boolean,
[colorsEnum.green]:boolean
}

當我運行它時,我收到以下錯誤:

A computed property name in an interface must directly refer to a built-in symbol.

我做錯了還是不可能?

您可以嘗試使用類型:

export enum colorsEnum{
    red, blue, green
}

export type colorsInterface = {
    [key in colorsEnum]: boolean;
};

let example: colorsInterface = {
    [colorsEnum.red]: true,
    [colorsEnum.blue]: false,
    [colorsEnum.green]: true
};

或者,如果您不想使用所有鍵:添加 ?

export type colorsInterface = {
    [key in colorsEnum]?: boolean;
};

let example: colorsInterface = {
    [colorsEnum.red]: true,
    [colorsEnum.blue]: false
};

好的,關鍵思想是將 Enum 轉換為正確的類型並使用它擴展接口: 您可以在此處查看實時代碼。

const enum Enum {
    key1 = "value1",
    key2 = "value2",
    key3 = "value3",
}
type EnumKeys = keyof typeof Enum;
type EnumKeyFields = {[key in EnumKeys]:boolean}

interface IEnumExtended extends EnumKeyFields {
    KeyEx1:boolean;
    KeyEx2:string;
}

// Test it
const enumInstance: IEnumExtended = {

};

當您進入enumInstance您將獲得 Enum 鍵的自動完成功能,而不是值。

要定義接口,必須提供成員名稱而不是計算。

export interface colorsInterface {
    red: boolean;
    blue: boolean;
    green: boolean;
}

如果您擔心保持枚舉和接口同步,您可以使用以下方法:

export interface colorsInterface {
    [color: number]: boolean;
}

var example: colorsInterface = {};
example[colorsEnum.red] = true;
example[colorsEnum.blue] = false;
example[colorsEnum.green] = true;

TypeScript 非常樂意讓您將枚舉作為索引傳遞,例如,如果您決定重命名red ,則重命名重構會將所有內容保持在一起。

為什么不讓它盡可能簡單:

export enum Color {
    Red = 'red',
    Blue = 'blue',
    Green = 'green'
}

export interface IColors{
    [Color.Red]: boolean,
    [Color.Blue]: boolean,
    [Color.Green]: boolean
}

使用本機Record<Keys, Type>實用程序的簡單解決方案。 ( 文檔)

export enum Colors {
    RED = 'red',
    GREEN = 'green',
    BLUE = 'blue'
}

export type ColorInterface = Record<Colors, boolean>

這種類型轉換為:

// translates to:

export type ColorInterface = {
    red: boolean;
    green: boolean;
    blue: boolean;
}

重要提示:您必須定義一個enum鍵並將值相應地映射到它們,否則,您將獲得一個使用枚舉index的類型/接口,如下所示:

export enum Colors {
    'red',
    'green',
    'blue'
}

export type ColorInterface = Record<Colors, boolean>

// translates to:

export type ColorInterface = {
    0: boolean;
    1: boolean;
    2: boolean;
}

或者,如果您不想顯式定義枚舉鍵,或者如果您只有幾個鍵可以使用,您也可以使用type別名定義顏色,這也將正確轉換為您需要的:

export type Colors = 'red' | 'green' | 'blue'

// will also translate to:

export type ColorInterface = {
    red: boolean;
    green: boolean;
    blue: boolean;
}

這對我們有用:

type DictionaryFromEnum = {
  [key in keyof typeof SomeEnum]?: string
}

可能您正在通過as搜索密鑰重新映射

注意:需要TypeScript ^4.1

示例:

enum Color {
  red,
  blue,
  green,
}

// Define valid colors
// type TColor = 'red' | 'blue' | 'green';
type TColor = keyof typeof Color;

// Define object structure, with `color` as prefix for each `TColor`
type TWithColorCode = {
  [colorKey in TColor as `color${Capitalize<string & colorKey>}`]: string;
};

const a: TWithColorCode = {
  // All properties will be required
  colorGreen: '#00FF00',
  colorBlue: '#0000FF',
  colorRed: '#FF0000',
};

// Extending an `interface`:

export interface ICarRGB extends TWithColorCode {
  id: number;
  name: string;
  // Optional property
  createdAt?: Date;
}

const b: ICarRGB = {
  id: 1,
  name: 'Foo',
  colorGreen: '#00FF00',
  colorBlue: '#0000FF',
  colorRed: '#FF0000',
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM