TypeScript Best Practices for 2025
TypeScript Best Practices for 2025
TypeScript has become essential for modern web development. Here are the best practices I follow in 2025.
1. Use Strict Mode
Always enable strict mode in tsconfig.json:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true
}
}
2. Avoid 'any' Type
Use 'unknown' instead:
// Bad
function process(data: any) {}// Good
function process(data: unknown) {
if (typeof data === 'string') {
// TypeScript knows data is string here
}
}
3. Use Type Guards
function isUser(obj: unknown): obj is User {
return (
typeof obj === 'object' &&
obj !== null &&
'name' in obj &&
'email' in obj
)
}
4. Leverage Utility Types
type User = {
id: string
name: string
email: string
password: string
}// Pick specific properties
type PublicUser = Pick
// Omit sensitive data
type SafeUser = Omit
// Make all properties optional
type PartialUser = Partial
// Make all properties required
type RequiredUser = Required
5. Use Generics Wisely
function getFirstElement(arr: T[]): T | undefined {
return arr[0]
}const num = getFirstElement([1, 2, 3]) // number | undefined
const str = getFirstElement(['a', 'b']) // string | undefined
6. Discriminated Unions
type Success = {
status: 'success'
data: User
}type Error = {
status: 'error'
message: string
}
type Result = Success | Error
function handleResult(result: Result) {
if (result.status === 'success') {
// TypeScript knows result.data exists
console.log(result.data)
} else {
// TypeScript knows result.message exists
console.log(result.message)
}
}
7. Const Assertions
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
} as const// config.apiUrl is 'https://api.example.com', not string
// config is readonly
8. Template Literal Types
type EventName = 'click' | 'focus' | 'blur'
type EventHandler = on${Capitalize}
// 'onClick' | 'onFocus' | 'onBlur'
9. Branded Types
type UserId = string & { __brand: 'UserId' }
type ProductId = string & { __brand: 'ProductId' }function getUser(id: UserId) {}
const userId = 'user-123' as UserId
const productId = 'prod-456' as ProductId
getUser(userId) // OK
getUser(productId) // Error!
10. Use satisfies Operator
type Config = {
apiUrl: string
timeout: number
}const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
extra: 'allowed', // OK
} satisfies Config
Conclusion
TypeScript is powerful when used correctly. These practices will help you write safer, more maintainable code.
Need TypeScript expertise? I'm available for code reviews and consulting. [Contact me](/contact)
About the Author
Monank Sojitra
Freelance Full Stack Developer | 4+ Years Experience
Having built 10+ production applications, I focus on performance, scalability, and clean code that teams love to maintain.
I'm a freelance full stack developer with 4+ years of experience building modern web and mobile applications. I specialize in helping startups and businesses achieve their goals with clean code, fast delivery, and measurable results. My work has helped clients achieve 70% automation, 3x faster development, and significant cost savings.