Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
title date categories tags
Requiring One of Two Properties to Exist in TypeScript
2020-07-12
Development
typescript

How do we represent a function or a React component that requires one of two properties, but not both, to exist in TypeScript?

We can create a base interface and extend that with two more interfaces that include and exclude those specific properties. Let's assume that we expect to have either displayName or firstName for a user.

interface BaseUser {
  id: string;
  age: number;
  // ... other base user properties
}

interface UserWithDisplayName extends BaseUser {
  displayName: string;
  firstName?: never;
}

interface UserWithFirstName extends BaseUser {
  displayName?: never;
  firstName: string;
}

type User = UserWithFirstName | UserWithDisplayName;

We use the "never" keyword to indicate that one property should not be set at the same time as the other. The or ("|") operator is used to create a union where a User can only have one of the exclusive properties.

Now we can use the User type in a function as follows.

const normalizeUser = ({
  age,
  displayName,
  firstName,
  id,
}: User) => { /* ... */}

Or if we're creating a React component:

const UserDetails: React.FunctionComponent<User> = ({
  age,
  displayName,
  firstName,
  id,
}: User) => { /* ... */ };