我的TypeScript代码看起来像这样:
type TokenType =
| "A"
| "B"
| "C";
class Token<TType extends TokenType> {
constructor(public readonly type: TType) {}
}
function testing(token: Token<TokenType>) {
switch (token.type) {
case "A":
token;
// ^? (parameter) token: Token<TokenType>
handleTypeA(token); // errors
break;
}
}
function handleTypeA(token: Token<"A">) {
// do stuff with the token here...
}
我想使用这个switch
语句来缩小token
的类型,因为我知道它实际上是Token<"A">
。有什么方法可以做到吗?特别是,不使用as
或某种 predicate 函数?在我的实际用例中,我有一个非常长的TokenType
,有很多选项,所以我宁愿使用switch
语句,而不是一大堆if ... else if ... else
语句。
3条答案
按热度按时间m4pnthwp1#
当您为所有可能的令牌类型创建一个令牌类型的并集类型时:
那么你的测试函数将如你所期望的那样工作:
hlswsv352#
您可以使用自索引mapped type将
TokenType
联合分发到Token
联合(以下示例中为SomeToken
):mutmk8jj3#
是的,您可以使用switch语句来缩小令牌的类型,但是您需要使用类型保护。类型保护是返回布尔值的函数,该值指示值是否为特定类型。它们允许您基于运行时检查来细化值的类型。
在您的示例中,您可以为您想要处理的每个令牌类型定义一个类型保护函数,如下所示:
然后,你可以像这样在switch语句中使用这些类型保护:
请注意,isTypeX函数是在调用相应的handleTypeX函数之前调用的。这是必要的,因为TypeScript无法自动推断类型细化,并且您需要在调用期望它的函数之前手动检查令牌是否为预期类型。
这样,您就可以避免使用as或 predicate 函数,仍然使用switch语句来处理令牌类型。
Happy coding:)