XML to TypeScript
Paste XML and instantly generate idiomatic TypeScript interfaces with inferred types for elements, attributes, and arrays.
Example
Input XML:
<book id="1" available="true">
<title>Clean Code</title>
<year>2008</year>
</book>
Generated TypeScript:
export interface Root {
"@id": number;
"@available": boolean;
title: string;
year: number;
}How it works
DOMParser turns your XML into a node tree, then the tool infers a type model (string/number/boolean primitives, nested objects, and arrays for repeated tags) and emits TypeScript interfaces. Attributes become properties, text content becomes a value field, and the root type is named Root.
Good to know
XML to TypeScript takes a chunk of XML you paste in and works out a set of TypeScript interface definitions that describe its shape. It walks the parsed document tree, samples the actual values to guess primitive types (string, number, boolean), nests interfaces for child elements, and turns any tag that appears more than once under the same parent into an array. It is aimed at developers who consume XML APIs, config files, or legacy feeds and want strongly typed access to that data without hand-writing the types.
Reach for it when you are wiring up a parser like fast-xml-parser, xml2js, or a DOMParser-based loader and need types that match the parsed JSON-style object rather than the raw markup. It is also handy for a quick one-off: drop in a sample response, copy the generated Root interface, and you have an editor-friendly contract to code against and catch typos at compile time.
Read the output with the comment header in mind. Attribute properties are prefixed with @ (so an XML id attribute becomes "@id"), an element's own text content lands under "#text", and a trailing ? marks any property that was missing from some repeated siblings. The top-level type is always called Root, and nested element types are named from their tag in PascalCase, with numeric suffixes added when names collide.
One caveat to keep in mind: every type is inferred from the example you paste, not from a schema. If your sample only ever shows "true" in a field it will be typed boolean, and a field that happens to hold digits becomes number even if the source can also contain text. For reliable results, paste a representative sample that includes optional fields and varied values, then widen any inferred type by hand where the real data is broader than the example.
Frequently asked questions
How are XML attributes and text content represented?
Attributes are emitted as properties prefixed with @ (for example "@id"), and an element's own text content is emitted as a "#text" property. This mirrors common XML-to-JSON conventions so the generated types map cleanly onto parsed XML.
How does it decide when a property is an array?
If the same child tag appears more than once under a parent, that property becomes an array (Type[]). Types from repeated and differing siblings are merged, and properties missing in some siblings are marked optional with ?.
Is my data uploaded anywhere?
No — this tool runs entirely in your browser. Your input never leaves your device and it works offline once loaded.
Is it free?
Yes, completely free with no sign-up and no limits.
People also ask
How do I use the generated types with fast-xml-parser or xml2js?
Configure your parser to expose attributes with an @ prefix and text content under a #text key, which matches the convention this tool emits. Then cast or annotate the parser's output with the generated Root interface so the fields line up.
Why are all my numbers and booleans typed as number and boolean instead of string?
The tool inspects the literal value of each element or attribute and infers the narrowest matching primitive, so "2008" becomes number and "true" becomes boolean. If a field can actually hold mixed content, change the type to string manually after generating.
Does this tool generate a TypeScript type from an XSD or DTD schema?
No. It infers types only from the example XML instance you paste, not from any XSD, DTD, or RelaxNG schema. The accuracy of the result depends entirely on how representative your sample data is.
What happens to XML namespaces and prefixes like soap: or xsi:?
Namespace declaration attributes (xmlns and xmlns:*) are skipped, and elements are keyed by their local name. Prefixed attributes keep their name as the property key.
Why does a field show up with a question mark in the interface?
A trailing ? means the property is optional because it was present in some repeated sibling elements but missing in others. The tool merges all siblings of the same tag and marks any field that is not always present as optional.
Can it handle multiple root elements or an XML fragment?
It expects a single well-formed document with one root element, which it names Root. A fragment with multiple top-level elements is invalid XML and will trigger a parse error, so wrap such content in a single wrapper element first.
Is XML to TypeScript different from converting XML to JSON first?
It produces only the type definitions, not the data. It uses the same @attribute and #text conventions common in XML-to-JSON conversion so the interfaces fit cleanly over a JSON-parsed version of the same XML.
Does the conversion send my XML to a server?
No. All parsing and type generation run in your browser using the built-in DOMParser, so the input stays on your device and works offline once the page has loaded.
Related tools