How I fixed some trouble importing types in .d.ts files
By Flavio Copes
Augment Astro's global App namespace from env.d.ts while importing TypeScript types with import type and declare global.
I had some trouble making something work in my Astro site.
I used Astro locals and I had to type a variable I shared using locals.
So I went and added that to the src/env.d.ts, as the docs say.
But my types weren’t picked up.
My code looked like this:
/// <reference types="astro/client" />
import { sometype } from 'somelib'
declare namespace App {
interface Locals {
somevariable: sometype
}
}
That first line came from Astro 4’s default env.d.ts. Astro 5 and later don’t create env.d.ts for you anymore: the same types come from the generated .astro/types.d.ts, which the tsconfig.json you extend already includes. If you add an env.d.ts yourself today, you can leave the reference line out. The rest of the problem is the same.
Imports are allowed in .d.ts files. The important detail is that a top-level import turns the declaration file into a module. A namespace written at the top level is then no longer a global augmentation.
Keep the type import and wrap the namespace in declare global:
/// <reference types="astro/client" />
import type { SomeType } from 'somelib'
declare global {
namespace App {
interface Locals {
somevariable: SomeType
}
}
}
export {}
import type is erased from the emitted JavaScript, while declare global makes the intent explicit.
An inline import type also works when you prefer to keep the file as a global script:
declare namespace App {
interface Locals {
somevariable: import('somelib').SomeType
}
}Want me to talk about your product? You can sponsor this site.
Related posts about typescript: