Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

TypeScript Utility Types: Partial, Pick, Omit, Record and Awaited

What Are Utility Types?

Utility types are built-in TypeScript helpers that transform existing types into new types. They help you avoid repeating similar object shapes again and again.

For example, a user record may have many required fields in the database, but an update form may allow only a few fields to be changed. Instead of writing a second almost-identical type by hand, you can derive it with a utility type.

Deriving Types
type User = {
  id: number;
  name: string;
  email: string;
  active: boolean;
};

type UserUpdate = Partial<User>;
type UserPreview = Pick<User, "id" | "name">;

const patch: UserUpdate = { active: false };
const preview: UserPreview = { id: 1, name: "Admin" };

Partial and Required

Partial<T> makes every property optional. This is useful for patch/update payloads where a caller sends only the fields that changed.

Required<T> does the opposite: it makes every property required. This can be useful after validation, when a previously optional configuration object has been normalized into a complete object.

Partial and Required
type Profile = {
  name: string;
  bio?: string;
  avatarUrl?: string;
};

type ProfilePatch = Partial<Profile>;
type CompleteProfile = Required<Profile>;

const updateProfile = (id: number, patch: ProfilePatch) => {
  console.log("Updating", id, patch);
};

const complete: CompleteProfile = {
  name: "Asha",
  bio: "Frontend developer",
  avatarUrl: "/images/asha.png",
};

updateProfile(1, { bio: "TypeScript learner" });

Pick and Omit

Pick<T, K> creates a type with only selected properties from another type. It is helpful when a screen, component, or API response should expose a smaller version of a larger model.

Omit<T, K> removes selected properties. It is useful when a type is mostly correct but contains fields that should not be visible, editable, or accepted from a client.

Public and Editable Models
type Product = {
  id: number;
  name: string;
  price: number;
  internalCost: number;
  createdAt: string;
};

type ProductCard = Pick<Product, "id" | "name" | "price">;
type PublicProduct = Omit<Product, "internalCost">;

const card: ProductCard = {
  id: 10,
  name: "Keyboard",
  price: 1499,
};

const product: PublicProduct = {
  id: 10,
  name: "Keyboard",
  price: 1499,
  createdAt: "2026-05-24",
};

Record

Record<K, V> creates an object type where the keys have type K and the values have type V. It is commonly used for dictionaries, lookup tables, feature flags, translations, and grouped data.

Use Record when the object is used like a map. If every property has a different meaning, a normal object type is usually clearer.

Typed Dictionaries
type FeatureName = "darkMode" | "betaDashboard" | "newEditor";
type FeatureFlags = Record<FeatureName, boolean>;

const flags: FeatureFlags = {
  darkMode: true,
  betaDashboard: false,
  newEditor: true,
};

type ErrorMessages = Record<number, string>;

const messages: ErrorMessages = {
  400: "Bad request",
  401: "Login required",
  500: "Server error",
};

Readonly and Mutable Thinking

Readonly<T> makes all properties read-only at the type level. It is useful when a value should be treated as immutable after creation, such as configuration, constants, or values passed into pure functions.

Readonly does not deeply freeze nested objects at runtime. It is a TypeScript-level protection for the properties of that type.

Readonly Configuration
type AppConfig = {
  appName: string;
  apiBaseUrl: string;
  retries: number;
};

const config: Readonly<AppConfig> = {
  appName: "Tutorials Logic",
  apiBaseUrl: "https://api.example.com",
  retries: 3,
};

// config.retries = 5;
// Error: retries is read-only.

ReturnType, Parameters and Awaited

Some utility types inspect functions. ReturnType<T> gets the return type of a function. Parameters<T> gets a tuple of parameter types. These are useful when you want helper code to stay connected to an existing function signature.

Awaited<T> unwraps a promise-like type. It is helpful when working with async service functions because you can describe the resolved value without manually copying the type.

Function Utility Types
async function fetchUser(id: number) {
  return {
    id,
    name: "Admin",
    active: true,
  };
}

type FetchUserArgs = Parameters<typeof fetchUser>;
type FetchUserPromise = ReturnType<typeof fetchUser>;
type LoadedUser = Awaited<FetchUserPromise>;

const args: FetchUserArgs = [1];
const user: LoadedUser = {
  id: 1,
  name: "Admin",
  active: true,
};

Useful Utility Types

UtilityPurposeCommon Use
Partial<T>Make all properties optionalPatch/update payloads
Required<T>Make all properties requiredValidated configuration
Pick<T, K>Select specific propertiesPreview cards and small DTOs
Omit<T, K>Remove specific propertiesPublic models without private fields
Readonly<T>Prevent property assignmentConfiguration and immutable inputs
Record<K, V>Create a typed key-value objectDictionaries and lookups
ReturnType<T>Extract a function return typeHelper types based on services
Awaited<T>Get resolved Promise valueAsync data types
Key Takeaways
  • Utility types transform existing types instead of forcing you to duplicate them manually.
  • Partial and Required change whether properties are optional.
  • Pick and Omit create focused versions of larger models.
  • Record is best for typed dictionaries and lookup objects.
  • Function utility types help keep helper types connected to real function signatures.

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.