type User = { id: number; name: string; email: string };type A = MyPartial<User>; // { id?: number; name?: string; email?: string }type B = MyReadonly<User>; // { readonly id: number; ... }type C = MyPick<User, 'id' | 'name'>; // { id: number; name: string }type D = MyOmit<User, 'email'>; // { id: number; name: string }
Решение
Оптимальное решение
// Mapped type: перебираем ключи через [P in keyof T]// ? делает поля необязательнымиtype MyPartial<T> = { [P in keyof T]?: T[P];};// -? убирает необязательностьtype MyRequired<T> = { [P in keyof T]-?: T[P];};// readonly-модификаторtype MyReadonly<T> = { readonly [P in keyof T]: T[P];};// K ограничен ключами T; перебираем только выбранныеtype MyPick<T, K extends keyof T> = { [P in K]: T[P];};// Exclude убирает K из общего набора ключейtype MyOmit<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P];};