// mathUtils.d.ts
export function add(a: number, b: number): number;
export const PI: number;
Topics
26
Classes: Access Modifiers, Abstract Classes & Implements
Conditional Types
Declaration Files
Decorators
Discriminated Unions & Exhaustiveness Checking
Enums
Function Types, Overloads & Optional/Default Parameters
Generics
Index Signatures & Record Types
Mapped Types
Migrating JavaScript to TypeScript
Modules
Namespaces & Declaration Merging
Never, Unknown & Void Types
Nullability: strictNullChecks, Optional Chaining & Nullish Coalescing
Primitive Types, Arrays & Tuples
Readonly, const Assertions & Immutability
Structural Typing & Duck Typing
Template Literal Types
tsconfig & Compiler Options
Type Assertions & Type Casting
Type Inference & Contextual Typing
Type Narrowing & Guards
Types & Interfaces
Union & Intersection Types
Utility Types
Declaration Files
10 questions found
A declaration file contains only type information — interfaces, type aliases, and function/variable signatures — with no runtime implementation code. It lets TypeScript type-check code that uses a JavaScript library, or lets consumers of your own package get type checking and autocomplete.
Real-world example
Providing type information for a plain JavaScript library so TypeScript users get autocomplete and type errors when using it.
Modules
How do you get type definitions for a popular JavaScript library that doesn't ship its own types?
BeginnerInstall the corresponding community-maintained package from DefinitelyTyped, prefixed with @types/ — TypeScript automatically discovers and uses these type packages from node_modules without any extra configuration.
npm install lodash
npm install --save-dev @types/lodash
Real-world example
Getting full type safety and autocomplete for a library like lodash or express that's written in plain JavaScript.
tsconfig & Compiler Options
declare tells TypeScript 'trust me, this exists at runtime somewhere else' — it describes a type shape without providing (or requiring) any implementation, and is erased entirely from compiled output. It's the core keyword used throughout .d.ts files and for describing global variables injected by other scripts.
declare const APP_VERSION: string; // exists globally at runtime, injected by a build tool
console.log(APP_VERSION); // type-checks fine, no import needed
Real-world example
Describing a global variable injected by a bundler's DefinePlugin, or a third-party script tag that attaches to 'window'.
Modules
How do you write a declaration file for a library that attaches itself to the global 'window' object?
IntermediateUse a 'declare global' block (inside a module file) or a plain ambient declaration (in a non-module .d.ts) to extend the global scope's type, describing the shape the library adds to window at runtime.
// jquery-global.d.ts
declare global {
interface Window {
$: (selector: string) => any;
}
}
export {}; // marks this file as a module
// usage.ts
window.$('#app'); // now type-checks
Real-world example
Adding types for a legacy jQuery or analytics script loaded via a <script> tag rather than an npm import.
Modules
'export =' in a .d.ts describes a module whose entire export is a single value (common in older CommonJS libraries), rather than a set of named exports — consumers then use 'import x = require("module")' syntax (or esModuleInterop-based default import) to bring it in correctly.
// legacy-lib.d.ts
declare function legacyLib(config: object): void;
export = legacyLib;
// usage.ts
import legacyLib = require('legacy-lib');
Real-world example
Typing an older CommonJS npm package whose module.exports is a single function rather than an object of named exports.
Modules
What is module augmentation and how do you use it to add a method to an existing library's types?
AdvancedModule augmentation lets you re-open and extend an already-declared module's types from a separate file, by writing `declare module 'existing-module' { ... }` and adding new members — commonly used to add custom properties that a plugin injects onto a library's base types.
// express-augment.d.ts
import 'express';
declare module 'express' {
interface Request {
userId?: string; // added by an auth middleware
}
}
// usage.ts
app.get('/', (req) => {
console.log(req.userId); // now recognized
});
Real-world example
Adding a custom 'userId' property that an authentication middleware attaches to Express's Request object.
Namespaces & Declaration Merging
How does TypeScript resolve which .d.ts file to use for a given package, and what does the 'types'/'typings' field in package.json control?
AdvancedTypeScript checks a package's package.json for a 'types' (or legacy 'typings') field pointing to its bundled declaration file; if absent, it falls back to looking for an @types/<package-name> package in node_modules, and finally to an implicit 'any' type if neither exists (unless noImplicitAny blocks that).
// package.json of a library
{
"name": "my-lib",
"main": "dist/index.js",
"types": "dist/index.d.ts"
}
Real-world example
Publishing your own npm package with bundled types so consumers get type checking without a separate @types install.
tsconfig & Compiler Options
How do you write a declaration file for a library with multiple overloaded call signatures, like jQuery's $()?
AdvancedList multiple function signatures back-to-back with the same name (no implementation) inside the declaration file — TypeScript treats them as overloads and picks the most specific matching signature based on the caller's argument types.
declare function $(selector: string): HTMLElement[];
declare function $(callback: () => void): void;
$('#app'); // resolves to the string overload
$(() => console.log('ready')); // resolves to the callback overload
Real-world example
Accurately describing a flexible, multi-shape JavaScript API in a hand-written declaration file for a legacy library.
Function Types
Overloads & Optional/Default Parameters
What is 'triple-slash directive' syntax and when is it still necessary in modern TypeScript?
AdvancedTriple-slash directives like `/// <reference types="node" />` at the top of a file are an older mechanism for explicitly pulling in ambient type declarations, mostly superseded by automatic node_modules/@types resolution — still occasionally needed in standalone .d.ts files or when writing global scripts outside a normal module graph.
/// <reference types="node" />
declare const process: NodeJS.Process; // relies on @types/node's ambient types
Real-world example
Explicitly including Node.js global types in a script-mode .d.ts file that isn't part of the normal module resolution graph.
tsconfig & Compiler Options
How do 'declaration' and 'declarationMap' compiler options in tsconfig.json affect a published npm package?
AdvancedSetting "declaration": true generates a corresponding .d.ts file for every compiled .ts file automatically, giving consumers of your published package full type information without hand-writing declarations. "declarationMap": true additionally generates source maps for those .d.ts files, letting editors 'Go to Definition' jump straight into your original TypeScript source instead of the generated declaration file.
// tsconfig.json
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "dist"
}
}
Real-world example
Publishing an npm library where consumers get full type support and can jump directly to your original source for definitions.
tsconfig & Compiler Options