TypeScript函数this值的类型

this是JavaScript中的关键字,它可以表示调用函数的对象或者实例对象等。本文为朋友们介绍函数声明和函数表达式中this值的类型。

在默认情况下,编译器会将函数中的this值设置为any类型,并允许程序在this值上执行任意的操作。因为,编译器不会对any类型进行类型检查。例如,下例中在this值上的所有访问操作都是允许的:

function f() {
   // 以下语句均没有错误
   this.a = true;
   this.b++;
   this.c = () => {};
}

将this值的类型设置为any类型对类型检查没有任何帮助。因此,TypeScript提供了一个“--noImplicitThis”编译选项。当启用了该编译选项时,如果this值默认获得了any类型,那么将产生编译错误;如果函数体中没有引用this值,则没有任何影响。

/**
* --noImplicitThis=true
*/
function f0() {
   this.a = true;     // 编译错误
   this.b++;          // 编译错误
   this.c = () => {}; // 编译错误
}

// 没有错误
function f1() {
   const a = true;
}

函数中this值的类型可以通过一个特殊的this参数来定义。

函数的this参数

TypeScript支持在函数形式参数列表中定义一个特殊的this参数来描述该函数中this值的类型。示例如下:

function foo(this: { name: string }) {
   this.name = 'Patrick';

   this.name = 0;
//  ~~~~~~~~~
//  编译错误!类型 0 不能赋值给类型 'string'
}

this参数固定使用this作为参数名。this参数是一个可选的参数,若存在,则必须作为函数形式参数列表中的第一个参数。this参数的类型即为函数体中this值的类型。

this参数不同于常规的函数形式参数,它只存在于编译阶段,在编译生成的JavaScript代码中会被完全删除,在运行时的代码中不存在这个this参数。

如果我们想要定义一个纯函数或者是不想让函数代码依赖于this的值,那么在这种情况下可以明确地将this参数定义为void类型。这样做之后,在函数体中就不允许读写this的属性和方法。示例如下:

function add(this: void, x: number, y: number) {
   this.name = 'Patrick';
   //   ~~~~
   //   编译错误:属性 'name' 不存在于类型 'void'
}

当调用定义了this参数的函数时,若this值的实际类型与函数定义中的期望类型不匹配,则会产生编译错误。示例如下:

function foo(this: { bar: string }, baz: number) {
   // ...
}

// 编译错误
// 'this'类型为'void',不能赋值给 '{ bar: string }' 类型的this
foo(0);

foo.call({ bar: 'hello' }, 0); // 正确

第1行,将foo函数this值的类型设置为对象类型“{ bar: string }”

第7行,调用foo函数时this值的类型为void类型,它与期望的类型不匹配,因此产生编译错误。

第9行,在调用foo函数时指定了this值为“{ bar: 'hello' }”,其类型符合this参数的类型定义,因此不会产生错误。“Function.prototype.call()”方法是JavaScript内置的方法,它能够指定调用函数时使用的this值。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!