Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override the properties of an interface in TypeScript

I know that overriding properties of an interface in an extended interface, modifying their types, is forbidden.

I'm looking for an alternative solution that would allow me to not copy the contents of the first interface (it's pretty big).

Here is below my first naive approach. Given that base interface:

interface OrginalInterface {
    title?: string;
    text?: string;
    anotherProperty?: SomeType;
    // lots of other properties
}

This interface is defined in a library. I can't modify it (ie. add generics, for example) just to satisfy my needs in the extended interface.

In the extended interface, used by a wrapper library (mine), I want to reuse the existing interface, while making some fields having a different type:

interface ExtendedInterface extends OriginalInterface {
    title?: string | ReactElement<any>;
    text?: string | ReactElement<any>;
}

But this is not possible.

error TS2430: Interface 'ExtendedInterface' incorrectly extends interface 'OriginalInterface'.
  Types of property 'title' are incompatible.
    Type 'ReactElement<any>' is not assignable to type 'string'.

I also tried to merge the two interfaces together:

type Extended = OriginalInterface & NewInterfaceWithOverridingPropertiesOnly;

While this passes the compilation, it does not work. If you declare a variable with this type, you'll only be able to assign objects that have a compatible structure with OriginalInterface.

I feel like TypeScript's type-system don't offers me any other way to express my need to declare a new type derived from OrginalInterface. I don't need the new type to be assignable to OriginalInterface ; I just need it to reuse most properties of OriginalInterface.

I'd need something like mapped types with a condition on which properties are affected. Maybe Conditional types from pre-release TypeScript 2.8? Or should I copy the first interface's contents?

like image 805
Morgan Touverey Quilling Avatar asked Mar 09 '18 17:03

Morgan Touverey Quilling


People also ask

Can we have an interface with optional and default properties in TypeScript?

In TypeScript, interfaces represent the shape of an object. They support many different features like optional parameters but unfortunately do not support setting up default values.

Can we inherit interface in TypeScript?

An interface can be extended by other interfaces. In other words, an interface can inherit from other interface. Typescript allows an interface to inherit from multiple interfaces. Use the extends keyword to implement inheritance among interfaces.

Can we define method in interface TypeScript?

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

Using TypeScript Omit:

Omit<T,K>

Constructs a type by picking all properties from T and then removing K

// original interface
interface A {
  a: number;
  b: number; // we want string type instead of number
}

// Remove 'b'
type BTemp = Omit<A, 'b'>;

// extends A (BTemp) and redefine b
interface B extends BTemp {
  b: string;
}

const a: B = {
  a: 5,
  b: 'B'
}

enter image description here

like image 131
Felix Avatar answered Sep 16 '22 11:09

Felix