allowJs
Allows .js files into the program so TypeScript can compile and import them.
"allowJs": boolean // default: false- Added in TypeScript 1.8
Parameters
| Parameter | Type | Description |
|---|---|---|
$allowJsoptional | boolean= false | Allow JavaScript files to be part of the program and to be imported from TypeScript files. |
Return value
booleanA program that includes .js and .jsx files, letting them be imported from TypeScript and emitted to outDir.
Errors
Nothing on its own. Without allowJs, importing a .js file from TypeScript is error TS2307 (Cannot find module) unless a matching .d.ts exists.
Changelog
- PHP 2.3checkJs added, so JavaScript files admitted by allowJs can also be type-checked rather than only inferred.
By default a TypeScript program contains only .ts and .d.ts files; a .js file matched by include is ignored, and importing one is TS2307. allowJs admits .js and .jsx to the program, so they can be imported, inferred from, and emitted to outDir like any other input.
The first step of a migration
This is what makes incremental adoption possible. Point include at your whole source tree, turn on allowJs, and the build keeps working with zero renames. From there you convert files one at a time: a renamed .ts file can still import its untouched .js neighbours, and those neighbours still contribute inferred types — badly, but not as any everywhere. Turn on checkJs next when you want errors reported in the JavaScript too.
What trips people up
allowJs means tsc now emits your JavaScript. If outDir is unset or equals the source directory, the compiler will overwrite your source files in place — set a distinct outDir, or noEmit, before enabling it. It also pulls anything include matches into the program, so an unexcluded node_modules, dist or minified vendor bundle can suddenly add tens of thousands of files and stall the build.
Example
// legacy/rates.js — plain JavaScript, unchanged, admitted by allowJs:
// export const rates = { EUR: 1, USD: 1.08 };
// export function convert(amount, to) { return amount * rates[to]; }
import { convert } from "./legacy/rates.js";
// With allowJs but not checkJs, convert is inferred as
// (amount: any, to: any) => any, so this compiles with no complaint.
const total: number = convert(100, "USD");
console.log(total.toFixed(2)); // "108.00"
// Turning on checkJs would flag rates[to] inside the .js file itself,
// because `to` is an implicit any used as an index.
console.log(typeof convert);When to use it
- Starting a JavaScript-to-TypeScript migration without renaming anything on day one.
- Importing a local untyped helper module from .ts without writing a .d.ts shim for it.
- Keeping a build green while converting one file per pull request.
- Generating .d.ts files for a JavaScript-only package using emitDeclarationOnly.
Frequently asked questions
How do I import a .js file from TypeScript?
Set "allowJs": true in compilerOptions. Without it the .js file is not part of the program at all and the import fails with TS2307, Cannot find module. With it on, the file is included, its exports are inferred, and you can import it from .ts normally. Add checkJs if you also want type errors reported inside the JavaScript.
Does allowJs slow down my build?
It can, sharply, because every .js file matched by include now joins the program. Excluding node_modules, dist, build output and minified vendor bundles is usually what fixes a build that got slow right after enabling it. checkJs adds further cost, since those files are then fully type-checked rather than only inferred.
Will allowJs overwrite my JavaScript source files?
Yes, if outDir is unset or resolves to the same directory as the input. The compiler treats .js files as inputs that need emitting, so it writes them back to the computed output path. Always set a distinct outDir, or use noEmit or emitDeclarationOnly, before turning allowJs on.
More examples
Safe migration config
outDir is distinct from rootDir, so emitted JavaScript never lands on top of the source. The exclude list matters more than usual: without it, allowJs pulls every matched .js — including vendored bundles — into the program, and compile times climb sharply. checkJs stays off until the team is ready for errors in the untouched files.
{
"compilerOptions": {
"allowJs": true,
"checkJs": false,
"outDir": "dist",
"rootDir": "src",
"target": "es2022",
"module": "nodenext"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.min.js"]
}Producing types for a JavaScript package
tsc reads JSDoc in the .js sources and writes .d.ts files into types/ without touching the JavaScript. emitDeclarationOnly is essential here — with plain declaration the compiler would also emit .js, and pointing outDir back at the source tree would overwrite the originals.
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "types",
"rootDir": "src"
},
"include": ["src/**/*.js"]
}
Discussion