Dev.to · 3 min read

TypeScript 7.1 can check an import attribute and still miss a missing file

TypeScript 7.1 can check an import attribute and still miss a missing file

My TypeScript 7.1 Beta example passed the compiler. The imported file did not exist. Running the emitted JavaScript failed with ERR_MODULE_NOT_FOUND. That result is a useful way to understand the beta's new ambient module declarations: they describe how an import should be typed. They do not prove that its target exists. 💡 Results from my small compiler check using TypeScript 7.1.0-beta. The runtime failure deliberately uses a nonexistent file. The new declaration follows the attribute TypeScript's October 20 announcement adds import attributes to ambient module declarations. That lets a project describe a module selected by an attribute, instead of repeating declarations for every file extension. These declarations are supplied by the project; the beta does not add them to its built-in libraries. [1] Here is the complete declaration I used in assets.d.ts: declare module "*" with { type: "text" } { const content: string; export default content; } And the import in good.ts: import note from "./missing.txt" with { type: "text" }; const upper: string = note.toUpperCase(); console.log(upper); The compiler accepts the import and treats note as a string. The deliberate filename is a clue to the next boundary. 🔍 Reproduce the compiler result In an empty project with Node and npm available, install the exact beta I checked: npm install --save-dev typescript@7.1.0-beta npx tsc --ignoreConfig --module esnext --target es2022 --strict --noEmit assets.d.ts good.ts I checked these cases with the same compiler options: Import form Compiler result with { type: "text" } Passed Attribute omitted Failed with { type: "bytes" } Failed The declaration only supplies the text case. It gives the compiler no matching declaration for the other imports in this fixture. ✅ That makes the attribute useful at the development boundary: a project can require the import form its tooling expects, and code gets the corresponding type. Now cross the runtime boundary I emitted the accepted case with: npx tsc --ignoreConfig --module esnext --target es2022 --strict --outDir dist assets.d.ts good.ts With {"type":"module"} in dist/package.json, node dist/good.js failed because missing.txt was absent. The runtime check used Node 22.22.1. It does not demonstrate a working text-import implementation. The compiler did exactly what the declaration asked: it gave the matching import a type. It did not find or create the file. Microsoft's announcement explicitly documents that ambient matches do not validate file lookups. [1] ⚠️ An ambient declaration is easy to mistake for a loader configuration. It supplies neither the asset nor the runtime behavior. Keep the build or runtime check that proves your real asset-loading route works. Where I would use this In a project whose bundler or runtime already supports attribute-based loading, I would describe that established behavior with a narrowly chosen declaration. Then I would run a small real import through the build as well as through the type checker. For this fixture, the useful result is the boundary itself: the matching attribute gets checked, while file availability remains another tool's job. 🧪 References Microsoft: Announcing TypeScript 7.1 Beta, October 20, 2026. Asset credit: original diagram generated from the saved compiler outcomes. No speed benchmark or production compatibility claim. AI disclosure AI was used to draft the article.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Programming & Dev News