1.Giới thiệu
Chắc hẳn với 1 dev frontend thì việc sử dụng typescript là 1 thứ hết sức quen thuộc.Đặc biệt với sự update thư viện và ngôn ngữ hiện nay, typescript gần như là ngôn ngữ mặc định khi setup project.
Với việc mang hơi hướng OOP nhiều hơn là functional programming (đơn giản như cái tên của nó, nó ko hướng tới xử lý logical business mà xử lý về data).TypeScript có rất nhiều các utilities để handle data 1 cách nhanh chóng và thuận tiện(mặc dù nó khá lú @@).
1 số keyword cơ bản như type,interface,typeof,Genetic type đa số chúng ta đã thấy 1 vài lần khi làm với TS dù ở level nào. Vì vậy để đi sâu hơn vào xử lý data type cũng như usecases khi dùng chúng, mình sẽ giới thiệu 1 số keyword nâng cao hơn
2. Extends
- Syntax:
Tương tự như với OOP,chúng ta có extends(kế thừa), trong TS, chúng ta dùng extends để kế thừa thuộc tính từ type hoặc interface khác.
- Advanced:
Tuy nhiên chúng ta có thể thấy,điểm bất tiện trong việc sử dụng TS như trên là thiếu linh hoạt trong việc thay đổi type của properties -> khi muốn thay đổi type của A hoặc B, chúng ta phải thay đổi cả C để không gây lỗi,và mới những kiến trúc như DDD hay repository trong nestJS hoặc NodeJS thì việc sửa lại dữ liệu sẽ thật sự đau đầu.
Vì vậy kết hợp với Generics có thể là 1 phương pháp tối ưu hơn:
VD:Giải thích:
- Kết hợp ternaries với generics: Khai báo a với kiểu dữ liệu
Generics<string>
được truyền vào ứng với T(bạn có thể đặt trên khác ko nhất thiết phải là T). T extends string
: return về true hoặc false, có thể hiểu là 'nếu T có string'- Nếu T không có string hoặc number thì kết quả của
Generics<string>
sẽ là undefined
Như ví dụ trên, chúng ta có thể thể thấy việc sử dụng Generics với ternaries khá hữu ích khi xử lý type of properties, nó sẽ được áp dụng trong 1 số usecases như sau:
- Kết hợp ternaries với generics: Khai báo a với kiểu dữ liệu
- Form field type
- API response handler
- Event Handler Systems
- Database Query Builders
- Theme Configuration
- State Management Actions
- Component Props with Variants
3.Infer
-
Khái niệm: Từ khóa infer được sử dụng để trích xuất/thu thập các types từ other types với conditional types. Giống như nói "tìm ra type này nên là gì và lưu trữ nó trong một biến".
Nói dễ hiểu hơn thì: nó chỉ được sử dụng trong conditional types(như ví dụ với extends generics type bên trên). Và nó sẽ lấy type của properties của type truyền vào (T) và return ra 1 biến = type của properties. -
Ví dụ:
Giải thích:
- T extends Array<infer U>: khởi tạo 1 giá trị mới là U,U sẽ ứng với type của item array được truyền vào
- typeof b: như phần comment: b sẽ có type là Array<string | number>
- => U = string | number => type Generics<typeof b> = number => a sẽ có type là number
- Advanced:
- Kết hợp với ReturnType và Awaited:
- Usecase: Giả sử BE return cho FE hoặc đơn giản muốn convert từ string thành object thì ta có thể dùng Infer(còn tại sao lại dùng string hay object,đơn giản vì primitive luôn nhẹ hơn object)
Practice:
Hãy tự thử nghiệm để hiểu hơn về extends lẫn infer nhé
- Kết hợp với ReturnType và Awaited: