Skip to content

Instantly share code, notes, and snippets.

@cspotcode
Created January 19, 2022 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cspotcode/06489615623b9d0573db20a521371f6d to your computer and use it in GitHub Desktop.
Save cspotcode/06489615623b9d0573db20a521371f6d to your computer and use it in GitHub Desktop.

Understanding the flavors of .d.ts

We think of .d.ts as having two styles: the ambient declare module style (Ambient) and the named "DT" style. (Named)

declare module "some string" { tells the compiler that, from then forward, if it ever sees any import of "some string" then it need look no further. It will not attempt to find anything on the filesystem, it will not scan through directories, none of that at all. On the other hand, if you put export const foo... at the beginning of a .d.ts, then the .d.ts itself is essentially pretending to be a .js file (Named) and imports will pass through typescript's resolver, doing all sorts of path mapping and filesystem traversal to find the .d.ts file.

The .d.ts's filename only matters in the latter case, where the declaration is pretending to by a .js file. (Named) In the former case, (Ambient) where the .d.ts exists to declare global types or declare module, the .d.ts's filename does not matter. All that matters is that the compiler has somehow been triggered to look at the file, either via tsconfig includes, tsconfig typeRoots / types, or /// <reference

There's also a quirk: if the .d.ts is acting like a module (has top-level export) (Named) then any declare module within it must be module augmentations, not module declarations. In other words, you can augment modules that the compiler already knows about, but cannot declare new ones.

--traceResolutions helps understand how typescript is doing the aforementioned filesystem traversal to locate a module. However, if the compiler already knows about the module specifier via declare module "some string" then I don't think it will use the resolver at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment