Typescript and Friends – Phần 2: Typescript Types mở rộng?

2 min read

typescript utility type

Mở đầu

Tiếp tục với series Typescript and Friends, ở phần 1 thì mình đã trình bày về các type cơ bản có sẵn trong typescript cũng như cách tạo ra các type mới. Tuy nhiên ngoài những type cơ bản, typescript cũng cung cấp rất nhiều type có sẵn khác hay thường được gọi là Utility Types.

Trong bài viết này, mình sẽ giới thiêu cho mọi người về các Utility Types theo mình là hay được sử dụng. Không dài dòng nữa, bắt đầu ngay thôi nào!

Partial<Type>

Tạo ra một type mới từ type có sẵn với tất cả thuộc tính của type đó là tùy chọn.

interface Todo {
  title: string;
  description: string;
}
const todo: Todo = { title: 'write blog' }; // not ok, description is required
const optionalTodo: Partial<Todo> = { title: 'write blog' }; // ok

Required<Type>

Ngược lại với Partial, Required tạo ra một type mới từ type có sẵn với tất cả thuộc tính của type đó là bắt buộc.

interface Todo {
  title: string;
  description?: string;
}
const todo: Todo = { title: 'write blog' }; // ok
const requiredTodo: Required<Todo> = { title: 'write blog' }; // not ok, description is required

Readonly<Type>

Đặt tất của thuộc tính của type có sẵn thành readonly và trả về type mới.

interface Todo {
  title: string;
}

const todo: Todo = { title: 'write blog' };
todo.title = 'read blog'; // ok

const readonlyTodo: Readonly<Todo> = { title: 'write blog' };
readonlyTodo.title = 'read blog'; // not ok, Cannot assign to 'title' because it is a read-only property.

Record<Keys, Type>

Tạo ra một type có cấu trúc dạng key - value. Nếu mọi người đã quen với Javascript thì cũng không lạ gì khi chúng ta tạo ra một biến object để mapping nhanh chóng các giá trị.

type MessageType = 'error' | 'success' | 'warning';
const messageMap: Record<MessageType, string> = {
  error: 'This is error message.',
  success: 'This is success message.',
  warning: 'This is warning message.'
}

console.log(messageMap.error);

Pick<Type, Keys>

Sử dụng khi chúng ta muốn tạo ra type mới chỉ chọn một số thuộc tính từ type đã có.

interface Todo {
  title: string;
  description: string;
  status: boolean;
}
 
type TodoStatus = Pick<Todo, "status">; // new type contain only "status" property
 
const todoStatus: TodoStatus = {
  status: true
};

Omit<Type, Keys>

Ngược lại với Pick, Omit tạo ra type mới bằng cách loại bỏ một số thuộc tính của type có sẵn.

interface Todo {
  title: string;
  description: string;
  status: boolean;
}
 
type TodoStatus = Omit<Todo, "title" | "description">; // new type contain only "status" property
 
const todoStatus: TodoStatus = {
  status: true
};

Exclude<UnionType, ExcludedMembers>

Được sử dụng để loại bỏ một số union’s member khỏi union type.

type Animal = 'cat' | 'dog' | 'fish' | 'bird';
type GroundAnimal = Exclude<Animal, 'fish' | 'bird'>;

const animal: Animal = 'fish'; // ok
const groundAnimal: GroundAnimal = 'bird' // not ok, Type '"bird"' is not assignable to type 'GroundAnimal'.

Extract<Type, Union>

Được sử dụng để chọn ra một số union’s member từ union type.

type Animal = 'cat' | 'dog' | 'fish' | 'bird';
type GroundAnimal = Extract<Animal, 'cat' | 'dog'>;

const animal: Animal = 'fish'; // ok
const groundAnimal: GroundAnimal = 'bird' // not ok, Type '"bird"' is not assignable to type 'GroundAnimal'.

NonNullable<Type>

Loại bỏ nullundefined khỏi union.

type CustomNum = number | null | undefined;

const num: CustomNum = null; // ok
const onlyNum: NonNullable<CustomNum> = null; // not ok, Type 'null' is not assignable to type 'number'.

Tổng kết

Trên đây mình đã trình bày sơ qua một số Utility Types theo mình là hay được sử dụng. Như mọi người thấy, các Utility Types của typescript có syntax generic, khá quen thuộc trong một số ngôn ngữ lập trình khác như Java, Php,…

Ở phần tiếp theo, mình sẽ đi sâu vào khái niệm Generics trong typescript cũng như cách tự tạo ra một Utility Type. Hẹn gặp lại mọi người ở bài viết sau, see ya.

Tìm hiểu thêm về Utility Types trong typescript ở đây:

https://www.typescriptlang.org/docs/handbook/utility-types

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *