Pick, Omit, and Record Composition
Derive view and input types from one canonical entity with Pick and Omit, so changes to the source shape propagate to every dependent type.
Code
export interface User {
id: string;
email: string;
passwordHash: string;
createdAt: Date;
updatedAt: Date;
}
export type PublicUser = Omit<User, "passwordHash">;
export type UserSummary = Pick<User, "id" | "email">;
export type UpdateUserInput = Partial<Pick<User, "email">>;
export type UserIndex = Record<string, UserSummary>;
export function toPublic(user: User): PublicUser {
const { passwordHash: _omit, ...rest } = user;
return rest;
}
export function buildIndex(users: User[]): UserIndex {
return Object.fromEntries(users.map((u) => [u.id, { id: u.id, email: u.email }]));
}Report a problem with this exampleOpens a pre-filled issue on GitHub.