๐—ง๐˜†๐—ฝ๐—ฒ๐—ฆ๐—ฐ๐—ฟ๐—ถ๐—ฝ๐˜ ๐—ง๐—ฒ๐—บ๐—ฝ๐—น๐—ฎ๐˜๐—ฒ ๐—Ÿ๐—ถ๐˜๐—ฒ๐—ฟ๐—ฎ๐—น ๐—ง๐˜†๐—ฝ๐—ฒ๐˜€

Strings cause many bugs in TypeScript.

You might pass "400px" when a function needs "4rem". You might type "onclick" instead of "onClick". You might build a broken URL by forgetting a slash.

Most developers use runtime validation or hope for the best. You can do better. Use template literal types to enforce string patterns at compile time.

This is not just a basic union like "up" | "down". Template literal types let you build and restrict strings dynamically.

Use them for CSS values:

type CSSSize = ${number}px | ${number}rem | ${number}% | "auto";

Now, TypeScript knows the difference: โ€ข setSize("16px") is OK. โ€ข setSize("16") is an error. โ€ข setSize("banana") is an error.

You get safety without runtime overhead.

Use them for event handlers:

type EventName = "click" | "change" | "submit"; type EventHandler = on${Capitalize<E>};

This turns "click" into "onClick" automatically. If you add a new event, the handler type updates itself. This creates a single source of truth.

Use them for API routes:

type ApiRoute = /api/${string} | /api/${string}/${string};

You can even use the "infer" keyword to parse strings. This lets you pull parameters out of a URL path at the type level. It is like running a split function, but during compilation.

Follow these rules to avoid trouble:

Template literal types turn strings into contracts. They catch mistakes before they reach your users.

What is your experience with template literal types? Have you found a clever pattern or hit a limit?

Source: https://dev.to/kaithorne/typescript-template-literal-types-turn-your-strings-into-type-safe-contracts-529f