TypeScript - Các Loại Điều Kiện

Xin chào, các pháp sư TypeScript tương lai! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của Các Loại Điều Kiện. Đừng lo lắng nếu bạn mới bắt đầu học lập trình - tôi sẽ là người hướng dẫn thân thiện của bạn, và chúng ta sẽ cùng nhau bước qua từng bước. Cuối bài học này, bạn sẽ ngạc nhiên về bao nhiêu điều bạn đã học được!

TypeScript - Conditional Types

Các Loại Điều Kiện Cơ Bản

Hãy bắt đầu từ những điều cơ bản. Các Loại Điều Kiện trong TypeScript giống như việc đưa ra quyết định trong mã của bạn. Hãy tưởng tượng bạn đang ở một cửa hàng kem, và bạn phải quyết định giữa chocolate và vanilla dựa trên việc liệu ngày hôm nay có nóng hay không. Đó chính là điều mà Các Loại Điều Kiện trong TypeScript làm!

Dưới đây là một ví dụ đơn giản:

type IceCreamChoice = boolean extends true ? "Chocolate" : "Vanilla";

Trong đoạn mã này, chúng ta đang nói: "Nếu boolean (đại diện cho true hoặc false) có thể là true, thì chọn Chocolate; ngược lại, chọn Vanilla."

Nhưng đợi đã, boolean luôn có thể là true, phải không? Vậy hãy làm cho ví dụ này thực tế hơn:

type WeatherChoice<T> = T extends "Hot" ? "Ice Cream" : "Hot Chocolate";

let summerChoice: WeatherChoice<"Hot"> = "Ice Cream";
let winterChoice: WeatherChoice<"Cold"> = "Hot Chocolate";

Ở đây, chúng ta đã tạo một loại WeatherChoice nhận một tham số loại T. Nếu T mở rộng (hoặc khớp với) "Hot", chúng ta chọn "Ice Cream"; ngược lại, chúng ta chọn "Hot Chocolate".

Các Loại Điều Kiện Nhiều Năng

Bây giờ, hãy nâng cấp! Các Loại Điều Kiện Nhiều Năng cho phép chúng ta làm cho các loại của mình linh hoạt và có thể tái sử dụng hơn. Hãy tưởng tượng như tạo một máy làm kem siêu linh hoạt có thể làm ra nhiều hương vị dựa trên những gì bạn cho vào.

type IsArray<T> = T extends any[] ? true : false;

type CheckString = IsArray<string>;  // false
type CheckNumberArray = IsArray<number[]>;  // true

Trong ví dụ này, IsArray là một loại generic kiểm tra xem loại đầu vào T có phải là một mảng hay không. Nếu có, nó trả về true; ngược lại, nó trả về false.

Hãy thử một điều gì đó phức tạp hơn:

type ElementType<T> = T extends (infer U)[] ? U : never;

type StringArrayElement = ElementType<string[]>;  // string
type NumberArrayElement = ElementType<number[]>;  // number
type NotArrayElement = ElementType<number>;  // never

Ở đây, ElementType trích xuất loại của các phần tử trong một mảng. Nếu T là một mảng, nó suy luận loại phần tử U và trả về nó. Nếu T không phải là một mảng, nó trả về never (tức là "điều này không bao giờ xảy ra").

Ràng Buộc Các Loại Điều Kiện

Đôi khi, chúng ta muốn đặt một số ràng buộc lên các loại của mình. Điều này giống như nói, "Bạn chỉ có thể ăn kem nếu đã ăn hết rau của mình!" Hãy xem điều này hoạt động như thế nào trong TypeScript:

type NumberOperation<T extends number> = T extends 0 ? "Zero" : "Non-zero";

type ZeroCheck = NumberOperation<0>;  // "Zero"
type NonZeroCheck = NumberOperation<5>;  // "Non-zero"
type InvalidCheck = NumberOperation<"5">;  // Lỗi: Type '"5"' does not satisfy the constraint 'number'.

Trong ví dụ này, NumberOperation chỉ chấp nhận các loại mở rộng number. Nó sau đó kiểm tra nếu số là 0 hay không.

suy luận trong Các Loại Điều Kiện

Cuối cùng, hãy nói về suy luận trong các loại điều kiện. Điều này giống như có một máy làm kem siêu thông minh có thể đoán ra hương vị bạn muốn dựa trên tâm trạng của bạn!

type Flatten<T> = T extends Array<infer U> ? U : T;

type FlattenedNumberArray = Flatten<number[]>;  // number
type FlattenedString = Flatten<string>;  // string

Ở đây, Flatten kiểm tra nếu T là một mảng. Nếu có, nó suy luận loại phần tử U và trả về nó. Nếu không, nó trả về T như cũ.

Hãy thử một điều gì đó phức tạp hơn:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function greet(name: string): string {
return `Hello, ${name}!`;
}

type GreetReturn = ReturnType<typeof greet>;  // string

Trong ví dụ này, ReturnType suy luận loại trả về của một hàm. Nó kiểm tra nếu T là một loại hàm, và nếu vậy, nó suy luận và trả về loại trả về R.

Kết Luận

Chúc mừng! Bạn đã chính thức bước những bước đầu tiên vào thế giới của Các Loại Điều Kiện trong TypeScript. Nhớ rằng, giống như học骑自行车, có thể sẽ cảm thấy không vững chắc ban đầu, nhưng với sự luyện tập, bạn sẽ nhanh chóngzoom xung quanh!

Dưới đây là bảng tóm tắt các phương pháp chúng ta đã bao gồm:

Phương Pháp Mô Tả
Các Loại Điều Kiện Cơ Bản Làm ra quyết định dựa trên điều kiện
Các Loại Điều Kiện Nhiều Năng Tạo các loại linh hoạt, có thể tái sử dụng
Ràng Buộc Các Loại Điều Kiện Đặt ràng buộc lên các loại đầu vào
Suy Luận trong Các Loại Điều Kiện Trích xuất và suy luận các loại trong điều kiện

Tiếp tục luyện tập, 保持好奇心, và trước khi bạn biết, bạn sẽ tạo ra những điều tuyệt vời với TypeScript. Chúc mừng coding, các master TypeScript tương lai!

Credits: Image by storyset