objectenvy / ToEnv
Type Alias: ToEnv<T, D>
ts
type ToEnv<T, D> = Simplify<UnionToIntersection<FlattenToEnv<T, "", D>>>;Defined in: typeUtils.ts:141
Convert a nested camelCase config type to a flat SCREAMING_SNAKE_CASE env record, preserving string literal and template literal types.
Type Parameters
| Type Parameter | Default type | Description |
|---|---|---|
T | - | The nested camelCase config type to convert. |
D extends Depth | 5 | Internal recursion depth counter (do not set manually). |
Remarks
ToEnv recursively traverses the config type T, joining key segments with underscores and uppercasing them (portNumber → PORT_NUMBER, log.level → LOG_LEVEL). Value types are converted via UncoercedType: boolean → BooleanString, number → NumberString, string → string (literal unions are preserved). Arrays are serialized as string (they become comma-joined at runtime via envy()).
Recursion is capped at depth 5 to prevent TypeScript from hanging on deeply nested schemas. For configs deeper than 5 levels, the type degrades to Record<string, string> at that level.
Use When
- You want compile-time validation that your
.env.examplefile has the correct keys. - You're typing the argument to
child_process.spawn({ env: ... })with static guarantees. - You want IDE autocomplete for env variable names derived from your config type.
Avoid When
- Your config type is recursive (tree structures, linked lists) — use a simpler mapped type.
- You need more than 5 levels of nesting — the type degrades silently at depth 5.
Pitfalls
- NEVER use
ToEnvon config types that contain non-serialisable values (Date, Map, Set) — BECAUSE the type utility models them asstring, masking type errors at compile time even thoughenvy()will produce'[object Object]'at runtime. - NEVER manually set the
Ddepth parameter — BECAUSE it exists solely to bound recursion; overriding it can cause TypeScript to instantiate the type incorrectly.
Example
ts
import type { ToEnv } from 'objectenvy';
type Config = {
portNumber: number;
log: {
level: 'debug' | 'info' | 'warn' | 'error';
path: string;
};
apiUrl: `https://${string}`;
};
type Env = ToEnv<Config>;
// {
// PORT_NUMBER: `${number}`;
// LOG_LEVEL: 'debug' | 'info' | 'warn' | 'error';
// LOG_PATH: string;
// API_URL: `https://${string}`;
// }See
- FromEnv for the inverse transformation
- SchemaToEnv for extracting the env type from a Zod schema