A declaration file (.d.ts) describes the shape of JavaScript that lives in another file. It contains types and declared values only, so it is an ambient context: no function bodies (TS1183) or variable initializers (TS1039), and tsc emits nothing for it.
Where types for a package come from, in the order you reach for them:
- Bundled with the package. The
package.jsontypesfield (ortypings), or atypescondition insideexports. Authors generate them withdeclaration: true, plusemitDeclarationOnlyfor a JavaScript project. - DefinitelyTyped. Community-written
@types/foofor the npm packagefoo, installed as a dev dependency.tscfinds them on import even whentypesis limited. - Your own. Needed when neither exists. Without it,
strictcode importing the package fails with TS7016.
Writing one for an untyped library.
- Create a
.d.tsfile yourtsconfigincludes, with no top-levelimportorexport, so it stays a global script. - Start with the shorthand
declare module "name";, which makes every importany. Then replace it withdeclare module "name" { export function ... }for the parts you use. - Match the module's real shape:
export =for amodule.exports = fnpackage (see the interop question). - Keep it minimal and type only what you call; contribute it to DefinitelyTyped when it is stable.
Version note. TS 6.0 changed types to default to []: global-declaring @types packages such as @types/node are no longer included automatically, so add "types": ["node"].