Các mẫu generic bạn hay dùng, nhóm theo công việc: khai báo tham số kiểu, ràng buộc nó, đặt giá trị mặc định, rẽ nhánh bằng conditional, bắt kiểu bằng infer, và ánh xạ qua một hình dạng. Mỗi dòng ghép một mẫu với một ví dụ một dòng.
Một generic là một tham số kiểu: một chỗ trống cho kiểu mà bên gọi chọn, nhờ đó một hàm hay một kiểu dùng được cho nhiều hình dạng mà không mất độ chính xác. Hãy đọc <T> là "với một kiểu T nào đó". Sức mạnh đến từ việc ràng buộc T, rẽ nhánh trên nó, và ánh xạ nó. Các mẫu dưới đây là vốn từ vựng để làm việc.
Bảng tham chiếu · 28 mục
Generic trong TypeScriptExplained
28 of 28 rows
Khai báo
Một tham số kiểu do bên gọi chọn.
function first<T>(xs: T[]): T
Nhiều tham số kiểu độc lập với nhau.
function pair<T, U>(a: T, b: U): [T, U]
Tham số thứ hai gắn với các khóa của tham số thứ nhất.
function get<T, K extends keyof T>(o: T, k: K): T[K]
Một lớp có tham số kiểu trên trường và phương thức của nó.
class Box<T> { value: T }
Một hình dạng đối tượng kèm tham số kiểu.
interface Result<T> { data: T }
Tham số kiểu trên hàm mũi tên; dấu phẩy cuối giúp file .tsx không đọc nó thành JSX.
const first = <T,>(xs: T[]): T => xs[0]
Ràng buộc
Yêu cầu T có thể gán cho Type.
function len<T extends { length: number }>(x: T)
Ràng buộc T vào một khóa của kiểu khác.
type Keys<O> = keyof O
Ràng buộc T vào một lớp có thể khởi tạo.
function make<C extends new () => C>(c: C): C
Yêu cầu T thỏa mãn nhiều ràng buộc cùng lúc.
function log<T extends Error & { code: number }>(e: T)
Ràng buộc vào bất kỳ thứ gì; giữ tham số ở dạng generic mà không thu hẹp nó.
type Wrap<T> = T extends unknown ? { v: T } : never
Mặc định & infer
Cho T một giá trị mặc định khi bên gọi bỏ qua.
function parse<T = string>(): T
Bắt một kiểu bên trong một conditional.
type El<T> = T extends Array<infer I> ? I : never
Mở Promise lồng nhau ra kiểu bên trong của nó.
type Data = Awaited<Promise<User>>
Bắt một mảnh của kiểu literal mẫu chuỗi.
type Path<S> = S extends `/api/${infer R}` ? R : never
Kiểm tra cả union cùng lúc; một T trần suy luận từng thành viên một.
type El<T> = [T] extends [Array<infer I>] ? I : never
Điều kiện & ánh xạ
Chọn một kiểu tùy theo T có thể gán cho U hay không.
type IsStr<T> = T extends string ? true : false
Dựng kiểu đối tượng mới bằng cách biến đổi từng khóa của T.
type Frozen<T> = { [K in keyof T]: Readonly<T[K]> }
Đối tượng có khóa là K và giá trị là V.
type Scores = Record<string, number>
Các generic dựng sẵn dẫn xuất từ các mẫu trên.
type Preview = Pick<User, "id" | "name">
Một T trần trước extends chạy một lần cho mỗi thành viên của union rồi ghép kết quả lại.
ToArray<'a' | 'b'> = 'a'[] | 'b'[]
Thêm hoặc bỏ modifier trên các khóa ánh xạ.
type Req<T> = { [K in keyof T]-?: T[K] }
Các khóa của một giá trị runtime, ở dạng kiểu.
const opts = { a: 1 }; type K = keyof typeof opts
Dựng kiểu chuỗi từ các kiểu chuỗi khác.
type Route = `/users/${string}`
Nối các kiểu tuple đầu với đuôi.
type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U]
Một kiểu có định nghĩa tham chiếu chính nó.
type Json = string | number | Json[] | { [k: string]: Json }
Kiểm tra một giá trị với một kiểu và giữ kiểu literal hẹp hơn của nó.
const c = { dark: "#000" } satisfies Record<string, string>
Giữ kiểu literal của bên gọi thay vì mở rộng nó (TS 5.0).