Исходный тип является обычным объектом User с полями. Чтобы избежать дублирования полей был введён ряд модификаторов, которые выполняют ту или иную роль, например
Expand раскрывает тип, а
DeepNonNull должен рекурсивно перебирать поля и удалять null из возможных значений.
UserCreateInput раскрывается нормально, а
UserWhereOneInput не раскрывается и не закрывается:
type UserCreateInput = Expand<Pick<User, 'firstname' | 'username' | 'phone' | 'password'> & Partial<Omit<User, 'firstname' | 'username' | 'phone' | 'password'>>>;
type UserWhereOneInput = Expand<AtLeast<DeepNonNull<Pick<User, 'id' | 'username' | 'phone' | 'email'>>>>;
С
Expand:
Без
Expand
Типы модификаторов:
type Expand<T> = {
[K in keyof T]: T[K];
};
type NoExpand<T> = T extends unknown ? T : never;
type AtLeast<
O extends object,
K extends keyof O = never
> = NoExpand<
[K] extends [never]
? {
[P in keyof O]-?: Required<Pick<O, P>> & Partial<Omit<O, P>>;
}[keyof O]
:
{
[P in K]-?: Required<Pick<O, P>> & Partial<Omit<O, P>>;
}[K]
>;
type DeepNonNull<T> = T extends never
? NonNullable<T>
: T extends Array<infer U>
? Array<DeepNonNull<U>>
: T extends object
? { [P in keyof T]: DeepNonNull<T[P]> }
: NonNullable<T>;
export type {
Expand,
AtLeast,
DeepNonNull
}
Модификаторы сгенерировала нейросеть, в данный момент я слабо представляю как они работают и времени изучить нет, возможно проблема в них, в частности в DeepNonNull.
Цель: Избавиться от
Record<string, any> и подобных в подсказках, т.к. постоянно путешествовать по типам чтобы посмотреть поле желания нет.
- Возможно это решается средствами ide, отсюда и тег.
- Возможно есть альтернативные решения проблемы - я не знаю.