Use Pick and Omit to Narrow JSON-Generated Types
Use json to typescript with Pick and Omit to derive list-view and detail-view subsets from a full resource type without duplication.
Detailed Explanation
Pick and Omit in Practice
The same backend resource often appears in multiple shapes: a full detail object on the show page, a slim summary on the list page, and a tiny avatar tooltip. Pick and Omit derive each shape from one source.
Base JSON
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"avatar_url": "https://cdn.example.com/a.jpg",
"bio": "Full-stack dev",
"role": "admin",
"created_at": "2024-01-15T08:00:00Z",
"last_seen_at": "2024-03-20T12:00:00Z"
}
Generated Base Type
interface User {
id: number;
name: string;
email: string;
avatar_url: string;
bio: string;
role: "admin" | "editor" | "viewer";
created_at: string;
last_seen_at: string;
}
Three Derived Views
// List row — only what the table displays
type UserListItem = Pick<User, "id" | "name" | "email" | "role">;
// Avatar component props — minimal subset
type UserAvatar = Pick<User, "id" | "name" | "avatar_url">;
// Public profile — exclude sensitive timestamps
type PublicProfile = Omit<User, "email" | "last_seen_at">;
Why Pick Beats Re-Declaring
Re-declaring { id: number; name: string; email: string } in three places becomes a maintenance burden the moment id changes from number to string. With Pick, the change propagates automatically.
Pick vs Omit Heuristic
- Use
Pickwhen the subset is small relative to the full type (3 of 12 fields). - Use
Omitwhen you exclude a few fields from a large type (10 of 12 fields). - Combine them:
Pick<Omit<User, "password">, "id" | "name">removes a field first, then narrows.
Type-Level Tests
To prove your derived types stay correct as the base evolves, add static assertions:
type AssertEqual<A, B> = A extends B ? (B extends A ? true : false) : false;
const _check: AssertEqual<keyof UserListItem, "id" | "name" | "email" | "role"> = true;
If someone later renames name to displayName on User, the _check line fails to compile and surfaces every dependent view.
Use Case
Reusing a single User interface generated from your API across a list page, an avatar tooltip, and a public profile page without re-declaring overlapping field sets.
Try It — JSON to TypeScript
Related Topics
Apply Partial, Required, and Readonly to JSON-Generated Types
TypeScript Patterns
Apply DeepReadonly to JSON-Generated TypeScript Types
TypeScript Patterns
Use TypeScript Utility Types with JSON-Generated Interfaces
Complex Types
Decide Optional vs Required Fields in JSON-to-TypeScript
TypeScript Patterns
Generate Literal Status Unions from JSON for State Machines
TypeScript Patterns