13 Typescript Utility: A Cheat Sheet for Developer

13 Typescript Utility: A Cheat Sheet for Developer

ยท

4 min read

Typescript is very powerful in terms of type checking, but sometimes it gets tedious when some types are subsets of other types and you need to define type checking for them.

Let's take an example, you have 2 response types:

UserProfileResponse
interface UserProfileResponse {
  id: number;
  name: string;
  email: string;
  phone: string;
  avatar: string;
}
LoginResponse
interface LoginResponse {
  id: number;
  name: string;
}

Instead of defining types of the same context LoginResponse and UserProfileResponse, we can define types for UserProfileResponse and pick some properties for LoginResponse.

type LoginResponse = Pick<UserProfileResponse, "id" | "name">;

Let's understand some utility functions that can help you to write better code.


Uppercase

Constructs a type with all properties of Type set to uppercase.
type Role = "admin" | "user" | "guest";

// Bad practice ๐Ÿ’ฉ
type UppercaseRole = "ADMIN" | "USER" | "GUEST";

// Good practice โœ…
type UppercaseRole = Uppercase<Role>; // "ADMIN" | "USER" | "GUEST"

Lowercase

Constructs a type with all properties of Type set to lowercase. Opposite of Uppercase.
type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice ๐Ÿ’ฉ
type LowercaseRole = "admin" | "user" | "guest";

// Good practice โœ…
type LowercaseRole = Lowercase<Role>; // "admin" | "user" | "guest"

Capitalize

Constructs a type with all properties of the Type set to capitalize.
type Role = "admin" | "user" | "guest";

// Bad practice ๐Ÿ’ฉ
type CapitalizeRole = "Admin" | "User" | "Guest";

// Good practice โœ…
type CapitalizeRole = Capitalize<Role>; // "Admin" | "User" | "Guest"

Uncapitalize

Constructs a type with all properties of Type set to uncapitalize. Opposite of Capitalize.
type Role = "Admin" | "User" | "Guest";

// Bad practice ๐Ÿ’ฉ
type UncapitalizeRole = "admin" | "user" | "guest";

// Good practice โœ…
type UncapitalizeRole = Uncapitalize<Role>; // "admin" | "user" | "guest"

Partial

Constructs a type with all properties of Type set to optional.
interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice ๐Ÿ’ฉ
interface PartialUser {
  name?: string;
  age?: number;
  password?: string;
}

// Good practice โœ…
type PartialUser = Partial<User>;

Required
Constructs a type consisting of all properties of Type set to required. Opposite of Partial.
interface User {
  name?: string;
  age?: number;
  password?: string;
}

// Bad practice ๐Ÿ’ฉ
interface RequiredUser {
  name: string;
  age: number;
  password: string;
}

// Good practice โœ…
type RequiredUser = Required<User>;

Readonly

Constructs a type consisting of all properties of the Type set to read-only.
interface User {
  role: string;
}

// Bad practice ๐Ÿ’ฉ
const user: User = { role: "ADMIN" };
user.role = "USER";

// Good practice โœ…
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = { role: "ADMIN" };
user.role = "USER"; // Error: Cannot assign to 'role' because it is a read-only property.

Record<K extends string, T>

Constructs a type with a set of properties K of type T. Each property K is mapped to the type T.
interface Address {
  street: string;
  pin: number;
}

interface Addresses {
  home: Address;
  office: Address;
}

// Alternative โœ…
type AddressesRecord = Record<"home" | "office", Address>;

Pick<Type, keys>

Pick only the properties of the Type whose keys are in the union type keys.
interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice ๐Ÿ’ฉ
interface UserPartial {
  name: string;
  age: number;
}

// Good practice โœ…
type UserPartial = Pick<User, "name" | "age">;

Omit<Type, keys>

Omit only the properties of the Type whose keys are in the union type keys.
interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice ๐Ÿ’ฉ
interface UserPartial {
  name: string;
  age: number;
}

// Good practice โœ…
type UserPartial = Omit<User, "password">;

Exclude<Type, Excluded>

Constructs a type with all properties of Type except for those whose keys are in the union type Excluded.
type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice ๐Ÿ’ฉ
type NonAdminRole = "USER" | "GUEST";

// Good practice โœ…
type NonAdmin = Exclude<Role, "ADMIN">; // "USER" | "GUEST"

Extract<Type, Extract>

Constructs a type with all properties of Type whose keys are in the union type Extract.
type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice ๐Ÿ’ฉ
type AdminRole = "ADMIN";

// Good practice โœ…
type Admin = Extract<Role, "ADMIN">; // "ADMIN"

NonNullable

Constructs a type with all properties of Type set to non-nullable.
type Role = "ADMIN" | "USER" | null;

// Bad practice ๐Ÿ’ฉ
type NonNullableRole = "ADMIN" | "USER";

// Good practice โœ…
type NonNullableRole = NonNullable<Role>; // "ADMIN" | "USER"

Thank you for reading ๐Ÿ˜Š

Got any questions or additional? please leave a comment.

Must Read If you haven't

React best practices and patterns to reduce code - Part 1

React best practices and patterns to reduce code - Part 2

React.js state management using signals

useAsync hook with cache

More content at Hashnode.
Catch me on: Github, Twitter, LinkedIn, Medium, Dev.to, Blogspot, Stackblitz

Did you find this article valuable?

Support Rahul Sharma by becoming a sponsor. Any amount is appreciated!

ย