Nhảy tới nội dung

noImplicitThis

noImplicitThis là compiler option bắt buộc type annotation cho this.

  • Mặc định: true nếu strict được bật, ngược lại là false
  • Phiên bản thêm vào: 2.0
  • TypeScript khuyến nghị nên bật

Giải thích

Named function và anonymous function khác với arrow function ở chỗ this được xác định tại runtime. Do đó, khi sử dụng this bên trong, chúng được xem như có type any tại thời điểm viết function.

Ví dụ, xét function lengthOfDiagonal() tính độ dài đường chéo. Nếu (ngang, dọc) là (width, height) thì function sẽ như sau:

ts
function lengthOfDiagonal(): number {
return (this.width ** 2 + this.height ** 2) ** (1 / 2);
}
ts
function lengthOfDiagonal(): number {
return (this.width ** 2 + this.height ** 2) ** (1 / 2);
}

Gán function này vào instance của object có property width, height thì có thể tính độ dài đường chéo:

ts
const area = {
width: 3,
height: 4,
diagonal: lengthOfDiagonal,
};
 
console.log(area.diagonal());
5
ts
const area = {
width: 3,
height: 4,
diagonal: lengthOfDiagonal,
};
 
console.log(area.diagonal());
5

Nếu nhầm lẫn gõ width thành witch thì function này sẽ không trả về kết quả như mong muốn:

ts
const area = {
witch: 3,
height: 4,
diagonal: lengthOfDiagonal,
};
 
console.log(area.diagonal());
NaN
ts
const area = {
witch: 3,
height: 4,
diagonal: lengthOfDiagonal,
};
 
console.log(area.diagonal());
NaN

Khi bật option này, this đang bị nhận dạng là type any sẽ không thể thực thi được trừ khi làm rõ type của nó:

ts
function lengthOfDiagonal(): number {
return (this.width ** 2 + this.height ** 2) ** (1 / 2);
'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.
2683
2683
'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.
}
ts
function lengthOfDiagonal(): number {
return (this.width ** 2 + this.height ** 2) ** (1 / 2);
'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.
2683
2683
'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.
}

Để tránh lỗi này, phải chỉ rõ this là gì. Chi tiết về this parameter có ở trang function, vui lòng tham khảo:

📄️ Tham số this

Tham số đầu tiên của function (ngoài arrow function) và method của class có thể nhận tham số đặc biệt là this. Vì ý nghĩa của this thay đổi tùy theo context sử dụng, nên điều này được dùng để cho TypeScript biết function này nên được sử dụng trong context nào. Khi gọi, caller không cần quan tâm đến this này. Chỉ cần chỉ định từ tham số thứ hai trở đi.

ts
type Area = {
width: number;
height: number;
diagonal(): number;
};
 
function lengthOfDiagonal(this: Area): number {
return (this.width ** 2 + this.height ** 2) ** (1 / 2);
}
 
const area: Area = {
width: 3,
height: 4,
diagonal: lengthOfDiagonal,
};
ts
type Area = {
width: number;
height: number;
diagonal(): number;
};
 
function lengthOfDiagonal(this: Area): number {
return (this.width ** 2 + this.height ** 2) ** (1 / 2);
}
 
const area: Area = {
width: 3,
height: 4,
diagonal: lengthOfDiagonal,
};