Jacob Paris
← Back to all content

Partially match a subset of an object's fields in Typescript

I have a type Contact that gets used in multiple places. A Person can have a contact, so it becomes a field on their type, but also a Company can have a contact.

export interface Contact {
firstName: string
lastName: string
phoneNumber: string
}
export type Person = {
id: string
contact: Contact
}
export type Company = {
id: string
contact: Contact
}
const company = {
id: uuid(),
contact: {
phoneNumber: "+123456790",
},
}

produces the error

Type '{ phoneNumber: string; }' is missing the following properties from type 'Contact': firstName, lastName

Typescript expects that all implementations of the Contact type use every defined field, but since a business doesn't need to have a first or last name, I don't want to have to add those.

The solution

There are several typescripty ways to solve this

New type

One solution is to stop messing around with reusability and just make a new type for this clearly different use-case.

export interface CompanyContact {
phoneNumber: string
}
export type Company = {
id: string
contact: CompanyContact
}

Partial

The Partial type makes every field optional

export type Company = {
id: string
contact: Partial<Contact>
}

Pick

Pick allows you to pick specifically which fields you want

export type Company = {
id: string
contact: Pick<Contact, "phoneNumber">
}
Professional headshot

Hi, I'm Jacob

Hey there! I'm a developer, designer, and digital nomad with a background in lean manufacturing.

About once per month, I send an email with new guides, new blog posts, and sneak peeks of what's coming next.

Everyone who subscribes gets access to the source code for this website and every example project for all my tutorials.

Stay up to date with everything I'm working on by entering your email below.

Unsubscribe at any time.