I wanted to extend the Window type in TypeScript and read the new property in my React app. TypeScript kept saying it wasn't defined, even though I had declared it in global.d.ts.
Because of the @typescript-eslint/consistent-type-definitions rule, I was using a type alias:
type Window = {
dataLayer: Record<string, unknown>;
};A type alias doesn't support augmentation. It only works when you declare every property in one place, so a second declaration with the same name is an error, not a merge. An interface does support augmentation, which is what extending the Window interface needs:
interface Window {
dataLayer: Record<string, unknown>;
}One thing to watch: if global.d.ts has a top-level import or export, TypeScript treats it as a module and the interface no longer touches the global scope. Wrap the block in declare global in that case.
In general, I prefer type for app code since it avoids hidden extensions. But if you're extending the Window object or any other built-in or third-party type, interface is the way to go.
For the full rules, see declaration merging on the TypeScript website.
Occasional notes on software, tools, and things I learn. No spam.
Unsubscribe anytime.