Advanced TypeScript: Partial Is a Mapped Type
Welcome to the Partial Is a Mapped Type lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Now that we've seen mapped types, we can revisit the
Partialutility type.Partialisn't a special part of the TypeScript compiler! It's a regular mapped type that we can define ourselves if we want to.(We'll name our type
OurPartialto avoid conflicting with the built-inPartialtype.)>
type OurPartial<T> = {[P in keyof T]?: T[P];};type User = {email: stringage: number};- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
const user: OurPartial<User> = {email: 'amir@example.com',};user;Result:
{email: 'amir@example.com'} - Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
const user: OurPartial<User> = {age: 36,};user;Result:
{age: 36} There are three important things happening in this type.
First, it's generic. Instead of referencing a specific type like
User, theOurPartialtype works with any object type. If we writeOurPartial<{name: string, age: number}>, thenOurPartialmaps over the properties "name" and "age".Second,
OurPartialdoesn't change the individual properties' types. It leaves them all asT[P]. The originalUsertype hasemail: string, soOurPartial<User>also has anemailproperty, and it's also a string.Third,
OurPartialmakes the properties optional with the?syntax:[P in keyof T]?: T[P]. The originalUserhademail: string, soOurPartial<User>hasemail?: string.At first, the syntax in
[P in keyof T]?: T[P]may look strange. But it's the same optional property syntax that we've seen before, likeemail?: string. Here, the property name is[P in keyof T]instead ofemail, and the property type isT[P]instead ofstring.Many utility types are implemented as mapped types. For example, we might want a
Nullabletype that makes all properties nullable, rather than making them optional. The process here is similar toOurPartial, except that we union the existing type withnull. UnlikePartial, we don't need to use the optional property syntax (propertyName?: SomeType).Here's a code problem:
Sometimes we want a
Nullable<T>utility type that makes every object property nullable. For example, ifThas a number property, thenNullable<T>should have the same property, but with the typenumber | null. Finish the partially-writtenNullabletype below.type Nullable<T> = {[K in keyof T]: T[K] | null};type Company = {name: stringyearFounded: number};const company1: Nullable<Company> = {name: 'Shure', yearFounded: null};const company2: Nullable<Company> = {name: null, yearFounded: 1925};/* We pull the properties back out to make sure your types are correct. */const name: string | null = company1.name;const yearFounded: number | null = company1.yearFounded;[name, yearFounded];- Goal:
['Shure', null]
- Yours:
['Shure', null]