有枚举:
enum Foo {
Bar, // should cause type error
Baz = 'Baz'
}
是否可以为其指定类型以使其成为仅字符串枚举?
答案 0 :(得分:2)
如果您愿意,可以执行以下操作:
创建一个函数,要求其输入只有string
- 值属性:
const enforceStringEnum = <E extends Record<keyof E, string>>(e: E) => {};
然后,根据需要声明Foo
:
enum Foo {
Bar,
Baz = 'Baz'
}
并以Foo
作为输入调用该函数:
enforceStringEnum(Foo); // error!
// Type 'Foo.Bar' is not assignable to type 'string'.
这会在您收到有关Foo.Bar
的消息时出错,您可以返回并修复以删除错误。
是的,您获得的错误不是Foo
声明的本地错误,但它确实允许您将Foo
保留为enum
,而不是使用其他语言结构。是的,enforceStringEnum()
在运行时具有(非常小的)效果。如果你想要根本没有运行时工件,那么它是可能的,但(在我看来)有点丑陋:
type EnforceStringEnum<E extends Record<keyof E, string>> = true;
enum Foo {
Bar,
Baz = 'Baz'
}
declare var fooWitness: EnforceStringEnum<typeof Foo>; // error!
// Type 'Foo.Bar' is not assignable to type 'string'.
但它的工作方式相同。
编辑:或者,正如@estus提到的,你可以使用类型别名而不是变量声明:
type FooWitness = EnforceStringEnum<typeof Foo>; // error!
// Type 'Foo.Bar' is not assignable to type 'string'.
希望有所帮助。祝你好运!
答案 1 :(得分:1)
如果你检查生成的枚举的JS代码,你会发现它等同于
enum Foo {
Bar = 0, // should cause type error
Baz = 'Baz'
}
但允许在TypeScript中创建此类枚举,请参阅Heterogeneous Enums。
您还可以使用命名空间:
namespace Foo {
export const Bar: string = "Foo";
export const Baz: string = "Baz";
}
或具有静态字段的类:
class Foo {
static Bar: string = "Foo";
static Baz: string = "Baz";
}
第一个好处是Bar
中只有Baz
和Foo
属性,没有别的。