Generate TypeScript interfaces from a YAML document — nested mappings as their own interfaces, sequences of mappings merged into one element interface, sometimes-absent keys as optional properties, stringified non-string keys reported. Your input is never auto-saved: YAML is configuration, and configuration carries secrets. Free, no sign-up — runs locally in your browser.
Why generate TypeScript interfaces from a YAML sample?
TypeScript tooling reads YAML constantly — static-site front
matter, workflow definitions, OpenAPI documents, config for
build pipelines — and the usual pattern is a cast: parse, assert
the type you hope for, and let any drift surface at runtime.
Generating the interfaces from a real sample replaces the hope
with evidence. Every key in the sample gets a property with an
inferred type, nested mappings become their own interfaces,
sequences of mappings merge into one element interface, a key
that only sometimes appears becomes optional — and the
judgement calls (stringified keys, resolved anchors, values
that mix types and become unions) are written into the notes
instead of being buried in the output.
How to use this tool
- Paste the YAML, upload a file, or drop one on the panel. One document only — multi-document files are refused with an explanation.
- Name the root interface.
Config is the default because that is what most YAML pasted here turns out to be. - Press Generate TypeScript interfaces. The root interface comes first.
- Read the notes if any appear: stringified keys and anchor effects are listed there (the generator's own calls — optionals and unions — are visible in the output itself).
- Copy or download, and remember the input was never saved — if you clear the box, the YAML is gone from this tool entirely.
The mapping rules
Mappings become interfaces, property names
verbatim (quoted when they are not valid identifiers).
Sequences become arrays, and a sequence of
mappings yields one merged element interface; a key missing
from some items becomes an optional property.
Scalars infer like JSON: numbers are
number, true/false is boolean,
everything else is string — including dates,
which this parser hands over as strings, so a
when: 2024-01-15 property is a string unless your
runtime library resolves dates and you adjust the type. A slot
showing several shapes becomes their union — TypeScript can
say exactly what the sample shows. Nulls and mixed
slots widen the union rather than disappearing.
Identical shapes share one interface.
Worked example
Given this service configuration (the second endpoint has no retries):
service: api
replicas: 3
endpoints:
- path: /health
retries: 0
- path: /metrics
the converter emits:
export interface Config {
service: string;
replicas: number;
endpoints: Endpoint[];
}
export interface Endpoint {
path: string;
retries?: number;
}
The question mark on retries is the second
endpoint talking: the sample proves the key comes and goes,
so the type makes every reader handle its absence.
Frequently asked questions
My configuration library reads YAML at runtime. Will these interfaces match what it returns?
They match the shape of the parsed value: mappings become objects with these properties, sequences become arrays, scalars keep the types shown. Two things to check against your library: how it spells non-string keys (this generator stringifies them, and the notes list every one) and whether it resolves timestamps — this site's parser hands dates back as strings, so a 'when: 2024-01-15' field is string here; if your runtime library gives you Date objects instead, that one field's type is yours to adjust, and the difference is a library choice, not a file difference.
Why is this property optional?
Because the sample says it comes and goes: the key is present in some items of its sequence and missing from others. The question mark is the sample's evidence written into the type — code that reads the property must handle its absence, which is exactly the bug class interfaces exist to catch. A key missing from a mapping that appears only once cannot be detected this way: with a single occurrence there is no evidence either way, and the property is emitted as required.
My YAML has several documents separated by ---. What happens?
The converter refuses, and says how many documents it found. Each document would need its own root type, and quietly generating the first (or merging them) would produce interfaces that misdescribe your file. Split the documents and convert each one, or name the root per document — that is a modelling decision, so the tool leaves it to you.
I use anchors, aliases and merge keys. Do they survive?
They are resolved before generation: an aliased mapping is seen as the full mapping it points at, and a merge key's entries appear as the properties they contribute, so the generated interfaces describe the values, not the anchor syntax. If two keys alias mappings with the same shape, they share one interface, like any identical shapes. What is lost is the sharing itself — the type cannot say 'these two properties are the same object'. If your program depends on that identity rather than the values, no interface generator can express it.
My keys aren't strings — YAML allows that. What happens to them?
TypeScript property names here are strings, so a numeric or boolean YAML key is treated as its string spelling (42 becomes "42", quoted in the interface) and the notes call out every key it happens to. One subtlety: YAML also distinguishes the keys 42 and "42"; the parsed value cannot, so a document using both would collapse them — the notes are where to check if that matters to you.
Why isn't my input auto-saved like on other tools?
Because YAML is usually configuration, and configuration files carry secrets — API keys, tokens, internal hostnames, database passwords. This converter keeps no draft of your input or your root interface name, in your browser or anywhere else: paste, convert, done. Refresh the page and it is gone — that is deliberate, and it is the same rule on every YAML tool on this site.