- vừa được xem lúc

Blog#55: Sử dụng TypeScript Mapped một cách chuyện nghiệp 😊 (Series: Bón hành TypeScript - PHẦN 5)

0 0 16

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

Mình là TUẤN hiện đang là một Full-stack Web Developer tại Tokyo 😊. Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😉.

Chào mừng bạn đến với loạt bài Làm chủ TypeScript. Được nằm trong Series BÓN HÀNH TYPESCRIPT, những bài viết này sẽ giới thiệu về kiến ​​thức và kỹ thuật cốt lõi của TypeScript dưới dạng Animations sinh động.

OK GÉT GÔ

Vấn đề

Bạn đã sử dụng Partial, Required, Readonly, and Pick utility types chưa?

Nếu bạn muốn làm chủ chúng một cách thuần thục và tạo ra các utility types cho riêng mình thì đừng bỏ qua nội dung được đề cập trong bài viết này.

Tạo một type User là một kịch bản phổ biến trong công việc hàng ngày. Ở đây, chúng ta có thể sử dụng TypeScript để xác định loại User trong đó tất cả các khóa được yêu cầu.

type User = { name: string; password: string; address: string; phone: string;
};

Thông thường, đối với Type User đã được khai báo, chúng ta chỉ cho phép sửa đổi một số thông tin. Tại thời điểm này, chúng ta có thể xác định một loại UserPartial mới đại diện cho loại đối tượng User cần cập nhật, trong đó tất cả các khóa là tùy chọn.

type UserPartial = { name?: string; password?: string; address?: string; phone?: string; };

Đối với kịch bản xem thông tin user, chúng ta hy vọng rằng tất cả các khóa trong loại đối tượng tương ứng với đối tượng user đều ở chế độ chỉ đọc (Readonly). Đối với yêu cầu này, chúng ta có thể xác định loại User chỉ đọc.

type ReadonlyUser = { readonly name: string; readonly password: string; readonly address: string; readonly phone: string;
};

Xem lại ba Type liên quan đến user đã được xác định, bạn sẽ thấy rằng chúng chứa rất nhiều code trùng lặp.

Vậy làm cách nào để có thể giảm bớt code trùng lặp trong các loại trên? Câu trả lời là bạn có thể sử dụng các Mapped Types, là các Type chung có thể được sử dụng để ánh xạ loại đối tượng ban đầu sang loại đối tượng mới.

Mapped Type

Cú pháp cho các loại ánh xạ như sau:

Trường hợp P in K tương tự như câu lệnh in trong JavaScript, được sử dụng để lặp qua tất cả các loại trong loại K và biến loại T, được sử dụng để biểu thị bất kỳ loại nào trong TypeScript.

Bạn cũng có thể sử dụng các cú pháp sửa đổi bổ sung chỉ đọc và dấu chấm hỏi (?) trong quá trình mapping. Các cú pháp sửa đổi tương ứng được thêm vào và loại bỏ bằng cách thêm các tiền tố dấu cộng(+) và dấu trừ(-). Mặc định là sử dụng dấu cộng nếu không thêm tiền tố.

Bây giờ chúng ta có thể tóm tắt cú pháp của các loại Mapping phổ biến.

{ [ P in K ] : T }
{ [ P in K ] ?: T }
{ [ P in K ] -?: T }
{ readonly [ P in K ] : T }
{ readonly [ P in K ] ?: T }
{ -readonly [ P in K ] ?: T }

Sau khi xem cú pháp của các loại Mapped Types, giờ hãy đến một số ví dụ.

Hãy xem cách xác định lại loại UserPartial bằng cách sử dụng các Mapped Types.

type MyPartial<T> = { [P in keyof T]?: T[P];
};
type UserPartial = MyPartial<User>;

Trong đoạn code trên, chúng ta xác định Mapped Types MyPartial và sau đó sử dụng nó để ánh xạ loại User thành loại UserPartial. Toán tử keyof được sử dụng để lấy tất cả các khóa của một loại và kiểu trả về của nó là kiểu kết hợp. Biến loại P thay đổi thành một loại khác với mỗi lần duyệt, T[P], tương tự như cú pháp truy cập Properties và được sử dụng để lấy loại value tương ứng với một Properties của loại đối tượng.

Hãy xem ảnh minh họa quy trình thực thi hoàn chỉnh của Mapped Types MyPartial, nếu chưa rõ, bạn có thể xem nhiều lần để hiểu sâu hơn về Mapped Types TypeScript.

TypeScript 4.1 cho phép chúng ta ánh xạ lại các khóa trong các Mapped Types bằng mệnh đề as. Cú pháp của nó như sau:

type MappedTypeWithNewKeys<T> = { [K in keyof T as NewKeyType]: T[K] // ^^^^^^^^^^^^^ // New Syntax!
}

Trong đó loại NewKeyType phải là một kiểu con của string | number | symbol union type. Sử dụng mệnh đề as, chúng ta có thể xác định Getters utility type và tạo ra loại Getter tương ứng cho loại đối tượng.

type Getters<T> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};
interface Person { name: string; age: number; location: string;
}
type LazyPerson = Getters<Person>;
// {
// getName: () => string;
// getAge: () => number;
// getLocation: () => string;
// }

Trong đoạn code trên, vì loại được trả về bởi keyof T có thể chứa kiểu ký hiệu (Symbol type) và kiểu Viết hoa chữ cái đầu (Capitalize utility). Nó yêu cầu kiểu được xử lý cần phải là một kiểu con của loại string, nên cần phải lọc kiểu bằng toán tử &.

Ngoài ra, trong quá trình Mapping lại các Keys, chúng ta có thể lọc các Keys bằng cách trả về never type.

// Remove the 'kind' property
type RemoveKindField<T> = { [K in keyof T as Exclude<K, "kind">]: T[K]
};
interface Circle { kind: "circle"; radius: number;
}
type KindlessCircle = RemoveKindField<Circle>;
// type KindlessCircle = {
// radius: number;
// };

Sau khi đọc bài viết này, mình chắc rằng bạn đã hiểu chức năng của các mapped types và cách implement một số utility types bên trong TypeScript.

Mapping là một trong những kiến thức nền tảng và cốt lõi để bạn có thể tiến xa hơn trên con đường chinh phục những khái niệm nâng cao khác trong Typescript.

Roundup

Như mọi khi, mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.

Cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo! 😍

Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé. Thank you.😉

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 528

- vừa được xem lúc

Type annotation vs Type Inference - Typescript

Trong bài viết này, chúng ta sẽ tìm hiểu kỹ về TypeScript bằng cách tìm hiểu sự khác biệt giữa kiểu chú thích và kiểu suy luận. Tôi sẽ cho rằng bạn có một số kinh nghiệm về JavaScript và biết về các kiểu cơ bản, như chuỗi, số và boolean.

0 0 45

- vừa được xem lúc

Type Annotation và Type Inference trong TypeScript là gì?

Khi làm việc với javascript chắc hẳn các bạn đã quá quen với việc dùng biến mà không cần phải quan tâm đến kiểu dữ liệu của nó là gì phải không? Đúng là mới đầu tiếp cận với Typescript mình cũng cảm thấy nó khá là phiền vì cần phải khai báo đủ type để nó chặt chẽ hơn. Lúc đó mình còn nghĩ: " JavaScr

0 0 37

- vừa được xem lúc

Tìm hiểu TypeScript và kiến thức cơ bản

TypeScript là gì. TypeScript sử dụng tất cả các tính năng của của ECMAScript 2015 (ES6) như classes, modules.

0 0 53

- vừa được xem lúc

TypeScript - P1: Vì sao TypeScript được yêu thích đến vậy?

Trải nghiệm thực tế. Trước khi là một Web Developer, tôi là một Mobile Developer và Java là thứ mà tôi từng theo đuổi.

0 1 69

- vừa được xem lúc

4 Tính năng rất hay từ TypeScript

Xin chào các bạn hôm nay mình xin chia sẽ những tính năng rất hay của TypeScript (TS), các bạn cùng tìm hiểu nhé. Ngoài việc set Type cho biến, tham số hay function thì ví dụ khi bạn nhìn vào một tham

0 0 96