简体   繁体   中英

How can I extend an interface and override a property's type?

I have a pretty complicated object with multiple properties that I'd like to extend and override a specific property.

interface ComplicatedObject {
  propertyOne: string,
  propertyTwo: null
}

interface MoreComplicatedObject extends ComplicatedObject {
  propertyTwo: string
}

Essentially, objects with the type ComplicatedObject are converted to the MoreComplicatedType by assigning a string value to propertyTwo . I'd like to avoid using a union type on propertyTwo because all calls using propertyTwo assume that it's a string, not a null value, so I'd rather not have to include type checks in every instance where I access propertyTwo .

How can I extend an interface and override the type of an existing property?

You can override property type when extending an interface only if the type in the extending interface is compatible with original type of the property. Usual case is when you are overriding it with more restrictive type.

It means that you have to have foresight and declare original property with a type that will be compatible with all possible extensions. In your case, you can use union type in ComplicatedObject :

interface ComplicatedObject {
  propertyOne: string,
  propertyTwo: null | string
}

interface MoreComplicatedObject extends ComplicatedObject {
  propertyTwo: string
}

Or you can make CompicatedObject generic as described in this answer .

You can make use of Omit<T, K> , which allows you to omit certain keys of a type. You can then use & to append the keys you want.

type A = {a: string, b: string}
type B = Omit<A, 'b'> & {b: number}

Note that you can declare A as an interface, Omit<T,K> similarly works.

Playground Link

Using the type-fest npm package, you can use the Merge helper to overwrite/override any property on the original, however you like:

import {Merge} from 'type-fest'

type ComplicatedObject = {
  propertyOne: string,
  propertyTwo: null
}

type MoreComplicatedObject = Merge<ComplicatedObject, {
  propertyTwo: string
}>

This may work with interfaces too, but I've only used it with object types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM