打字稿

时间:2017-11-17 13:03:46

标签: javascript typescript object enums

我正在尝试通过枚举访问地图的值,并为其中的所有字符串制作翻译就绪应用。 两个问题都重叠,我必须决定使用枚举还是只使用JSON格式的对象。

那么枚举和对象之间的区别和用途到底是什么?

例如:

  • 我可以使用枚举来访问数组以及插入标签和其他内容,例如

const enum FieldNames {
  FirstField: "Field One",
  SecondField: "Field Two"
};
    
someFieldArray[FieldNames.FirstField].label = FieldNames.FirstField;
someFieldArray[FieldNames.SecondField].label = FieldNames.SecondField;

  • 或者我可以通过对象实现相同的行为

const FieldNames = {
  FirstField: "Field One",
  SecondField: "Field Two"
};

someFieldArray[FieldNames.FirstField].label = FieldNames.FirstField;
someFieldArray[FieldNames.SecondField].label = FieldNames.SecondField;

我真的没有从简单对象中选择枚举的好处。在我看来,一个对象有更多的好处,没有任何缺点。

4 个答案:

答案 0 :(得分:17)

枚举

如果您需要这些功能,枚举可能会为您带来额外的好处:

const enum FieldNamesEnum {
  FirstField = "Field One",
  SecondField = "Field Two"
};

let x: FieldNamesEnum;

x = FieldNamesEnum.FirstField;
x = FieldNamesEnum.SecondField;

// Error - not assignable to FieldNames
x = 'str';

// Cannot assign
FieldNamesEnum.FirstField = 'str';

重要的是,您无法分配给枚举成员,并且会将类型检查到枚举成员,而不是字符串。

此外,因为您在示例中使用了const enum,所以枚举在运行时将不存在,并且所有引用都将替换文字值(如果您使用了普通enum枚举存在于运行时)。

对象

将此与对象示例进行比较:

const FieldNames = {
  FirstField: "Field One",
  SecondField: "Field Two"
};

let y: string;

y = FieldNames.FirstField;
y = FieldNames.SecondField;

// Oops it works
y = 'str';

// Oops it works

FieldNames.FirstField = 'str';

联盟

如果您不需要完整的枚举,但想要限制值,则可以使用文字值的并集:

type FieldNames = "Field One" | "Field Two";

let x: FieldNames;

x = "Field One";
x = "Field Two";

// Error - not allowed
x = "Field Three";

答案 1 :(得分:7)

我不喜欢@Fenton。对象是安全类型。

const FieldNames = {
  FirstField: 'Field One',
  SecondField: 'Field Two',
} as const;

type ValueOf<T> = T[keyof T];
let y: ValueOf<typeof FieldNames>;

y = FieldNames.FirstField;
y = FieldNames.SecondField;

// TS2322: Type '"str"' is not assignable to type '"Field One" | "Field Two"'.
y = 'str';

// TS2540: Cannot assign to 'FirstField' because it is a read-only property
FieldNames.FirstField = 'str';

答案 2 :(得分:6)

function (foo: FieldNames) { }

如果FieldNames是一个对象,这意味着此函数需要一个具有属性FirstFieldSecondField的实例。如果FieldNames是枚举(在这种情况下它应该是单数,而不是复数),这意味着函数需要 FieldNames 的值之一,即{{1} }或"Field One"

用法非常不同。

答案 3 :(得分:0)

这应该是主要原因。.可以将enum用作类型,因此可以使用以下选项之一,但不能将cosnt对象定义为类型,它将在一个obj中包含所有选项:)

您也可以这样做

type FieldNames = "Field One" | "Field Two";

但是如果列表很长,则枚举要好得多, 在ES6中,枚举是纯粹无用的,只是使用obejct 但在打字稿中,这是我的选择,也是我选择的主要好处