【发布时间】:2017-02-26 03:20:01
【问题描述】:
我遇到了一些看起来像这样的代码:
export function foo(arg: string): arg is MyType {
return ...
}
我无法在 docs 或 google 中搜索 is,这是一个非常常见的词,并且基本上出现在每个页面上。
关键字在这种情况下的作用是什么?
【问题讨论】:
标签: typescript
我遇到了一些看起来像这样的代码:
export function foo(arg: string): arg is MyType {
return ...
}
我无法在 docs 或 google 中搜索 is,这是一个非常常见的词,并且基本上出现在每个页面上。
关键字在这种情况下的作用是什么?
【问题讨论】:
标签: typescript
有关更多信息,请参阅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会缩小在由函数调用保护的任何块中键入string。
编译器会认为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()}。