Declaration merging has been around for a while now in TypeScript. In a nutshell it lets you merge definitions of types. There's plenty of examples in the documentation, so let's just start off with something simple.
enum HardDriveType {
ssd,
sata
}
enum ProcessorType {
i3,
i5,
i7,
i9
}
interface Computer {
processor: ProcessorType;
}
interface Computer {
hardDriveType: HardDriveType;
}
// interface has been merged
const myPC: Computer = {
hardDriveType: HardDriveType.ssd,
processor: ProcessorType.i9
};
// interface is merged so type checking fails since the processor property is missing
const myBadPC: Computer = {
hardDriveType: HardDriveType.ssd,
};
You can play around with the example in the TypeScript Playground.
So two interfaces called Computer
are declared and all the properties of those interfaces are merged together into one declaration for the Computer
interface. This is a simple example to show how it works, but in a real world app, you wouldn't be declaring the interface in two pieces in a file. Let's go with something more realistic.
You are using a third-party library or it's something in your project that needs to live on the window
. The window
has it's own type, the Window interface. This type has all the properties you'd expect to find on MDN about window
.
Let's use our a fictitious 3rd party library called awesomeThing
. It gets loaded onto the window
object so we need to enhance the Window
interface.
export interface AwesomeThing {
doIt: () => void;
}
declare global {
interface Window {
awesomeThing: AwesomeThing
}
}
// The window interface has been merged with our interface to add awesomeThing.
window.awesomeThing.doIt();
// Errors because it's not on the `Window` interface.
window.thingThatIsNotOnWindow.doIt();
You can play around with the example in the TypeScript Playground.
If you'd like to see some real world examples in open source, look no further than a recent PR of mine that got merged to the Refined GitHub browser extension repository. I was really happy getting this PR in because it's an extension I use everyday.
Specifically, check out globals.d.ts in the project.
That's pretty much all there is to it. To summarize, declaration merging is a great way to enhance existing types.
Photo by Mike Enerio on Unsplash