我有一个类属性,其类型是多个字符串文字的并集:
toBinary
我要做的是将这些字符串定义在某种数组中的其他位置,然后在属性定义中使用该数组。如下所示:
public reaction? : 'haha' | 'wow' | 'angry' | 'sad' | 'like';
我知道以上是不可能的,但这是一般的想法。打字稿能提供完成这项工作的任何东西吗?
答案 0 :(得分:1)
不,您无法为数组中的字符串定义有效值,并在编译时检查它。
当您通过TypeScript编译器运行第一个示例时,其原因变得更加明显 - 它来自:
class Test {
public reaction?: 'haha' | 'wow' | 'angry' | 'sad' | 'like' = 'haha';
}
对此:
var Test = (function () {
function Test() {
this.reaction = 'haha';
}
return Test;
}());
编译器运行完毕后,您的类型不再存在了!它只是JavaScript,除了你明确写的内容之外没有添加额外的逻辑。您无法将有效值存储在数组中,因为在代码实际运行之前,不会对数组的内容进行求值,此时已执行类型检查并且已丢弃类型。 / p>
因此,如果要检查字符串是否与数组中的值匹配,则需要实际编写一些在运行时进行检查的代码。
答案 1 :(得分:1)
这取决于您打算如何使用它,但字符串枚举可能会为您提供所需内容:
enum ReactionKind {
haha = 'haha',
wow = 'wow',
angry = 'angry',
sad = 'sad',
like = 'like'
}
const reaction: ReactionKind = ReactionKind.angry;
// Get the string value
const stringValue = ReactionKind[reaction];
// Get the Enum from a string
const enumValue = ReactionKind['wow'];
您仍然可以在需要的地方使用纯字符串值,但您可以将其用作类型和运行时值,这似乎就是您所追求的。
您还会注意到,对于字符串枚举,如果在映射到枚举时使用字符串键,只要您使用--noImplicitAny
,就会检查它。
// Error
const enumValue = ReactionKind['wat'];
答案 2 :(得分:1)
自TypeScript 3.4起,您可以使用 const断言从运行时值生成类型。
const allowedStrings = ['haha', 'wow', 'angry', 'sad', 'like'] as const;
type AllowedString = typeof allowedStrings[number]; // [number] is important here
// We can freely map over values
const mapped = allowedStrings.map((s) => s.toUpperCase());
// And use generated type to create type-safe functions
const process = (s: AllowedString) => {
// Type of s is
// s: "haha" | "wow" | "angry" | "sad" | "like"
return s;
};
答案 3 :(得分:0)
enum Reaction {
'haha',
'wow',
'angry',
'sad',
'like'
}
let reaction: keyof typeof Reaction;
reaction = 'angry'; // Fine
// reaction = 'whatever'; // Error
看来上面应该做你想做的。如果仍然需要字符串数组,则可以按以下方式获取它:
const allowedStrings = Object.keys(Reaction).filter(k => Number.isNaN(+k));
答案 4 :(得分:0)
您可以使用 type
来命名联合类型。
type Reaction = 'haha' | 'wow' | 'angry' | 'sad' | 'like';
const reaction?: Reaction = 'haha';