Quick Overview
A `.d.ts` file describes types with no implementation, which is how JavaScript packages get typed without being rewritten. `@types/*` packages are exactly that, published separately from the library.
Many third-party npm packages are written in raw JavaScript without TypeScript source code. Declaration Files (.d.ts) provide type annotations for JavaScript code without altering the underlying JavaScript execution.
.d.ts File?A .d.ts file contains ONLY type declarations (no executable code). The TypeScript compiler uses it to provide autocompletion and type checking for untyped JavaScript libraries.
declare module)If an npm package lacks types, you can declare ambient module shapes in a local types.d.ts file:
// types/legacy-lib.d.ts
declare module "legacy-chart-library" {
export function renderChart(elementId: string, data: number[]): void;
export const version: string;
}
Now you can import and use the untyped library safely in your project:
import { renderChart } from "legacy-chart-library";
renderChart("my-canvas", [10, 20, 30]); // Fully typed!
Augment ambient global objects (like adding custom properties to window or Express Request):
declare global {
interface Window {
analyticsToken: string;
}
}
// Now valid throughout your project!
window.analyticsToken = "token_123";
declare statements. Including executable JavaScript code throws compile errors!Use DefinitelyTyped (npm i -D @types/node) for open-source library types. Next, let's explore the satisfies operator!
TypeScript erases entirely at build time, so a `string` annotation produces no runtime check whatsoever. A value arriving from an API is whatever the server actually sent, regardless of what the annotation claims.
`let x = "GET"` infers `string` because the binding can change; `const x = "GET"` infers the literal `"GET"`. That widening rule is why object properties need `as const` to stay narrow.
`string[]` is any number of strings; `[string, number]` is exactly two, in that order. `readonly` removes the mutating methods at compile time, so `push` becomes a type error rather than a runtime surprise.