有一个枚举:
enum Foo {
Bar, // should cause type error
Baz = 'Baz'
}
是否可以指定一种类型,使其成为仅限字符串的枚举?
有一个枚举:
enum Foo {
Bar, // should cause type error
Baz = 'Baz'
}
是否可以指定一种类型,使其成为仅限字符串的枚举?
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
作为枚举而不是使用其他语言结构。是的,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'.
type FooWitness = EnforceStringEnum<typeof Foo>; // error!
// Type 'Foo.Bar' is not assignable to type 'string'.
enum Foo {
Bar = 0, // should cause type error
Baz = 'Baz'
}
但在TypeScript中可以创建这样的枚举类型,请参见异构枚举。
您也可以使用命名空间:
namespace Foo {
export const Bar: string = "Foo";
export const Baz: string = "Baz";
}
class Foo {
static Bar: string = "Foo";
static Baz: string = "Baz";
}
Foo
中只有 Bar
和 Baz
属性,没有其他内容。Bar
或Bar = 0
应该导致类型错误。 - Estus Flasktype Foo = "Bar" | "Baz"
。这样你甚至不需要使用前缀 Foo
,直接发送 "Bar"
和 "Baz"
即可。 - Wickootype Foo
,但我的意图是摆脱裸字符串,因为Baz
属性的值可能是很长的字符串。 - Estus Flask
declare
命名空间污染,我认为仅使用类型进行类型检查更好。如果您有更好的解决方法,请回答。 - Estus Flasktype alias
也是一个不错的选择。无论是使用declare var
还是type
,都会向命名空间(值或类型)添加一个不必要的名称,所以你可以自行决定使用哪种方式。使用类型更加清晰,但你可以多次重新声明相同的var
(只要类型相同),这样可能会减少命名空间的污染。 - jcalz