Type alias đặt tên cho một kiểu. Bạn viết type Name = ..., và từ đó trở đi Name dùng được ở bất cứ đâu cần một kiểu. Khác với interface, alias có thể đặt tên cho bất kỳ kiểu nào, không chỉ hình dạng đối tượng.
Alias chỉ tồn tại lúc biên dịch. JavaScript được xuất ra không chứa dòng type nào trong số này.
Cú pháp
type Name = SomeType;
type Name<T> = SomeTypeUsing<T>; // generic
export type Name = SomeType; // exported from a module
Theo quy ước, tên được viết theo kiểu PascalCase. Vế phải là một biểu thức kiểu bất kỳ, và một alias có thể dùng các alias khác, kể cả chính nó (xem phần kiểu đệ quy bên dưới). Alias dùng được trong toàn bộ phạm vi nơi nó được khai báo, kể cả phía trên dòng khai báo, vì kiểu được kiểm tra lúc biên dịch chứ không được thực thi theo thứ tự như const hay let.
Kiểu đối tượng
Với hình dạng đối tượng, alias và interface được viết gần như giống nhau. Alias dùng = và thường kết thúc bằng dấu chấm phẩy.
Alias không dùng được extends; phép giao & đảm nhận vai trò đó. Việc kiểm tra thuộc tính thừa, thuộc tính tùy chọn và readonly hoạt động y hệt như với interface. Nên chọn cái nào cho hình dạng đối tượng được bàn trong trang interface và type.
Union, tuple và hàm
Đây là những trường hợp chỉ alias mới đặt tên được, và là lý do chính để type tồn tại. Một alias union liệt kê các lựa chọn, một alias tuple cố định độ dài và kiểu phần tử của mảng, còn một alias hàm mô tả một chữ ký hàm.
Trong scale, các tham số không cần chú thích kiểu: alias Transform đã cung cấp kiểu cho chúng. Cú pháp tuple được trình bày trong trang tuple, còn việc thu hẹp union nằm trong trang union type.
Type alias generic
Tham số kiểu giúp một alias dùng được cho nhiều kiểu. Chúng có thể có giá trị mặc định, giống như tham số của hàm.
Result<number> dùng giá trị mặc định E = string. Những alias generic nhỏ như type Nullable<T> = T | null hay type Dict<T> = Record<string, T> rất phổ biến trong code thực tế. Các utility type dựng sẵn (Partial<T>, Pick<T, K>, ReturnType<F>) cũng là alias generic, được khai báo trong thư viện chuẩn.
Alias là tên, không phải kiểu mới
Alias không tạo ra một kiểu riêng biệt. Nó là tên thứ hai cho kiểu ở vế phải, và trình biên dịch coi hai thứ là một. Hai alias của string hoàn toàn dùng thay cho nhau được:
Đoạn code này in ra cancelling u_42 mà không có lỗi nào, và đó chính là bug mà alias không ngăn được. Alias vẫn giúp người đọc (một tham số có kiểu OrderId nói được nhiều hơn string), nhưng nếu việc nhầm lẫn hai id phải là lỗi biên dịch, hãy dùng branded type như string & { readonly __brand: "OrderId" }.
Type alias đệ quy
Alias có thể tham chiếu tới chính nó, đó là cách bạn mô tả cây, danh sách lồng nhau và JSON:
Alias Json từ chối những giá trị mà JSON không biểu diễn được: gán { when: new Date() } hay { f: undefined } cho Json đều là lỗi biên dịch (TS2322).
Kiểu từ giá trị: typeof
Khi đã có sẵn một giá trị, bạn có thể đặt tên cho kiểu của nó thay vì viết lại. Toán tử kiểu typeof đọc kiểu của một biến, và có thể kết hợp với các toán tử khác:
const defaults = { retries: 3, verbose: false, level: "info" };
type Options = typeof defaults;
// { retries: number; verbose: boolean; level: string }
type OptionKey = keyof typeof defaults;
// "retries" | "verbose" | "level"
function start(port: number) {
return { port, startedAt: new Date() };
}
type Server = ReturnType<typeof start>;
// { port: number; startedAt: Date }
Giá trị vẫn là nguồn dữ liệu duy nhất: thêm một thuộc tính vào defaults thì Options tự cập nhật theo. Xem thêm ở trang typeof.
Export và import alias
Alias được export và import giống như giá trị. import type cho thấy rõ chỉ có kiểu được import, nên lệnh import luôn bị loại khỏi đầu ra JavaScript:
// shapes.ts
export type Point = { x: number; y: number };
export type Shape = { kind: "circle"; center: Point; radius: number };
// main.ts
import type { Point, Shape } from "./shapes.js";
const p: Point = { x: 1, y: 2 };
Câu hỏi thường gặp
Type alias trong TypeScript là gì?
Type alias là một cái tên cho một kiểu, được khai báo bằng từ khóa type: type Point = { x: number; y: number }. Sau đó, Point dùng được ở bất cứ đâu cần một kiểu. Alias có thể đặt tên cho mọi kiểu: hình dạng đối tượng, union, tuple, chữ ký hàm, kiểu nguyên thủy hay kiểu generic.
Type alias có tạo ra kiểu mới không?
Không. Alias chỉ là một tên khác cho một kiểu đã có. Với type UserId = string và type OrderId = string, một UserId có thể được truyền vào nơi cần OrderId, vì cả hai đều chỉ là string. Để tạo các kiểu không dùng thay cho nhau được, hãy dùng branded type.
Type alias có thể tham chiếu tới chính nó không?
Có, miễn là phần tự tham chiếu nằm lồng bên trong một kiểu đối tượng, một mảng hoặc một tuple: type TreeNode = { value: number; children: TreeNode[] } và một alias Json có chứa Json[] đều hoạt động. Một tham chiếu trần như type Loop = Loop | string là lỗi TS2456, Type alias 'Loop' circularly references itself.
Type alias có thể là generic không?
Có. Đặt tham số kiểu sau tên: type Box<T> = { value: T }, rồi dùng như Box<number>. Tham số có thể có giá trị mặc định (type Result<T, E = string> = ...) và ràng buộc (type Keys<T extends object> = keyof T).
Làm sao để lấy kiểu từ một đối tượng có sẵn?
Dùng toán tử kiểu typeof: const defaults = { retries: 3, verbose: false }; type Options = typeof defaults; cho ra { retries: number; verbose: boolean }. Cách này giữ một nguồn dữ liệu duy nhất khi giá trị có trước.