60 phút
Type System Nâng cao trong TypeScript
Union và Intersection Types
Union Types
type Status = 'pending' | 'success' | 'error';
type ID = string | number;
let userId: ID = 123; // OK
userId = 'abc123'; // OK
// userId = true; // Error
function getStatusColor(status: Status): string {
switch(status) {
case 'pending': return 'yellow';
case 'success': return 'green';
case 'error': return 'red';
}
}
Intersection Types
interface User {
name: string;
email: string;
}
interface Admin {
role: string;
permissions: string[];
}
type AdminUser = User & Admin;
const admin: AdminUser = {
name: 'John Doe',
email: 'john@example.com',
role: 'superadmin',
permissions: ['read', 'write', 'delete']
};
Generics
Generic Functions
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("hello");
let output2 = identity(42); // Type inference
function getFirstElement<T>(array: T[]): T | undefined {
return array[0];
}
const numbers = [1, 2, 3];
const firstNumber = getFirstElement(numbers); // number
const strings = ['a', 'b', 'c'];
const firstString = getFirstElement(strings); // string
Generic Interfaces
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
interface User {
id: number;
name: string;
}
const userResponse: ApiResponse<User> = {
data: { id: 1, name: 'John' },
status: 200,
message: 'Success'
};
const productResponse: ApiResponse<Product> = {
// ...
};
Utility Types
Partial<T>
interface User {
id: number;
name: string;
email: string;
}
function updateUser(id: number, updates: Partial<User>) {
// Chỉ cập nhật các trường được cung cấp
}
updateUser(1, { name: 'Jane' }); // OK
updateUser(1, { phone: '123' }); // Error
Required<T> và Readonly<T>
interface Props {
name?: string;
age?: number;
}
const props1: Props = { name: 'John' }; // OK
const props2: Required<Props> = { name: 'John', age: 25 }; // Bắt buộc
const user: Readonly<User> = { id: 1, name: 'John' };
// user.name = 'Jane'; // Error - readonly
Pick<T, K> và Omit<T, K>
interface User {
id: number;
name: string;
email: string;
password: string;
createdAt: Date;
}
type UserPreview = Pick<User, 'id' | 'name' | 'email'>;
type UserWithoutPassword = Omit<User, 'password'>;
const preview: UserPreview = {
id: 1,
name: 'John',
email: 'john@example.com'
};
Conditional Types
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
type ExtractType<T> = T extends { type: infer U } ? U : never;
type Event = { type: 'click'; x: number; y: number };
type EventType = ExtractType<Event>; // 'click'
Bài tập thực hành
Hãy áp dụng advanced types trong các tình huống thực tế!