file-typeEngineering
TypeScript for Frontend
Typing props and hooks, generics, narrowing, discriminated unions, and the utility types worth knowing.
1 item
Links1
Type the boundaries, let inference do the rest
Annotate function signatures, component props, and API payloads. Inside a function, let TypeScript infer — over-annotating local variables is noise. The goal is types where data enters your code (props, fetch responses, form input), so everything downstream is checked for free.
Typing components
type ButtonProps = {
variant: "primary" | "ghost";
disabled?: boolean;
onClick: () => void;
children: React.ReactNode;
};
function Button({ variant, disabled = false, onClick, children }: ButtonProps) { ... }
- Use
React.ReactNodeforchildren, notstring. - Prefer union literals (
"primary" | "ghost") overstring— they document valid values and autocomplete. - For props that extend a DOM element, intersect with the element's props:
type Props = { variant: ... } & React.ComponentProps<"button">.
Discriminated unions — the most useful pattern
Model "states that can't coexist" so impossible states are unrepresentable:
type Result =
| { status: "loading" }
| { status: "error"; message: string }
| { status: "success"; data: User };
Switching on status narrows the type — TypeScript knows data only exists in the success branch. This kills a whole class of "cannot read property of undefined" bugs.
Narrowing & guards
typeof,in, and custom type guards (function isUser(x): x is User) narrowunknown/union types safely.- Treat external data as
unknownand validate it (Zod) rather than casting withas.asis a lie to the compiler — use it sparingly.
Utility types worth memorizing
Partial<T>,Required<T>,Pick<T, K>,Omit<T, K>for reshaping.Record<K, V>for maps/dictionaries.ReturnType<typeof fn>andAwaited<T>to derive types from values instead of duplicating them.- Derive types from a single source of truth (e.g. a Zod schema →
z.infer<typeof schema>) so types and runtime validation never drift.
Config
- Run in
strictmode. The whole value of TS evaporates without it. AddnoUncheckedIndexedAccessfor an extra safety net on array/object access.