lbp的blog

纸上得来终觉浅,绝知此事要躬行

0%

typescript关键字

详解ts关键字,目前包含以下关键字

  • as
  • is

as

as 关键字用来直接告诉编译器,把某个对象看做某个固定类型。

应用场景:

  • ts可以看做是强类型语言。如果在上下文中,不能够推断出类型,贸然使用一些对象方法可能会报错。
    1
    2
    3
    4
    // https://github.com/vuejs/vue-next/blob/3ea85c116836d1cf6fb8b7503dc9c269bbf9f113/packages/reactivity/src/reactive.ts#L212
    export function isReadonly(value: unknown): boolean {
    return !!(value && (value as Target)[ReactiveFlags.IS_READONLY])
    }

is

is 在ts中被称作type predicate(类型谓词)

谓词,用来代替或者展示其客体性质、特征或者客体之间关系的词项。
特点:用来描述或者判断客体性质
“猫是动物”中的是就是谓词,猫是客体
百度百科-谓词

在计算机语言的环境下,谓词是指条件表达式的求值返回真或假的过程。

ps:多种语言都谓词的使用。比如OC的NSPredicate、java的Predicate接口

如何使用
在定义的函数中返回 type predicate,如下所示:

1
2
3
4
5
6
7
8
// 使用type predicate
function isString(test: any): test is string{
return typeof test === "string";
}
// 不使用type predicate,直接使用boolean作为返回值
function isString(test: any): boolean{
return typeof test === "string";
}

总结来看,语法是:parameterName is Type,需要注意的是,parameterName必须是方法中的参数名称

A predicate takes the form parameterName is Type, where parameterName must be the name of a parameter from the current function signature.

user-defined-type-guards

type predicate的作用:编译器在编译阶段,把变量缩小为特定类型,发现一些运行时可能出现的错误。

1
2
3
4
5
6
7
8
9
10
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);
console.log(foo.toExponential(2)); // Property 'toExponential' does not exist on type 'string'.(2339)
}
}

上面的例子 foo.toExponential 在编译阶段和运行时都会报错。
下面的例子在编译阶段不会报错,但是运行时会报错。

1
2
3
4
5
6
7
8
9
10
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);
}
console.log(foo.toExponential(2));
}

这是因为,ts缩小foo类型为string,仅仅是在代码块中(TypeScript will ONLY narrow the type to string in the block guarded but not after)。

参考

What does the is keyword do in typescript?
user-defined-type-guards