← Back to TypeScript Course | Chapter 28: Real World Projects | Lesson 7 of 14

TypeScript Design System

A design system can use TypeScript to define component props, tokens, variants, and reusable UI contracts. Strong types help keep components consistent.
Syntax
typescript
export interface ComponentProps {
  variant: "optionA" | "optionB";
  onClick: () => void;
}

Core Concept

A typed design system defines reusable UI component props as TypeScript interfaces, so every consumer of a Button or Card component gets compile-time enforcement of exactly which props are valid and required.

Example: Core Concept

typescript
interface ButtonProps {
  variant: "primary" | "secondary";
  onClick: () => void;
}
const props: ButtonProps = { variant: "primary", onClick: () => console.log("clicked") };
console.log(props);

Basic Setup

A basic setup exports each component alongside its typed props interface (export interface ButtonProps { variant: primary | secondary; onClick: () => void }), published as its own versioned package.

Example: Basic Setup

typescript
export interface ButtonProps {
  variant: "primary" | "secondary";
  onClick: () => void;
}
console.log("Component and its typed props interface exported together");

Typed Example

A typed example: using a string-literal union like variant: primary | secondary | danger instead of a plain string means passing variant="primry" (a typo) is a compile error, not a silently-unstyled button in production.

Example: Typed Example

typescript
type Variant = "primary" | "secondary" | "danger";
function applyVariant(variant: Variant) {
  return `btn-${variant}`;
}
console.log(applyVariant("danger"));
// applyVariant("primry") would be a compile error, not a silent style bug

Project Usage

In a real project, a design system's typed props are what let dozens of feature teams consume shared components confidently, since the compiler — not a style guide document — enforces correct usage.

Example: Project Usage

typescript
interface CardProps {
  title: string;
  footer?: string;
}
function renderCard(props: CardProps) {
  return `${props.title}${props.footer ? " - " + props.footer : ""}`;
}
console.log(renderCard({ title: "Stats" }));

Best Practices

Version your design system's typed API deliberately and document breaking prop changes in a changelog, since a prop type change is a breaking change for every consumer even if the runtime behavior looks similar.

Example: Best Practices

typescript
// CHANGELOG.md: "v2.0.0: ButtonProps.variant no longer accepts 'default'"
interface ButtonProps {
  variant: "primary" | "secondary";
}
console.log("Breaking prop changes documented in a changelog");
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Typing variant as string instead of a literal union, so "primry" is accepted.
  2. Not exporting the props interface, so consumers cannot reuse or extend it.
  3. Making too many props optional, so components can be used in ways that were never designed.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.