我有一个自定义类型,比如说
export type Fruit = "apple" | "banana" | "grape";
我想确定一个字符串是否属于 Fruit 类型。我怎样才能做到这一点?
以下不起作用。
let myfruit = "pear";
if (typeof myfruit === "Fruit") {
console.log("My fruit is of type 'Fruit'");
}
任何想法表示赞赏!
原文由 maia 发布,翻译遵循 CC BY-SA 4.0 许可协议
简短的回答:
您不能在运行时使用
typeof
来检查仅在编译时存在的interface
类型。相反,您可以编写 用户定义的类型保护函数 来检查此类类型:长答案如下:
您可能会对 TypeScript 中值和类型之间的区别感到困惑,尤其是当它与
typeof
运算符有关时。您可能知道,TypeScript 为 JavaScript 添加了一个静态类型系统,并且 当代码被转译时,该类型系统会被删除。 TypeScript 的语法是这样的,一些表达式和语句引用运行时存在的 _值_,而其他表达式和语句引用仅在设计/编译时存在的 _类型_。值 具有 类型,但它们本身不是类型。重要的是,在代码中的某些地方,编译器会期望一个值并将它找到的表达式解释为一个值,如果可能的话,编译器会期望一个类型并将它找到的表达式解释为一个类型。typeof
运算符过着双重生活。表达式typeof x
总是期望x
是一个值,但是typeof x
本身可能是一个值或类型,具体取决于上下文:let TypeofBar = typeof bar;
行将通过 JavaScript,它将在运行时使用 JavaScript typeof 运算符 并生成一个字符串。但是type TypeofBar = typeof bar
;被删除,它使用 TypeScript 类型查询运算符 检查 TypeScript 分配给名为bar
的值的静态类型。在您的代码中,
typeof myfruit
是一个值,而不是一个类型。所以它是 JavaScripttypeof
运算符,而不是 TypeScript 类型查询运算符。它将始终返回值"string"
;它永远不会是Fruit
或"Fruit"
。您无法在运行时获得 TypeScript 类型查询运算符的结果,因为类型系统在运行时被擦除。您需要放弃typeof
运算符。您 可以 做的是检查
myfruit
与三个已知的Fruit
字符串文字的值…例如,例如:完美,对吧?好吧,也许这看起来像很多冗余代码。这是一种不太冗余的方法。首先,根据现有的文字值数组定义您的
Fruit
类型… TypeScript 可以从值推断类型,但您不能从类型生成值。您可以验证
Fruit
与您手动定义的类型相同。然后,对于类型测试,您可以像这样使用 用户定义的类型保护:isFruit()
是一个检查是否在fruit
数组中找到其参数的函数,如果是,则将其参数的类型缩小为Fruit
。让我们看看它的工作原理:该类型保护还让编译器知道在
if
语句的“then”子句中,myfruit
是Fruit
。想象一下,如果您有一个只接受Fruit
的函数,以及一个可能是也可能不是Fruit
的值:您不能直接调用该函数:
但是您 可以 在检查后在“then”子句中调用它:
这大概就是您首先要检查自定义类型的原因。这样你就可以做到了。
回顾一下:你不能使用
typeof
。您可以与字符串进行比较。您可以进行一些类型推断和类型保护,以消除重复代码并从编译器获取控制流类型分析。Playground 代码链接