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">}