Background:
TypeScript is designed to add static typing to existing JavaScript applications. The question arises — how to type an import when we are connecting a third-party or our own module written in pure JavaScript, where there are no types? In this case, TypeScript uses so-called declaration files (.d.ts), or it may infer types automatically (sometimes incorrectly).
Problem:
If TypeScript cannot find an appropriate type description during import, the variable receives the type any, which means a complete loss of type safety. This can lead to errors that the compiler does not catch and bugs at runtime. Developers often forget to explicitly declare types for imported functions/objects.
Solution:
Code example:
// 1. Explicit typing for JS module import import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Import from a JS module for which a file myLib.d.ts was created with export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. Importing a module without typing and explicitly describing the type import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;
Key features:
Can TypeScript automatically infer types for an imported JS module without declarations?
No, if the file is written in JavaScript, without type declarations TypeScript has to assume any and loses type information, except for trivial cases (export const x = 1;).
Is it possible to "extend" imported types if new fields appear in the JS module?
Only if you update the declaration file (.d.ts). If types are fixed in .d.ts, TypeScript will use them as "truth," and any new fields will remain untyped or lead to an error.
Is it safe to import a third-party JS module into a TypeScript project if there are no @types/ and declarations for it?
No, this greatly reduces safety — all work with the import becomes untyped (any), and the compiler will not give errors even if the module is unavailable or the API has changed. Working with such modules is acceptable only as a temporary solution, with explicit typing or code isolation.
A developer imports a third-party JS library without declarations, confidently using the API, receiving type any. After updating the library, the method signatures change, but no errors occur, only bugs at runtime.
Pros:
Cons:
A declaration file .d.ts is created or an @types/ package is added, and the API description strictly matches the original JS module. All imported methods are typed, the IDE provides autocomplete suggestions, and any mismatches show a compilation error.
Pros:
Cons: