Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Coding Standards|Rules, conventions, and best practices I follow and recommend to teams

TypeScript

Use TypeScript to enhance safety, clarity, and developer experience.

TypeScript helps catch errors early, improve code readability, and provide powerful tooling support. Proper use of types, generics, enums, and interfaces leads to more maintainable and scalable applications.

Use TypeScript’s type system — don’t bypass it

Avoid using any or casting types unless absolutely necessary. Let TypeScript help you catch errors through proper typings.

TypeScript
Copied!
1function process(data: any) {
2  const user = data as User;
3  return user.id;
4}
TypeScript
Copied!
1function process(data: unknown): number {
2  if (!isUser(data)) throw new Error("Invalid input");
3  return data.id;
4}

Use built-in utility types when possible

TypeScript provides many built-in utility types (Partial, Pick, Omit, etc.) that make type transformations cleaner and safer.

TypeScript
Copied!
1type UserPreview = {
2  name: string;
3  age: number;
4};
TypeScript
Copied!
type UserPreview = Pick<User, 'name' | 'age'>;

Prefer union types over enums for simple sets

For short, fixed sets of values, use union types ('draft' | 'published') instead of enum. They're lighter, simpler, and fully type-safe.

TypeScript
Copied!
1enum Status {
2  Draft = 'draft',
3  Published = 'published',
4}
TypeScript
Copied!
type Status = 'draft' | 'published';

Write custom type guards to narrow unknown types

For input validation or unknown sources (e.g., API responses), write reusable type guards that protect downstream logic.

TypeScript
Copied!
1function printUser(user: any) {
2  if (user && user.id) {
3    console.log(user.name);
4  }
5}
TypeScript
Copied!
1function isUser(obj: unknown): obj is User {
2  return typeof obj === 'object' && obj !== null && 'id' in obj;
3}
4
5function printUser(user: unknown) {
6  if (isUser(user)) {
7    console.log(user.name);
8  }
9}

Explicitly type return values in exported functions

Always specify return types for functions that are exported or reused. This improves type inference, refactoring safety, and readability.

TypeScript
Copied!
1export function getUser(id: string) {
2  return db.find(id);
3}
TypeScript
Copied!
1export function getUser(id: string): Promise<User | null> {
2  return db.find(id);
3}

Prefer 'keyof', 'Record', and indexed types for flexibility

Use advanced TS utilities like keyof and Record to build type-safe dynamic structures.

TypeScript
Copied!
1const roles: { [key: string]: boolean } = {
2  admin: true,
3  user: false
4};
TypeScript
Copied!
1type Role = 'admin' | 'user';
2const roles: Record<Role, boolean> = {
3  admin: true,
4  user: false
5};

Use labeled tuples for clarity in return types

Label tuple elements to improve clarity when returning multiple values from a function.

TypeScript
Copied!
function useFeature(): [boolean, () => void] { ... }
TypeScript
Copied!
function useFeature(): [enabled: boolean, toggle: () => void] { ... }
Styleguide: TypeScript | Yevhen Klymentiev