مقدمه
یک Utility Type در TypeScript، یک تایپ built-in است که برای تغییر یا ساختن تایپ های دیگر استفاده میشود.
یک Generic Utility Type به این معناست که میتواند روی هر تایپی که به آن بدهید کار کند.
Syntax تایپ ها در TypeScript
یک Generic Utility Type رو مثل یک تابع برای تایپ ها در نظر بگیرید.
// UtilityType<TypeYouPass>
Readonly<{ name: string; age: number }>کد بالا یعنی این object و تمام property های آن را readonly کن.
Utility Type های رایج در TypeScript
Readonly
تمام property های تایپ T را غیرقابل تغییر (immutable) میکند.
// Readonly<T>
type User = {
name: string;
age: number;
};
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = {
name: "Ali",
age: 30,
};
user.age = 31; // ❌ Error: Cannot assign to 'age' because it is a read-only propertyPartial
تمام property های تایپ T را آپشنال یا دلخواه میکند.
// Partial<T>
type User = {
name: string;
age: number;
};
type UpdateUser = Partial<User>;
const update: UpdateUser = {
name: "Reza", // ✅ OK
// age is optional now
};Required
برعکس Partial تمام property های تایپ T را اجباری میکند.
// Required<T>
type User = {
name?: string;
age?: number;
};
type CompleteUser = Required<User>;
const u: CompleteUser = {
name: "Ali", // ✅ Both required now
age: 25,
};Pick
فقط key های مشخص از تایپ T را انتخاب میکند.
// Pick<T, Keys>
type User = {
id: number;
name: string;
email: string;
};
type PublicProfile = Pick<User, "id" | "name">;
// Result:
// { id: number; name: string; }Omit
برعکس Pick اقدام به حذف key های مشخص از تایپ T را انتخاب میکند.
// Omit<T, Keys>
type User = {
id: number;
name: string;
email: string;
};
type WithoutEmail = Omit<User, "email">;
// Result:
// { id: number; name: string; }چرا Generic Utility Type ها مفید هستند؟
این ها به شما کمک میکنند تا:
- از تکرار تایپ جلوگیری کنید.
- APIهای انعطافپذیر بسازید.
- تایپ های مختلفی از یک آبجکت را مدیریت کنید.
- props کامپوننتها را ایمنتر و تمیزتر طراحی کنید.
Generic Utility سفارشی
شما حتی میتوانید Generic Utility خودتان را بسازید.
type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
type User = { name: string; age: number };
type NullableUser = Nullable<User>;
// Result: { name: string | null; age: number | null }