Skip to content

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 ParameterDefault typeDescription
T-The nested camelCase config type to convert.
D extends Depth5Internal recursion depth counter (do not set manually).

Remarks

ToEnv recursively traverses the config type T, joining key segments with underscores and uppercasing them (portNumberPORT_NUMBER, log.levelLOG_LEVEL). Value types are converted via UncoercedType: booleanBooleanString, numberNumberString, stringstring (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.example file 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 ToEnv on config types that contain non-serialisable values (Date, Map, Set) — BECAUSE the type utility models them as string, masking type errors at compile time even though envy() will produce '[object Object]' at runtime.
  • NEVER manually set the D depth 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

Released under the MIT License.