How do you write a minimal dom-utils.d.ts for a JS function?
Tests bridging untyped JavaScript into TypeScript via ambient module declarations. A strong answer declares a module matching the file path and exports the function with a typed signature. Red flag: suggesting rename to .ts or using any.
WHAT THIS TESTS: This question tests whether you can bridge untyped JavaScript into TypeScript using ambient module declarations. The interviewer wants to see if you understand that TypeScript can consume plain JS files without rewriting them, and whether you know the minimal syntax to make the compiler aware of a function signature. It also checks if you recognize the relationship between the import path and the module declaration string.
A GOOD ANSWER COVERS: A good answer hits four things in order. First, mention that you create a file named dom-utils.d.ts in the same directory as dom-utils.js. Second, declare a module block whose string literal matches exactly how the consumer imports it, such as declare module "dom-utils" if imported by name, or declare module "./dom-utils" if imported by relative path. Third, inside the module block, export the function with an explicit signature, for example export function focusFirstInput(): void. Fourth, note that the .d.ts file must be included in the TypeScript project, either by being picked up via include in tsconfig.json or by being referenced, so the compiler actually sees the declarations.
COMMON WRONG ANSWERS: Common wrong answers include suggesting you rename dom-utils.js to .ts, which misses the point of the exercise. Another red flag is using declare global and attaching focusFirstInput to the global scope, which is unnecessary and pollutes the global namespace. Some candidates write the function body inside the .d.ts file, forgetting that declaration files contain only type information and no runtime code. A frequent mistake is omitting the export keyword inside the module declaration, which makes the function unreachable from an import statement. Finally, typing the function as any or using a blanket declare module "*" shows a lack of precision and defeats the purpose of TypeScript.
LIKELY FOLLOW-UPS: The interviewer might ask how to handle default exports versus named exports in a .d.ts file. They could ask what happens if the JS file uses CommonJS module.exports instead of ES modules, which would require an export = syntax. Another follow-up is how to auto-generate declaration files from JavaScript using allowJs and declaration emit. They might also ask how to type a function that accepts an optional callback or complex DOM types like HTMLElement.
ONE CONCRETE EXAMPLE: If dom-utils.js lives in src/utils and is imported as import { focusFirstInput } from "./utils/dom-utils", then the minimal src/utils/dom-utils.d.ts should read: declare module "./utils/dom-utils" { export function focusFirstInput(): void; }. If the project uses path mapping or a bare specifier, the module string must match the import string exactly. For a function that actually takes an optional root element, the signature could be export function focusFirstInput(root?: HTMLElement | null): void.
Read the original → typescriptlang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.