Explain Codes LogoExplain Codes Logo

Overriding interface property type defined in Typescript d.ts file

javascript
type-aliases
interface-extension
type-safety
Nikita BarsukovbyNikita Barsukov·Sep 29, 2024
⚡TLDR

The type change within an interface can be achieved by exploiting TypeScript's interface merging. Declare in your code the same interface again and give a new definition to the type of your property. The compiler merges the declarations, which effectively overrides the original. Here's the example:

// Modifying interface from .d.ts - the fun begins here 😉 declare module './original-module' { interface MyInterface { property: number; // A wild number appears! It's super effective. } }

This process works if the new type is a subtype or compatible with the original one. Unrelated types are a no-go zone—it aims at refining types, not reckless swapping of them.

Strategies for Hacking Property Type Overrides

Omit – The Art of Property Exclusion

Excluding a property before reintroducing it with a new type can be achieved through TypeScript's Omit<T, K> utility:

interface OriginalInterface { propToOverride: string; otherProp: boolean; // Not me! I'm innocent! } type ModifiedInterface = Omit<OriginalInterface, 'propToOverride'> & { propToOverride: number; // Now, the magic happens. };

It's like performing property plastic surgery with precision.

Keep the Family Tree Alive - Interface Extension

For a painstakingly detailed property modification, extend an interface and give the property a makeover:

interface OriginalInterface { propToOverride: string; } interface ExtendedInterface extends OriginalInterface { propToOverride: number; }

Remember, using Object as a type is like handcuffing ourselves in a sprint race. Instead, use any, which is more flexible.

Compatibility – When Everything You Do Matters

While overriding types like a restyling guru, ensure every change you make is a compatible one to keep everything running smoothly.

interface OriginalInterface { propName: string; newPropName?: number; // New kid on the block! 🕺 }

Merge Type Pattern – The Property Type Overriding Masterstroke

Forge a new Merge type combining Omit and Pick:

type Merge<Original, Overrides> = Omit<Original, keyof Overrides> & Overrides;

It opens a new window of opportunities, painting a vivid property override landscape.

How Interface Emerged the Victor over Type Aliases

Interfaces have something that type aliases don't – the capability to merge numerous declarations:

interface BaseInterface { originalProp: string; } interface BaseInterface { originalProp: number; // "I'm the king of the world!" (Titanic, 1997) }

Advancing through the Property Type Overrides Maze

The Modify Pattern: The Property Override Champion

type Modify<T, R> = Omit<T, keyof R> & R;

It's like putting property override on steroids. Become an interface modification wizard.

Entering the Nested Property Override Labyrinth

For deep-nested structures, use a recursive pattern like ModifyDeep:

type ModifyDeep<T, R> = { [P in keyof T]: P extends keyof R ? ModifyDeep<T[P], R[P]> : T[P]; // Sorry, I'm busy. Come back later. };

This recursive approach will help to crack the hardest code without a sweat.

When is it a Good Time to Put Type Overrides to Sleep

In critical type safety situations, avoid overriding types:

interface SafeOriginalInterface { originalProp: string | number; // I can handle both. additionalProp?: number; // Optional, yet powerful. }