Skip to content

TypeScript

defineConfig is generic with a const type parameter, so your config keeps its literal types. The library imports your config through @yarcl/config and derives each prop type with keyof:

// inside the library
import type config from '@yarcl/config';
export type Size = keyof (typeof config)['sizes'];
export type Color = keyof (typeof config)['colors'];

Because @yarcl/config resolves to your file (through paths in your tsconfig.json), Size is your sizes.

Use them to type your own components:

import type { Color, Density, ModalSize, Radius, Shadow, Size, Spacing, TextStyle, Variant } from 'yarcl';
interface PriceTagProps {
tone?: Color;
size?: Size;
}

config is exported too, the resolved config object, for iterating over keys:

import { Button, config, type Color } from 'yarcl';
const colors = Object.keys(config.colors) as Color[];
colors.map((color) => <Button key={color} color={color}>{color}</Button>);

Keep a file of @ts-expect-error lines to prove that invalid values stay invalid. If one of them stops being an error, for example after someone adds a primary color by accident, type-checking fails:

src/contract.check.tsx
import { Button, Stack } from 'yarcl';
export const contract = (
<>
<Button size="lg" color="brand" />
{/* @ts-expect-error: not in this design system */}
<Button size="gigantic" />
{/* @ts-expect-error */}
<Button color="primary" />
{/* @ts-expect-error */}
<Stack gap="huge" />
</>
);
  • "moduleResolution": "bundler" (or node16 / nodenext)
  • "strict": true is recommended
  • the paths entry for @yarcl/config, as shown in installation