Zellio.io

YAML config to JSON and a TypeScript type

2 min readLast updated 3 steps · runs on this page

When an application loads a YAML file it usually wants to know what shape to expect. Paste the file, and the recipe normalises it, converts it to JSON, and derives an interface you can hand to the loader.

The steps

  1. 1

    Format YAMLvia Code Formatter

    Re-indents consistently; a file with mixed indentation is the usual cause of a loader complaining about a key that looks fine.

  2. 2

    YAML → JSONvia Code Formatter

    The same document as JSON, which is what most schema tools and test fixtures want.

  3. 3

    JSON → TypeScriptvia JSON to TypeScript

    A Config interface with nested interfaces for each mapping; a starting point for the loader's type.

Ctrl+Enter runs · nothing leaves this tab

Why format first

YAML is indentation-sensitive and tolerant of a lot, which means a file can be valid and still be read differently from how it looks. Formatting it before converting makes the structure visible: a key that was meant to be nested but was indented one space short shows up in the wrong place in the formatted output, before it shows up in the JSON as a missing field.

What the type will and will not say

The interface names every key present and infers each value's type. It does not know that logLevel is one of four strings, that port must be a number in a range, or that cache is optional; those constraints are yours to add. It is a good idea to keep the generated interface next to the sample the type was made from, so the next person can regenerate it after a change.

import type { Config } from "./config.types";

export function loadConfig(raw: unknown): Config {
  // validate against the interface's shape here
  return raw as Config;
}

Common mistakes this catches

  • A tab used for indentation, which YAML forbids; the formatter reports it.
  • A value like 08 or 1e3 that YAML reads as a number when a string was meant; it appears as a number in the JSON.
  • A list item at the wrong indentation, which becomes a sibling of its intended parent.

Questions

My YAML has several documents separated by ---.
Only the first is converted. Split the file and run each part, or merge them into one document first.
Where did my comments go?
JSON has no comments, so they are dropped at the conversion step. The formatted YAML in the first step keeps them.