Override Part of an Existing Type in Typescript
Tags: react, reactnative, typescript
Published: 2021-10-02 14:26:07

---
title: Override Part of an Existing Type in Typescript
published: true
date: 2021-10-02 00:00:00 UTC
tags: react, reactnative, typescript
description: Changing part of an existing type or interface
canonical_url: https://bionicjulia.com/blog/override-part-of-an-existing-type-in-typescript
---

I've recently been on a mission to eliminate all Typescript errors in our code base at work, and have been steadily chipping away at them systematically, during any downtime I get. I used to dislike Typescript when I first came across it, but really love it now and get an immense sense of satisfaction watching the red squigglies disappear as I work through each Typescript issue, bit by bit. 🤓

It was whilst doing this last week that I came across a situation that was new to me. What I was faced with was this...

I have a component that takes in a prop `item` which has an interface `IItem` defined as:

```jsx
interface IItem extends PickerItemProps {
  iconSource?: ImageSourcePropType;
}

// ...and separately in another file, the React Native library provides this interface
export interface PickerItemProps {
  testID?: string;
  color?: ColorValue;
  label: string;
  value?: any;
}
```

If you're not familiar with Typescript, `extends` effectively merges the `PickerItemProps` interface into `IItem` so that `item` can take this form, for example:

```jsx
const item: IItem = { iconSource: 'imagesourcelocation', label: 'An item' }

// How it's used
;<ParentComponent item={item} />
```

This issue I was faced with involved needing to extend the type `label`. Instead of it always being a plain string, I needed to allow `label` to also take the form of a component (the specific reason behind this has to do with how we're formatting certain bits of text in our app). Ideally then, `label` needs to either be of type `string` OR `JSX.Element`.

Because `label` actually belongs to and is defined in an external package, I didn't want to just change `PickerItemProps` directly (since these might unknowingly be overwritten on upgrades etc.). I therefore naively tried to do this, but quickly ran into Typescript complaining loudly.

```jsx
interface IItem extends PickerItemProps {
  iconSource?: ImageSourcePropType;
  label: string | JSX.Element; // Typescript complains that label already exists
}

// No changes to this
export interface PickerItemProps {
  testID?: string;
  color?: ColorValue;
  label: string;
  value?: any;
}
```

So what to do? The answer lies in using one of Typescript's utility types `Omit`. From the [Typescript documentation](https://www.typescriptlang.org/docs/handbook/utility-types.html), `Omit<Type, Keys>`...

> Constructs a type by picking all properties from Type and then removing Keys (string literal or union of string literals).

What I could do in my case therefore, was to `extends PickerItemProps` without `label`, before then defining label as part of `IItem` like so:

```jsx
interface IItem extends Omit<PickerItemProps, 'label'> {
  iconSource?: ImageSourcePropType;
  label: string | JSX.Element;
}

// Original definition remains untouched
export interface PickerItemProps {
  testID?: string;
  color?: ColorValue;
  label: string;
  value?: any;
}
```

Questions or comments? Find my at my [website](https://bionicjulia.com), [Twitter](https://twitter.com/bionicjulia) or [Instagram](https://instagram.com/bionicjulia).