typescript-conventionslisted
Install: claude install-skill pau-vega/AI-Devkit
# TypeScript Conventions
## Types & Interfaces
### Prefer `interface extends` over `&`
The `&` (intersection) operator has poor performance in the TypeScript compiler. Use `interface extends` for inheritance — it's faster and produces clearer error messages.
```ts
// Avoid
type C = A & B;
// Prefer
interface C extends A, B {}
```
Only use `&` where `interface extends` is not possible (e.g., combining mapped types).
### Use discriminated unions for variant data
Model data that can be in different shapes with a shared discriminant field. This prevents the "bag of optionals" problem where impossible states are representable.
```ts
// Avoid — allows { status: "idle", data: someValue }
type FetchingState<TData> = {
status: "idle" | "loading" | "success" | "error";
data?: TData;
error?: Error;
};
// Prefer — each status carries exactly the right fields
type FetchingState<TData> =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: TData }
| { status: "error"; error: Error };
```
Handle discriminated unions with `switch` statements:
```ts
const handleEvent = (event: Event) => {
switch (event.type) {
case "user.created":
console.log(event.data.email);
break;
case "user.deleted":
console.log(event.data.id);
break;
}
};
```
### Avoid `readonly` unless strictly needed
Do not add `readonly` to properties by default. Only use it when immutability is a critical invariant that must be enforced at compile t