📘Developer

TypeScript Utility Types: The Ones Worth Actually Learning

TypeScript has 20+ built-in utility types. Most tutorials list all of them. Here are the 8 you'll use constantly and how to actually think about them.

7 min readJanuary 18, 2026By FreeToolKit TeamFree to read

TypeScript's utility types show up in job interviews and documentation but rarely in explanations of when you'd actually use them. Let me fix that.

Partial<T> — For Update Operations

You have a User type with 12 required fields. But your updateUser function only changes 1-3 fields at a time. You don't want to require the caller to pass all 12. Partial<User> makes every field optional without you defining a new type.

Required<T> — The Opposite

Takes a type with optional fields and makes them all required. Use this after validation — once you've confirmed an object has all required fields, cast it to Required<T> to stop TypeScript asking you to handle undefined everywhere downstream.

Pick<T, K> and Omit<T, K> — For Slimming Types

Pick lets you select specific fields. Omit removes specific fields. Both create new types. Use them for DTOs — Data Transfer Objects — where your API response should only expose certain fields from your database model.

Record<K, V> — For Typed Dictionaries

Cleaner than { [key: string]: V }. Use Record<string, number> for lookup tables, Record<UserId, UserProfile> for caches, Record<'success' | 'error' | 'pending', string> for status message maps.

ReturnType<T> and Parameters<T> — For Working With External Types

When a library function returns a complex type that isn't exported, use ReturnType<typeof libraryFn> to capture it. When you need the argument types of a function, Parameters<typeof fn> gives you a tuple. These save you from manually copying type definitions from library source code.

NonNullable<T> — For After Null Checks

NonNullable<string | null | undefined> returns string. After you've checked that a value isn't null, use NonNullable to communicate that to the type system. Or use it in mapped types to strip null from every field of an API response type.

Frequently Asked Questions

What is the most useful TypeScript utility type?+
Partial<T> and Pick<T, K> are the ones I reach for most often. Partial makes all fields of a type optional — perfect for update functions where you only want to change some fields. Pick creates a new type with only the fields you specify — great for form types that only expose certain fields of a larger model. If I had to choose one, Partial is the one I'd miss most. It solves the update-payload problem that every CRUD application has without requiring you to define a separate UpdateUserInput type from scratch.
When should I use Pick vs Omit?+
Use Pick when you're choosing a small subset of a large type. Use Omit when you want almost everything except a few fields. The decision is ergonomic: if you're keeping 3 out of 20 fields, Pick is cleaner. If you're removing 2 out of 20 fields, Omit is cleaner. They're mathematically equivalent for a given type, just different ways to express the same transformation. A common mistake is using both Pick and Omit on the same type — that's usually a sign you need to define a new, explicit interface instead.
What's the difference between Readonly and const in TypeScript?+
const prevents reassignment of a variable. Readonly prevents modification of an object's properties. They solve different problems. const user = {} still lets you do user.name = 'Alice'. Readonly<User> prevents any property assignment on the object. They can be used together: const user: Readonly<User> = {} prevents both reassignment and property mutation. Note that Readonly is shallow — it doesn't recursively make nested objects readonly. For deep immutability, you need a recursive ReadonlyDeep type or a library like ts-essentials.
What is the ReturnType utility type used for?+
ReturnType<typeof someFunction> extracts the return type of a function. This is most useful when you're working with functions from external libraries where the return type isn't exported. Instead of manually writing out the complex type, you derive it from the function itself. Example: if a third-party library function returns a complex object type but doesn't export that type, ReturnType<typeof thirdPartyFn> gives you the type automatically. It's also useful for keeping derived types synchronized — if the function's return type changes, everything using ReturnType updates automatically.

🔧 Free Tools Used in This Guide

FT

FreeToolKit Team

FreeToolKit Team

We build free browser-based tools and write practical guides that skip the fluff.

Tags:

developertypescriptprogramming