What is `Prettify` in TypeScript?
Anyone who's worked with TypeScript on any meaningful project has likely encountered a type
that is a union of several other types, e.g.
type User = {
name: string;
} & {
age: number;
} & {
email: string;
}
// The type shows up in editors as:
// { name: string; } & { age: number; } & { email: string; }
There are times where you want to "flatten" these types into a new type, for a variety of reasons. For me, it's usually that I need to extract/narrow a type within those types when annotating a helper function.
Consider the following utility type.
type Prettify<T> = {
[K in keyof T]: T[K];
} & NonNullable<unknown>;
This utility type serves two main purposes:
- It flattens complex intersection types into a simpler object type
- It ensures the resulting type cannot be null or undefined (via
NonNullable<unknown>
)
Using our previous example...
// Without Prettify
type User = {
name: string;
} & {
age: number;
} & {
email: string;
}
// The type shows up in editors as:
// { name: string; } & { age: number; } & { email: string; }
// With Prettify
type PrettifiedUser = Prettify<User>;
// The type shows up in editors as:
// { name: string; age: number; email: string; }
The [K in keyof T]: T[K]
part creates a new mapped type that copies all properties from the original type T
. When combined with the intersection (&
), it forces TypeScript to compute the final shape of the type, resulting in a cleaner, more readable type in IDE tooltips and error messages.
The & NonNullable<unknown>
part ensures that the resulting type cannot be null or undefined. This is particularly useful in the context of email options where you want to ensure required fields are actually present.
This utility type is commonly used in library code to provide better developer experience by making complex types more readable and ensuring type safety.