Trong bài viết này, chúng ta sẽ tìm hiểu về ba khái niệm quan trọng trong TypeScript: Intersection Types, Discriminated Unions và Type Guards and Differentiating Types.
Đây là những khái niệm nâng cao giúp chúng ta làm việc hiệu quả hơn với các loại dữ liệu trong TypeScript.
Intersection Types là một cách để kết hợp nhiều loại dữ liệu thành một loại. Điều này rất hữu ích khi bạn muốn tạo ra một loại dữ liệu mới từ các loại dữ liệu đã có.
Ví dụ:
type Name = {
name: string;
};
type Age = {
age: number;
};
type Person = Name & Age;
let person: Person = {
name: "John",
age: 30
};
Trong ví dụ trên, chúng ta đã tạo ra một loại mới Person
từ hai loại Name
và Age
bằng cách sử dụng Intersection Types.
Discriminated Unions là một cách để tạo ra một loại dữ liệu mới từ nhiều loại dữ liệu khác nhau, nhưng chỉ có thể chọn một trong số đó tại một thời điểm.
Ví dụ:
type Circle = {
kind: "circle";
radius: number;
};
type Square = {
kind: "square";
sideLength: number;
};
type Shape = Circle | Square;
let shape: Shape = {
kind: "circle",
radius: 5
};
Trong ví dụ trên, chúng ta đã tạo ra một loại mới Shape
từ hai loại Circle
và Square
bằng cách sử dụng Discriminated Unions.
Type Guards và Differentiating Types giúp chúng ta kiểm tra loại của một biến và thực hiện các hành động khác nhau dựa trên loại của biến đó.
Ví dụ (Sử dụng type Shape trong ví dụ trên):
function getArea(shape: Shape) {
if (shape.kind === "circle") {
return Math.PI * shape.radius ** 2;
} else {
return shape.sideLength ** 2;
}
}
Trong ví dụ trên, chúng ta đã sử dụng Type Guards để kiểm tra loại của shape
và tính diện tích tương ứng.
Conditional Types là một kỹ thuật cho phép chúng ta tạo ra các kiểu dữ liệu dựa trên điều kiện.
Ví dụ về Conditional Types:
type IsString<T> = T extends string ? true : false;
Trong ví dụ trên, IsString
là một kiểu dữ liệu dựa trên điều kiện. Nếu T
là string
, thì IsString<T>
sẽ là true
, ngược lại sẽ là false
.
Mapped Types cho phép chúng ta tạo ra một kiểu dữ liệu mới từ một kiểu dữ liệu đã có, bằng cách ánh xạ từng thuộc tính của kiểu dữ liệu cũ.
Ví dụ về Mapped Types:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
Trong ví dụ trên, Readonly<T>
là một kiểu dữ liệu mới, trong đó mỗi thuộc tính của T
đều được đánh dấu là readonly
.
Template Literal Types cho phép chúng ta tạo ra các kiểu dữ liệu dựa trên chuỗi mẫu.
Ví dụ về Template Literal Types:
type World = "world";
type Greeting = `Hello, ${World}`;
Trong ví dụ trên, Greeting
là một kiểu dữ liệu mới, được tạo ra từ chuỗi mẫu Hello, ${World}
.
Hy vọng qua bài học này, các bạn đã hiểu rõ hơn về các kỹ thuật nâng cao trong TypeScript. Hãy tiếp tục thực hành để nắm vững kiến thức nhé!