TypeScript Guidelines
Type safety best practices for strict TypeScript.
TypeScript Guidelines
Strict Mode
TypeScript strict mode is enabled. Never use any or disable type checks.
// β Avoid
const data: any = fetchData();
// @ts-ignore
someUntypedCode();
// β
Use proper types
const data: UserData = await fetchData();
const result = someTypedCode<string>();
Component Props
// Define explicit interfaces
interface ButtonProps {
variant: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
onClick?: () => void;
children: ReactNode;
}
// Extend HTML attributes for DOM elements
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
}
Generic Components
// Generic list component
interface ListProps<T> {
items: T[];
renderItem: (item: T) => ReactNode;
keyExtractor: (item: T) => string;
}
function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map((item) => (
<li key={keyExtractor(item)}>{renderItem(item)}</li>
))}
</ul>
);
}
Event Handlers
// Use specific event types
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
};
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
// ...
};
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
// ...
};
Type Imports
// Use 'type' keyword for type-only imports
import type { ReactNode, HTMLAttributes } from 'react';
import type { UserData } from '@/types';
// Combined imports
import { useState, type Dispatch, type SetStateAction } from 'react';
Utility Types
// Pick specific properties
type UserPreview = Pick<User, 'id' | 'name' | 'avatar'>;
// Make all properties optional
type PartialUser = Partial<User>;
// Make all properties required
type RequiredUser = Required<User>;
// Omit specific properties
type UserWithoutPassword = Omit<User, 'password'>;