According to the TypeScript handbook, when we utilize the extends
keyword on an interface
, it allows us to essentially duplicate members from other named types while also adding any new members as desired. This feature is beneficial for reducing the amount of type declaration repetition and indicating that multiple declarations of the same property might be interconnected.
This implies that any type derived by extending another type must always be assignable to the original extended type. In simpler terms, the extended type is considered a subtype or a more specific type.
In a specific example mentioned, the HttpUpdate
type does not qualify as a subtype of Update
due to its type
property being a string union, which cannot be assigned to the single string literal in the Update
type. This discrepancy becomes evident when attempting to create the type with literal values.
If you encounter a scenario where extension of an interface doesn't serve practical purpose because of certain constraints, like having only one property, one workaround would be to introduce an additional property such as a message
property with a value of type string
.
Another method to achieve the desired type is by creating a new type that replicates all properties except the type
property using the utility function Omit<Type, Keys>
, and then setting the type
property accordingly with a string union.
To simplify this process, using type aliases can also yield the desired outcome, keeping the structure concise and understandable.
To streamline this pattern, a custom type utility can be constructed to merge attributes from two distinct types selectively, resulting in a unified type that encompasses common properties while maintaining their individual data types.