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");
在调用isString()之后,使用上述格式的类型谓词test is string(而不是只对返回类型使用boolean),如果函数返回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 的优势。