TypeScript Coding Standards#
Reference#
TypeScript Documentation: https://www.typescriptlang.org/docs/
React Typescript Cheatsheet:https://react-typescript-cheatsheet.netlify.app/
Type Annotations#
Basic Types - Be explicit when TypeScript can’t infer - Use built-in types appropriately - Avoid
any
// ❌ Bad
let value: any;
const numbers = [];
// ✅ Good
let value: string;
const numbers: number[] = [];
const handler = (event: React.MouseEvent) => {};
React Props - Define prop interfaces - Use children prop when needed - Document complex props
interface ButtonProps {
variant: 'primary' | 'secondary';
onClick: () => void;
children: React.ReactNode;
}
Interfaces vs. Type Aliases#
Use Interfaces For - React components props - Objects with clear contracts - Extendable shapes
// ✅ Good for interfaces
interface UserProfile {
id: string;
name: string;
}
interface AdminProfile extends UserProfile {
permissions: string[];
}
Use Types For - Unions and intersections - Complex types - Function types
// ✅ Good for type aliases
type ButtonVariant = 'primary' | 'secondary';
type Handler = (event: MouseEvent) => void;
type Theme = 'light' | 'dark';
Generics#
Common Use Cases - Reusable components - Type-safe functions - API responses
// Generic component
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
// Generic function
const getFirstItem = <T>(array: T[]): T => array[0];
Type Definitions for External Libraries#
Module Declarations - Declare modules for CSS - Add missing library types - Extend existing types
// CSS Modules
declare module '*.module.css' {
const classes: { [key: string]: string };
export default classes;
}
// Extend Window
declare global {
interface Window {
customProperty: string;
}
}
Library Types - Install @types packages - Create custom declarations - Document type extensions
Enums vs. Union Types#
Union Types (Preferred) - Use for simple choices - String literals for values - Better tree-shaking
// ❌ Avoid enums
enum ButtonSize {
Small = 'small',
Large = 'large'
}
// ✅ Use union types
type ButtonSize = 'small' | 'large';
type Theme = 'light' | 'dark';
When to Use Enums - Fixed set of values - Numeric values needed - Backend compatibility
Linting and Formatting#
TSConfig
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"jsx": "react"
}
}
ESLint Rules
module.exports = {
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended'
],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-unused-vars': 'error'
}
};
CSS Module Types#
Module Declaration - Ensure type safety for CSS Modules - Enable autocomplete - Prevent typos
// styles.d.ts
declare module '*.module.css' {
const classes: {
readonly [key: string]: string;
};
export default classes;
}
Usage with Components
import styles from './Button.module.css';
interface ButtonProps {
className?: string;
variant: keyof typeof styles;
}
const Button: React.FC<ButtonProps> = ({
variant,
className
}) => (
<button className={`${styles[variant]} ${className}`}>
Click me
</button>
);