انواع نگاشتی (Mapped Types)
«نوع نگاشتی (Mapped Type)» یعنی ساخت نوع جدید از روی نوع قبلی. مثل کپی کردن کارنامه و عوض کردن همه نمره ها به حروف. بنابراین تغییرها یکدست و ایمن می شوند.
یک نمونه خیلی کوچک
اینجا همه ویژگی ها اختیاری یا فقط خواندنی می شوند. ساده و یکدست.
type Person = { name: string; age: number };
type PartialPerson = { [P in keyof Person]?: Person[P] };
type ReadonlyPerson = { readonly [P in keyof Person]: Person[P] };
نحوه نوشتن نوع نگاشتی
الگو این است: { [P in K]: T }. یعنی روی کلیدها می چرخیم و نوع می سازیم.
interface Person {
name: string;
age: number;
email: string;
}
type PartialPerson = {
[P in keyof Person]?: Person[P];
};
const partialPerson: PartialPerson = {
name: 'John'
};
type ReadonlyPerson = {
readonly [P in keyof Person]: Person[P];
};
const readonlyPerson: ReadonlyPerson = {
name: 'Alice',
age: 30,
email: 'alice@example.com'
};
نوع های نگاشتی آماده
ابزارهای آماده کار را سریع تر می کنند. مانند Partial و Omit.
interface User {
id: number;
name: string;
email: string;
isAdmin: boolean;
}
type PartialUser = Partial<User>;
type RequiredUser = Required<Partial<User>>;
type ReadonlyUser = Readonly<User>;
type UserCredentials = Pick<User, 'email' | 'id'>;
type PublicUser = Omit<User, 'id' | 'isAdmin'>;
type UserRoles = Record<'admin' | 'user' | 'guest', string>;
ساخت نگاشتی های سفارشی
ساده اما کاربردی
می توانیم همه ویژگی ها را تبدیل کنیم؛ مثلا همه را رشته کنیم.
interface Product {
id: number;
name: string;
price: number;
inStock: boolean;
}
type StringifyProperties<T> = {
[P in keyof T]: string;
};
type StringProduct = StringifyProperties<Product>;
type Validator<T> = {
[P in keyof T]: (value: T[P]) => boolean;
};
const productValidator: Validator<Product> = {
id: (id) => id > 0,
name: (name) => name.length > 0,
price: (price) => price >= 0,
inStock: (inStock) => typeof inStock === 'boolean'
};
دستکاری مُدفایرها
حذف readonly و اختیاری کردن
می توانیم readonly را برداریم یا اختیاری ها را اجباری کنیم.
interface Configuration {
readonly apiKey: string;
readonly apiUrl: string;
timeout?: number;
retries?: number;
}
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
type MutableConfig = Mutable<Configuration>;
type RequiredProps<T> = {
[P in keyof T]-?: T[P];
};
type RequiredConfig = RequiredProps<Configuration>;
الگوهای پیشرفته
ترکیب با انواع شرطی
با شرطی ها، می توانیم فقط بعضی نوع ها را تغییر دهیم.
interface ApiResponse {
data: unknown;
status: number;
message: string;
timestamp: number;
}
type FormattedResponse<T> = {
[P in keyof T]: T[P] extends number ? string : T[P];
};
type FormattedApiResponse = FormattedResponse<ApiResponse>;
type StringPropsOnly<T> = {
[P in keyof T as T[P] extends string ? P : never]: T[P];
};
type ApiResponseStringProps = StringPropsOnly<ApiResponse>;
گام های عملی
- نوع پایه را مشخص کن.
- کلیدها را با
keyofبه دست آور. - الگو را با
[P in keyof T]بنویس. - در صورت نیاز، مُدفایرها را کم وزیاد کن.
- برای موارد پیچیده، شرطی ها را ترکیب کن.
جمع بندی سریع
- انواع نگاشتی تغییر یکدست روی همه ویژگی هاست.
PartialوOmitبسیار کاربردی هستند.- می توان مُدفایرها را کم وزیاد کرد.
- با شرطی ها، تغییرها هوشمند می شوند.
برای ادامه، صفحه انواع نگاشتی و همچنین انواع شرطی و نگهبان های نوع را ببین.