Creating HTML with DOM API statements can be verbose. JSX (JavaScript XML) lets a TSX file mix element-like markup with code, so a method can express the content it returns directly. JSX is associated with React, but the TypeScript compiler can also support it in a standalone application. section 16.7
Return an element from a class
In src/htmlDisplay.tsx, a getContent(): HTMLElement method can return <h3 className="bg-secondary">{this.getElementText()}</h3>. The expression supplies text from the class’s props, such as a product count and order total. This file needs JSX configuration before it will compile. section 16.7
At compilation, each JSX element is split into its tag, attributes, and content, then replaced with a factory-function call. For example, the h3 becomes a call shaped like createElement("h3", { className: "bg-secondary" }, this.getElementText()). The compiler generates the call; the factory creates the content at runtime. section 16.7.1
Listing 16.27 The contents of the jsxFactory.ts file in the src/tools folder
export function createElement(tag: any, props: Object,
...children : Object[]) : HTMLElement {
function addChild(elem: HTMLElement, child: any) {
elem.appendChild(child instanceof Node ? child
: document.createTextNode(child.toString()));
}
if (typeof tag === "function") {
return Object.assign(new tag(), { props: props || {}}).getContent();
}
const elem = Object.assign(document.createElement(tag), props || {});
children.forEach(child => Array.isArray(child)
? child.forEach(c => addChild(elem, c)) : addChild(elem, child));
return elem;
}
declare global {
namespace JSX {
interface ElementAttributesProperty { props; }
}
}
The src/tools/jsxFactory.ts listing supplies a minimal createElement implementation: it creates DOM elements, assigns properties, appends children, and handles JSX classes used as tags. Its JSX namespace declaration tells TypeScript to check element attributes against a class’s props property. This custom factory lacks the more sophisticated dynamic-content handling of frameworks. section 16.7.3
Two boundaries matter when using this pattern:
- JSX attributes use DOM property names, not necessarily HTML attribute names: write className rather than class. Check property names first when an element does not behave as expected. section 16.7.1
- A regular entry-point class can instantiate a JSX class, assign its props, call getContent(), and append the returned element to the document. section 16.7.4
JSX classes can also be composed as custom tags. A product list can include a category-list element whose attributes provide categories, the selected category, and a callback. At runtime, the factory creates that class, assigns its props, and calls getContent(). Buttons can invoke the callback through an onclick property. section 16.8.1
In a React toolchain, Babel can perform the JSX-to-JavaScript transformation instead. One TypeScript configuration uses jsx: "react-jsx" and noEmit: true, leaving JavaScript generation to Babel. JSX therefore describes the source format, not a requirement to use the minimal DOM factory. section 20.2





