Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove fields from a TypeScript interface via extension

Tags:

typescript

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?

like image 753
ffxsam Avatar asked Aug 12 '18 00:08

ffxsam


People also ask

Can TypeScript interfaces be extended?

TypeScript interfaces can extend classes. This means that an interface can inherit the members of a class but not their implementation. The class, in this case, acts as an interface with all the members declared without providing the implementation.

Can interface extend two interfaces TypeScript?

You can extend from as many interfaces as necessary by separating the interfaces with a comma. You are not required to add any new members to the final interface and can use the extends keyword to simply combine interfaces.

Can TypeScript interface have methods?

A TypeScript Interface can include method declarations using arrow functions or normal functions, it can also include properties and return types. The methods can have parameters or remain parameterless.


1 Answers

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. Hope that helps. Good luck!

like image 89
jcalz Avatar answered Sep 21 '22 17:09

jcalz