export type Simplify = { [KeyType in keyof T]: T[KeyType] }; export type Except = Pick>; export type Mutable = Simplify< // Pick just the keys that are not mutable from the base type. Except & // Pick the keys that should be mutable from the base type and make them mutable by removing the `readonly` modifier from the key. { -readonly [KeyType in keyof Pick]: Pick[KeyType] } >; export type IfEquals = (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? A : B; // eslint-disable-next-line @typescript-eslint/no-unused-vars // Alternatively: /* type IfEquals = [2] & [0, 1, X] extends [2] & [0, 1, Y] & [0, infer W, unknown] ? W extends 1 ? B : A : B; */ export type WritableKeys = { [K in keyof T]: IfEquals<{ [Q in K]: T[K] }, { -readonly [Q in K]: T[K] }, K> }[keyof T]; export type ReadonlyKeys = { [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, never, P> }[keyof T]; export type WritablePart = Pick>; export type MakeRequired = Simplify & Required>>;