Chú thích (comment) trong TypeScript chính là chú thích của JavaScript: // cho phần còn lại của dòng và /* */ cho một khối. Chú thích khối bắt đầu bằng /** là chú thích tài liệu (JSDoc), được trình soạn thảo hiển thị khi bạn rê chuột lên thứ mà nó mô tả. Ngoài ra, TypeScript còn đọc một vài chú thích đặc biệt làm thay đổi cách trình biên dịch kiểm tra code.
Đầu ra:
212
Chú thích không ảnh hưởng đến chương trình. Chúng cũng không ảnh hưởng đến việc kiểm tra kiểu, trừ các chú thích chỉ thị được giới thiệu bên dưới.
Chú thích một dòng và chú thích khối
// biến mọi thứ phía sau nó trên dòng thành chú thích, đây cũng là cách nhanh để tạm tắt một dòng code. /* */ có thể nằm giữa một dòng hoặc bao nhiều dòng.
Chú thích khối không lồng nhau được. Dấu */ đầu tiên kết thúc chú thích, nên bao một đoạn code đã có sẵn chú thích khối sẽ gây lỗi:
/* outer comment /* inner comment */ this text is now code */
Trình biên dịch khi đó cố đọc this text is now code */ như code và báo lỗi cú pháp. Để biến một vùng có chứa chú thích khối thành chú thích, hãy dùng // cho từng dòng; hầu hết trình soạn thảo làm việc này bằng Ctrl+/ (Cmd+/ trên macOS).
Chú thích tài liệu JSDoc
Một chú thích /** ... */ đặt ngay trước hàm, class, phương thức, thuộc tính, interface hoặc biến sẽ mô tả thứ đó. Trình soạn thảo hiển thị nội dung của nó trong tooltip khi rê chuột và trong gợi ý tự động hoàn thành, còn các công cụ tạo tài liệu như TypeDoc biến nó thành các trang tham khảo. TSDoc, một chuẩn cho loại chú thích này trong code TypeScript do Microsoft khởi xướng, dùng cùng cú pháp cho các tag phổ biến:
| Tag | Ý nghĩa |
|---|---|
@param name description | Mô tả một tham số |
@returns description | Mô tả giá trị trả về |
@throws description | Mô tả một lỗi mà hàm có thể ném ra |
@example | Mở đầu một khối ví dụ, thường theo sau là một khối code |
@deprecated reason | Đánh dấu một API đã lỗi thời; trình soạn thảo vẽ nó |
@see hoặc {@link Name} | Trỏ đến code liên quan |
@remarks | Phần giải thích dài hơn sau dòng tóm tắt |
Trong tệp .ts, đừng lặp lại kiểu trong JSDoc. Chú thích kiểu trong code mới là kiểu thật, và tag kiểu của JSDoc bị bỏ qua ở đó: /** @type {string} */ const v: number = 5; biên dịch không một lời phàn nàn vì chỉ : number được tính.
Trong trình soạn thảo, rê chuột lên transfer hoặc balance ở bất kỳ đâu trong dự án sẽ hiện các mô tả này.
Đánh dấu code đã lỗi thời
@deprecated không gây lỗi biên dịch. Nó báo cho trình soạn thảo hiển thị mọi chỗ dùng hàm lỗi thời với nét gạch ngang và lý do khi rê chuột, một cách nhẹ nhàng để hướng người gọi sang hàm thay thế:
Đầu ra:
$19.99
19.99 EUR
@ts-expect-error và @ts-ignore
Hai chú thích này tắt lỗi kiểu ở dòng ngay sau nó. Đôi khi đó là lựa chọn đúng: một bài test kiểm tra cách hàm xử lý đầu vào sai khi chạy, hoặc một chỗ thiếu sót đã biết trong kiểu của một thư viện.
Đầu ra:
runtime error: text.toUpperCase is not a function
Không có chú thích này, shout(42) là lỗi biên dịch (TS2345). Có nó, tệp biên dịch được và lời gọi đi đến lúc chạy, đó chính là mục đích của bài test này.
Khác biệt giữa hai chỉ thị lộ ra khi lỗi biến mất. @ts-expect-error đòi phải có lỗi để tắt, nên một chú thích lỗi thời tự nó trở thành lỗi:
index.ts(6,1): error TS2578: Unused '@ts-expect-error' directive.
// @ts-ignore ở cùng vị trí thì im lặng, cả khi lỗi còn và sau khi lỗi đã hết. Vì vậy @ts-expect-error là lựa chọn mặc định tốt hơn: khi ai đó sửa kiểu, trình biên dịch báo cho bạn biết có thể bỏ chỗ tắt lỗi đi. Luôn thêm lý do sau chỉ thị, như trong ví dụ trên, để người đọc sau biết vì sao nó ở đó.
Cả hai chỉ áp dụng cho dòng tiếp theo và mọi lỗi trên dòng đó. Khi cần thoát kiểm tra cho cả một giá trị, một phép as unknown as T tường minh hoặc một phép kiểm tra lúc chạy thường rõ ràng hơn chú thích tắt lỗi.
@ts-nocheck và @ts-check
// @ts-nocheck ở đầu tệp tắt kiểm tra kiểu cho cả tệp đó. Nó phải đứng đầu, trước mọi dòng code: đặt ở phía dưới thì nó bị bỏ qua và lỗi vẫn xuất hiện.
// @ts-nocheck
const n: number = "not a number"; // no error reported
Nó hữu ích khi chuyển đổi một codebase JavaScript lớn, và là dấu hiệu code có vấn đề ở mọi chỗ khác.
// @ts-check làm điều ngược lại trong tệp JavaScript: nó bật kiểm tra kiểu cho tệp .js đó, dựa vào suy luận kiểu và kiểu JSDoc, kể cả khi checkJs đang tắt trong tsconfig.json (tệp vẫn phải thuộc dự án, thông qua allowJs):
// @ts-check
/**
* @param {number} cents
* @returns {string}
*/
function formatCents(cents) {
return (cents / 100).toFixed(2);
}
formatCents("12"); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
Trong tệp JavaScript, các tag JSDoc chính là kiểu, và đó là cách nhiều dự án có kiểm tra kiểu mà không cần chuyển tệp sang .ts.
Chỉ thị ba gạch chéo
Một chú thích dạng /// <reference ... /> ở ngay đầu tệp là một chỉ thị cho trình biên dịch:
/// <reference types="node" />
/// <reference lib="es2023.array" />
/// <reference path="./globals.d.ts" />
types="node"thêm một package@typesvào chương trình, giống như liệt kê nó trong"types"củatsconfig.json.lib="..."thêm một thư viện có sẵn vào chương trình, giống như tùy chọnlib.path="..."đưa thêm một tệp khác vào, chủ yếu dùng trong tệp.d.ts.
Trong code ứng dụng, câu lệnh import và các thiết lập trong tsconfig.json thay thế gần như mọi cách dùng; bạn chủ yếu gặp các chỉ thị này trong tệp khai báo và code được sinh tự động như vite-env.d.ts của Vite. Để minh họa nhanh, lib cho phép dùng một phương thức mảng mới hơn trong tệp này:
Chú thích trong kết quả biên dịch
tsc giữ chú thích trong JavaScript mà nó sinh ra. Đặt "removeComments": true để bỏ chúng; chú thích bắt đầu bằng /*! vẫn được giữ lại kể cả khi đó, theo quy ước dành cho phần thông tin giấy phép:
/*! MyLib v1.2.0 | MIT License */
Chú thích JSDoc cũng được chép vào tệp .d.ts khi bật declaration, nên người dùng thư viện thấy được các mô tả ngay trong trình soạn thảo.
Câu hỏi thường gặp
Viết chú thích trong TypeScript như thế nào?
Giống như trong JavaScript: // bắt đầu một chú thích kéo dài đến hết dòng, còn /* ... */ bao một chú thích có thể trải trên nhiều dòng. Chú thích khối bắt đầu bằng /** là chú thích tài liệu (JSDoc), được trình soạn thảo hiển thị khi bạn rê chuột lên hàm, class hoặc thuộc tính được mô tả.
@ts-ignore và @ts-expect-error khác nhau thế nào?
Cả hai đều tắt lỗi kiểu ở dòng tiếp theo. // @ts-expect-error còn kiểm tra rằng ở đó thật sự có lỗi: nếu dòng đó hết lỗi, trình biên dịch báo error TS2578: Unused '@ts-expect-error' directive., nhờ vậy những chỗ tắt lỗi đã lỗi thời sẽ bị phát hiện. // @ts-ignore thì im lặng mãi mãi. Nên ưu tiên @ts-expect-error.
Làm sao để bỏ qua lỗi TypeScript trong cả một tệp?
Đặt // @ts-nocheck ở đầu tệp, trước mọi dòng code. Khi đó trình biên dịch không báo lỗi kiểu nào cho tệp đó (lỗi cú pháp vẫn xuất hiện). Đây là công cụ dùng khi chuyển đổi dự án; với một dòng đơn lẻ, hãy dùng // @ts-expect-error.
Chú thích có nằm lại trong JavaScript sau khi biên dịch không?
Có, mặc định tsc giữ chú thích trong kết quả. Với "removeComments": true, nó bỏ chúng đi, trừ các chú thích bắt đầu bằng /*!, được giữ lại cho phần thông tin giấy phép. Bundler và minifier thường xóa chúng trong bản build production.
Có nên viết kiểu trong chú thích JSDoc ở tệp .ts không?
Không. Trong tệp .ts, các tag kiểu của JSDoc như @type {string} hay @param {number} x bị bỏ qua khi kiểm tra kiểu; chú thích kiểu trong code mới là kiểu thật. Trong tệp .ts, hãy dùng JSDoc để mô tả, và chỉ dùng kiểu JSDoc trong tệp .js được kiểm tra bằng // @ts-check hoặc checkJs.