91

Let's say there's an interface that I don't have control over:

interface Original {
  name: string;
  size: number;
  link: SomeType;
}

I want to extend this interface, but actually remove link so I end up with a new interface that is effectively:

interface OriginalLite {
  name: string;
  size: number;
}

How can I do this?

3 Answers 3

192

You can use mapped and conditional types to achieve this. Usually we call what you're trying to do Omit:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

(for TS3.5+, the Omit utility type is included in the standard library, so you don't have to define it yourself anymore)

So Omit<T, K> is basically the same as T but with none of the properties in K. You can do the following to make a new interface called OriginalLite which is missing only link:

interface OriginalLite extends Omit<Original, 'link'> {}

Note that you are not extending Original. That's because to "extend" in TypeScript means to make a type more specific (a.k.a. "narrowing"), but in your case what you are doing is making it less specific (a.k.a. "widening"). So that's why extends Original does not appear in that definition. I assume that's okay with you.

Let's test it:

declare const originalLite: OriginalLite;
originalLite.name; // string
originalLite.size; // number
originalLite.link; // error, property 'link' does not exist on type 'OriginalLite'

Looks good.

Sign up to request clarification or add additional context in comments.

4 Comments

For people looking to exclude multiple properties, that would be: interface OriginalLite extends Omit<Original, 'link'|'size'> {}
Here is a list of all Utility Types: typescriptlang.org/docs/handbook/utility-types.html
@jcalz based on op's requirements just type OriginalLite = Omit<Original, "link"> is fine? is he wrong in extending into another interface without additional properties?
If they don't care about the difference between a type alias and an interface (and usually you don't really care), yes, that's fine. And since Omit was added to the standard library in TS3.5 there's no need to implement it ourselves anymore.
14

Sample of omitting multiple unwanted properties from a type, and adding new custom properties.

type UnwantedKeys = "key1" | "key2"

interface MyNewType extends Omit<Original, <UnwantedKeys>> {
  newProp1: string
  newProp2: number
}

3 Comments

What's different from the accepted answer ?
I’m to the point.
11

Just to add: if you don't have a list of keys you want to remove but only interface you can use keyof to get a list of keys and omit them.

Example:

interface RemoveThoseKeys {
  removeMe1: unknown
  removeMe2: unknown
}

interface AllKeys {
  keep1: unknown
  keep2: unknown
  removeMe1: unknown
  removeMe2: unknown
}

type KeysAfterRemoval = Omit<AllKeys, keyof RemoveThoseKeys>

If you instantiate an object with type KeysAfterRemoval and hit auto-completion in your IDE you should get only keep1 and keep2.

IDE autocompletion

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.