Lesson 46 of 60 – Utility Types
77%

Utility Types in TypeScript

Utility types are built-in TypeScript types that help you create new types from existing types. They are useful when you want to modify, reuse, or transform an existing type without writing everything again.

Note: Common utility types include Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, ReturnType, and Parameters.

1. What are Utility Types?

Utility types are predefined TypeScript types that can transform existing types into new types.

interface Student {
    id: number;
    name: string;
    course: string;
}

Instead of creating another interface manually, utility types can modify this existing type.

2. Why Use Utility Types?

Utility types reduce repeated code and make type definitions easier to maintain.

interface Student {
    id: number;
    name: string;
    course: string;
}

type StudentUpdate =
    Partial<Student>;

The existing Student type is reused instead of creating a new type from scratch.

3. Partial<T>

Partial<T> makes all properties of a type optional.

interface Student {
    id: number;
    name: string;
    course: string;
}

type StudentUpdate =
    Partial<Student>;

const update: StudentUpdate = {
    name: "Rahul"
};

Only the properties that need to be updated are required.

4. Partial with Multiple Properties

interface Student {
    id: number;
    name: string;
    course: string;
}

type StudentUpdate =
    Partial<Student>;

const update: StudentUpdate = {
    name: "Amit",
    course: "React Native"
};

Any combination of the original properties can be provided.

5. Required<T>

Required<T> makes all optional properties required.

interface Student {
    id: number;
    name?: string;
    course?: string;
}

type CompleteStudent =
    Required<Student>;

const student: CompleteStudent = {
    id: 101,
    name: "Amit",
    course: "TypeScript"
};

6. Readonly<T>

Readonly<T> makes the properties of a type readonly.

interface Student {
    id: number;
    name: string;
}

const student:
    Readonly<Student> = {

    id: 101,
    name: "Amit"

};

The properties cannot be reassigned through the readonly type.

7. Readonly Example

interface User {
    id: number;
    name: string;
}

const user:
    Readonly<User> = {

    id: 101,
    name: "Amit"

};

// Not allowed:
// user.name = "Rahul";

Readonly types are useful when data should not be modified after creation.

8. Pick<T, K>

Pick<T, K> creates a new type containing selected properties from an existing type.

interface Student {
    id: number;
    name: string;
    course: string;
    age: number;
}

type StudentBasic =
    Pick<Student, "id" | "name">;

const student: StudentBasic = {

    id: 101,
    name: "Amit"

};

9. Pick Multiple Properties

interface Student {
    id: number;
    name: string;
    course: string;
    age: number;
}

type StudentDetails =
    Pick<
        Student,
        "name" | "course" | "age"
    >;

const details: StudentDetails = {

    name: "Rahul",
    course: "React Native",
    age: 20

};

10. Omit<T, K>

Omit<T, K> creates a new type by removing selected properties from an existing type.

interface Student {
    id: number;
    name: string;
    course: string;
    age: number;
}

type StudentWithoutId =
    Omit<Student, "id">;

const student: StudentWithoutId = {

    name: "Amit",
    course: "TypeScript",
    age: 20

};

11. Omit Multiple Properties

interface Student {
    id: number;
    name: string;
    course: string;
    age: number;
}

type PublicStudent =
    Omit<
        Student,
        "id" | "age"
    >;

const student: PublicStudent = {

    name: "Amit",
    course: "JavaScript"

};

Multiple properties can be omitted at the same time.

12. Record<K, T>

Record<K, T> creates an object type whose property keys are defined by K and whose values have type T.

type Roles =
    "admin" | "teacher" | "student";

const permissions:
    Record<Roles, boolean> = {

    admin: true,
    teacher: true,
    student: false

};

13. Record with Student Data

interface Student {
    name: string;
    course: string;
}

const students:
    Record<number, Student> = {

    101: {
        name: "Amit",
        course: "TypeScript"
    },

    102: {
        name: "Rahul",
        course: "React Native"
    }

};

console.log(
    students[101].name
);

14. Exclude<T, U>

Exclude<T, U> removes types from a union.

type Status =
    "pending" |
    "approved" |
    "rejected";

type ActiveStatus =
    Exclude<
        Status,
        "rejected"
    >;

let status: ActiveStatus =
    "approved";

15. Extract<T, U>

Extract<T, U> keeps only the types from T that are also present in U.

type Status =
    "pending" |
    "approved" |
    "rejected";

type Allowed =
    Extract<
        Status,
        "approved" | "rejected"
    >;

let status: Allowed =
    "approved";

16. NonNullable<T>

NonNullable<T> removes null and undefined from a type.

type Value =
    string | null | undefined;

type RequiredValue =
    NonNullable<Value>;

let value: RequiredValue =
    "Hello";

The resulting type is string.

17. ReturnType<T>

ReturnType<T> extracts the return type of a function.

function getStudent() {

    return {
        id: 101,
        name: "Amit"
    };

}

type Student =
    ReturnType<typeof getStudent>;

const student: Student = {

    id: 102,
    name: "Rahul"

};

18. Parameters<T>

Parameters<T> extracts the parameter types of a function as a tuple.

function createStudent(
    name: string,
    age: number
) {

    return {
        name,
        age
    };

}

type StudentParameters =
    Parameters<
        typeof createStudent
    >;

const values:
    StudentParameters = [
        "Amit",
        20
    ];

19. ConstructorParameters<T>

ConstructorParameters<T> extracts the parameter types of a constructor.

class Student {

    constructor(
        public name: string,
        public age: number
    ) {}

}

type StudentParameters =
    ConstructorParameters<
        typeof Student
    >;

const values:
    StudentParameters = [
        "Amit",
        20
    ];

20. InstanceType<T>

InstanceType<T> creates the instance type of a constructor function.

class Student {

    constructor(
        public name: string
    ) {}

}

type StudentInstance =
    InstanceType<typeof Student>;

const student:
    StudentInstance =
    new Student("Amit");

21. Awaited<T>

Awaited<T> represents the type that results after a promise is resolved.

type Result =
    Awaited<Promise<string>>;

let value: Result =
    "Hello";

The resulting type is string.

22. Combining Utility Types

Utility types can be combined to create more useful types.

interface Student {

    id: number;
    name: string;
    course: string;
    age: number;

}

type StudentUpdate =
    Partial<
        Omit<Student, "id">
    >;

const update: StudentUpdate = {

    name: "Rahul"

};

Here, id is removed and the remaining properties become optional.

23. Utility Types for API Data

interface Student {

    id: number;
    name: string;
    course: string;

}

type StudentCreate =
    Omit<Student, "id">;

const student: StudentCreate = {

    name: "Amit",
    course: "TypeScript"

};

This pattern is useful when an ID is generated by the server.

24. Utility Types in React

Utility types can make React component props reusable and flexible.

interface User {

    id: number;
    name: string;
    email: string;

}

type UserPreview =
    Pick<
        User,
        "name" | "email"
    >;

function UserCard(
    props: UserPreview
) {

    return (
        <div>
            {props.name}
            <br />
            {props.email}
        </div>
    );

}

25. Utility Types in React Native

Utility types are useful when creating reusable React Native components with selected or optional properties.

interface User {

    id: number;
    name: string;
    email: string;
    phone: string;

}

type UserCardProps =
    Pick<
        User,
        "name" | "email"
    >;

function UserCard(
    props: UserCardProps
) {

    return (
        <View>

            <Text>
                {props.name}
            </Text>

            <Text>
                {props.email}
            </Text>

        </View>
    );

}

26. Common Utility Type Mistakes

  • Using any when a utility type is more appropriate.
  • Using Partial when all properties are actually required.
  • Using Pick with properties that do not exist.
  • Removing important properties with Omit.
  • Using complex utility type combinations unnecessarily.
  • Forgetting what the resulting type contains.

27. Most Common Utility Types

  • Partial<T> — makes properties optional.
  • Required<T> — makes properties required.
  • Readonly<T> — makes properties readonly.
  • Pick<T, K> — selects properties.
  • Omit<T, K> — removes properties.
  • Record<K, T> — creates mapped object types.
  • Exclude<T, U> — removes union members.
  • Extract<T, U> — keeps matching union members.
  • NonNullable<T> — removes null and undefined.
  • ReturnType<T> — gets a function's return type.
  • Parameters<T> — gets function parameter types.

28. Choosing the Right Utility Type

Choose the utility type according to what you need to do.

// Make properties optional
type Update =
    Partial<Student>;

// Select properties
type Basic =
    Pick<Student, "id" | "name">;

// Remove properties
type Public =
    Omit<Student, "id">;

// Make properties readonly
type Fixed =
    Readonly<Student>;

29. Complete Practical Example

interface Student {

    id: number;
    name: string;
    course: string;
    email: string;
    age: number;

}

// Data required when creating a student
type CreateStudent =
    Omit<Student, "id">;

// Data allowed when updating a student
type UpdateStudent =
    Partial<
        Omit<Student, "id">
    >;

// Data displayed in a small card
type StudentPreview =
    Pick<
        Student,
        "name" | "course"
    >;

const newStudent:
    CreateStudent = {

    name: "Amit",
    course: "React Native",
    email: "amit@example.com",
    age: 20

};

const update:
    UpdateStudent = {

    course: "TypeScript"

};

const preview:
    StudentPreview = {

    name: "Amit",
    course: "React Native"

};

console.log(newStudent);
console.log(update);
console.log(preview);

30. Utility Types Summary

Utility types make it easier to transform existing types and create new reusable types.

interface Student {

    id: number;
    name: string;
    course: string;

}

type UpdateStudent =
    Partial<Student>;

type StudentPreview =
    Pick<
        Student,
        "name" | "course"
    >;

type PublicStudent =
    Omit<Student, "id">;

Utility types are especially useful in large TypeScript, React, and React Native applications where many types are based on existing data structures.

📌 Key Points

  • Utility types transform existing TypeScript types.
  • Partial makes properties optional.
  • Required makes properties required.
  • Readonly prevents property reassignment.
  • Pick selects specific properties.
  • Omit removes specific properties.
  • Record creates object types with defined keys and values.
  • Exclude removes members from a union.
  • Extract keeps matching members from a union.
  • NonNullable removes null and undefined.
  • ReturnType extracts a function's return type.
  • Parameters extracts function parameter types.
  • ConstructorParameters extracts constructor parameters.
  • InstanceType creates an instance type from a constructor.
  • Awaited represents the resolved value type of a promise.
  • Utility types are widely useful in React and React Native projects.

🧠 Quick Quiz

Question: Which utility type makes all properties of a type optional?