我遇到了一些看起来像这样的代码:
export function foo(arg: string): arg is MyType { return ... }
我无法is在 docs 或 google 中搜索,这是一个非常常见的词,并且基本上出现在每个页面上。
is
关键字在这种情况下有什么作用?
有关更多信息,请参阅用户定义的类型保护函数的参考。
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用于返回类型), afterisString()被调用,如果函数返回true, TypeScript 会将类型缩小到string由函数调用保护的任何块中。 编译器会认为它foo位于string保护之下的块中(并且仅在保护之下的块中)
test is string
boolean
isString()
true
string
foo
{ console.log("it is a string" + foo); console.log(foo.length); // string function }
类型谓词仅在编译时使用。结果.js文件(运行时)将没有区别,因为它不考虑 TYPE。
.js
我将在以下四个示例中说明差异。
例如1:上面的示例代码不会出现编译错误或运行时错误。
例如 2:下面的示例代码将出现编译错误(以及运行时错误),因为 TypeScript 已将类型缩小到string并检查了toExponential不属于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)); } }
例如 3:下面的示例代码没有编译错误,但会出现运行时错误,因为 TypeScript 只会将类型缩小到string受保护的块中而不是之后,因此foo.toExponential不会产生编译错误(TypeScript 认为它不是string类型)。但是,在运行时,string没有该toExponential方法,因此会出现运行时错误。
foo.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 的优势。