Create Generic TypeScript Wrapper Types from JSON Envelopes
Learn how to convert repeating JSON envelope patterns like pagination and API wrappers into reusable generic TypeScript types.
Detailed Explanation
Generic Wrappers from JSON Patterns
Many APIs wrap their data in a consistent envelope: a status field, pagination metadata, and the actual payload. Instead of duplicating this structure for every endpoint, you can create a generic wrapper type.
Example JSON (Users endpoint)
{
"ok": true,
"data": [{ "id": 1, "name": "Alice" }],
"meta": { "page": 1, "total": 50, "perPage": 10 }
}
Example JSON (Products endpoint)
{
"ok": true,
"data": [{ "sku": "ABC-123", "price": 29.99 }],
"meta": { "page": 1, "total": 200, "perPage": 10 }
}
Generated TypeScript
interface Meta {
page: number;
total: number;
perPage: number;
}
interface ApiListResponse<T> {
ok: boolean;
data: T[];
meta: Meta;
}
interface User {
id: number;
name: string;
}
interface Product {
sku: string;
price: number;
}
type UserListResponse = ApiListResponse<User>;
type ProductListResponse = ApiListResponse<Product>;
Detecting the Generic Pattern
The converter identifies a generic wrapper when:
- Multiple responses share an identical outer structure (same keys and same types for non-data fields).
- The data field varies between responses — different inner objects.
- The envelope keys (
ok,meta,error) are consistent.
Single-Item Wrapper
For detail endpoints that return one item instead of a list:
interface ApiDetailResponse<T> {
ok: boolean;
data: T;
meta?: never; // explicitly absent
}
type UserDetailResponse = ApiDetailResponse<User>;
Error Envelope
interface ApiErrorResponse {
ok: false;
error: {
code: string;
message: string;
};
}
type ApiResponse<T> = ApiListResponse<T> | ApiErrorResponse;
Benefits
- Single source of truth — Changing the envelope structure (e.g., adding a
requestId) only requires updating the generic interface. - Type safety —
UserListResponseguarantees thatdatacontainsUser[], notProduct[]. - Less boilerplate — Endpoints reuse the same wrapper, reducing interface count by 50% or more in API-heavy codebases.
Use Case
Your API returns every response in the same envelope structure with ok, data, and meta fields, and you need a generic type that works for all endpoints instead of duplicating the wrapper 50 times.
Try It — JSON to TypeScript
Related Topics
Type a Full API Response JSON as TypeScript
Advanced Patterns
Convert JSON to TypeScript Discriminated Union Types
Complex Types
Use TypeScript Utility Types with JSON-Generated Interfaces
Complex Types
Convert JSON Arrays of Objects to TypeScript Types
Basic Conversions
Generate Recursive TypeScript Types from Self-Referencing JSON
Complex Types