Essential TypeScript Utility Types

Essential TypeScript Utility Types

·

4 min read

In TypeScript, there are several built-in utility types that make it easier to manipulate types in a flexible, dynamic way. Here are some of the most commonly used utility types:

Utility TypeDescriptionExample

Partial<T>

Makes all properties in T optional.

type PartialUser = Partial<{ name: string; age: number }>; Results in { name?: string; age?: number; }

Required<T>

Makes all properties in T required.

type RequiredUser = Required<{ name?: string; age?: number }>; Results in { name: string; age: number; }

Readonly<T>

Makes all properties in T read-only, preventing modifications.

type ReadonlyUser = Readonly<{ name: string; age: number }>; Results in { readonly name: string; readonly age: number; }

Pick<T, K>

Selects a subset of properties from T.

type PickedUser = Pick<{ name: string; age: number }, 'name'>; Results in { name: string; }

Omit<T, K>

Excludes a subset of properties from T.

type OmittedUser = Omit<{ name: string; age: number }, 'age'>; Results in { name: string; }

Record<K, T>

Constructs an object type with keys of type K and values of type T.

`type RecordExample = Record<'name'

Exclude<T, U>

Excludes types from T that are assignable to U.

`type NonString = Exclude<string

Extract<T, U>

Extracts types from T that are assignable to U.

`type OnlyString = Extract<string

NonNullable<T>

Excludes null and undefined from T.

`type Defined = NonNullable<string

InstanceType<T>

Extracts the instance type of a constructor function type T.

class Example { }
type Instance = InstanceType<typeof Example>; Results in Example

ReturnType<T>

Extracts the return type of a function type T.

type FuncReturn = ReturnType<() => string>; Results in string

Parameters<T>

Extracts the parameter types of a function type T as a tuple.

type FuncParams = Parameters<(name: string, age: number) => void>; Results in [string, number]

ConstructorParameters<T>

Extracts the parameter types of a constructor function type T as a tuple.

type ConstructorParams = ConstructorParameters<ErrorConstructor>; Results in [string]

ThisParameterType<T>

Extracts the type of this parameter in function T.

function sayHello(this: User) { }
type ThisType = ThisParameterType<typeof sayHello>; Results in User

OmitThisParameter<T>

Removes the this parameter from function T, if present.

function fn(this: { id: number }, name: string) { }
type WithoutThis = OmitThisParameter<typeof fn>;

Awaited<T>

Unwraps the type of a promise, useful for async functions.

type Data = Awaited<Promise<string>>; Results in string

Example Usage of Utility Types

  • Using Partial for Optional Parameters

      typescriptCopy codeinterface User {
        name: string;
        age: number;
      }
    
      type PartialUser = Partial<User>; // { name?: string; age?: number; }
    
  • Using Pick to Select Specific Properties

      typescriptCopy codeinterface User {
        name: string;
        age: number;
        email: string;
      }
    
      type UserWithAge = Pick<User, 'name' | 'age'>; // { name: string; age: number; }
    
  • Using Record to Define a Mapping

      typescriptCopy codetype Status = 'success' | 'error' | 'loading';
      type StatusMessages = Record<Status, string>;
    
      const messages: StatusMessages = {
        success: 'Operation was successful',
        error: 'There was an error',
        loading: 'Loading...'
      };
    
  • Using Exclude to Remove Specific Types

      typescriptCopy codetype AllowedTypes = Exclude<string | number | boolean, boolean>; // Result: string | nu
    
  • Using Extract to extract types from a Union
    Imagine you have a interface and want to create union type for properties that are of a specific type, like string.

      typescriptCopy codeinterface User {
        id: number;
        name: string;
        email: string;
        isAdmin: boolean;
      }
    
      type StringProperties = Extract<keyof User, "name" | "email">; // Result: "name" | "email"
    

Using NonNullable to exclude null and undefined from a given type.

You might have an object type where some properties are optional, and you want to create a type where those properties are guaranteed to be defined.

typescriptCopy codeinterface User {
  id: number;
  name: string | null;
  email?: string;
}

type DefinedUser = {
  [K in keyof User]: NonNullable<User[K]>
};

// Result:
// DefinedUser is now:
// {
//   id: number;
//   name: string;
//   email: string;
// }

Using InstanceType to extracts the instance type from a given constructor function type.
Suppose you have a User class, you want to get the type of an instance of User using InstanceType.

typescriptCopy codeclass User {
  id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }

  getInfo() {
    return `${this.name} (ID: ${this.id})`;
  }
}

type UserInstance = InstanceType<typeof User>;

// Now, `UserInstance` is equivalent to:
// {
//   id: number;
//   name: string;
//   getInfo: () => string;
// }

const user: UserInstance = new User(1, "Alice");

console.log(user.getInfo()); // Output: "Alice (ID: 1)"