我遇到了一些看起来像这样的代码:
export function foo(arg: string): arg is MyType {
return ...
}
我无法在 docs 或 google 中搜索 is
,这是一个非常常见的词,并且基本上出现在每个页面上。
关键字在这种情况下有什么作用?
有关详细信息,请参阅 user-defined type guard functions 的参考。
function isString(test: any): test is string{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
}
example("hello world");
使用上述格式的类型谓词 test is string
(而不是只使用 boolean
作为返回类型),在调用 isString()
后,如果函数返回 true
,TypeScript 会将类型缩小为 { 5} 在任何由函数调用保护的块中。 编译器会认为 foo
在下面保护的块中是 string
(并且仅在下面保护的块中)
{
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
类型谓词仅在编译时使用。生成的 .js
文件(运行时)没有区别,因为它不考虑 TYPE。
我将在以下四个示例中说明差异。
例如 1:上面的示例代码不会有编译错误,也不会出现运行时错误。
例如 2:下面的示例代码将出现编译错误(以及运行时错误),因为 TypeScript 已将类型缩小到 string
并检查 toExponential
不属于 string
方法。
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
console.log(foo.toExponential(2));
}
}
例如 3:下面的示例代码没有编译错误,但会出现运行时错误,因为 TypeScript 只会在受保护的块中将类型缩小到 string
而不是在之后,因此 foo.toExponential
不会产生编译错误(TypeScript 会不认为它是 string
类型)。但是,在运行时,string
没有 toExponential
方法,因此会出现运行时错误。
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
}
console.log(foo.toExponential(2));
}
例 4:如果我们不使用 test is string
(类型谓词),TypeScript 不会缩小受保护块中的类型,下面的示例代码不会出现编译错误,但会出现运行时错误。
function isString(test: any): boolean{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
console.log(foo.toExponential(2));
}
}
结论是 test is string
(类型谓词)在编译时用于告诉开发人员代码将有机会出现运行时错误。对于 javascript,开发人员不会知道编译时的错误。这就是使用 TypeScript 的优势。
boolean
来处理,对吧?is
关键字实际上是在转换类型,并且可以在稍后的代码中捕获类型错误。有关详细信息,请参阅 this example。true
对应于特定类型。if (pet is Fish){fish.swim()}
,而不是写function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; }; if (isFish(pet)){fish.swim()}
。