{"record":{"id":"80cd0fe7e2efee0e","repo":"microsoft/typescript-go","slug":"found-external-imports-in-d-ts-files-n-importer","errorCode":null,"errorMessage":"Found external imports in .d.ts files:\\n${importErrors.map(e => \"  \" + e).join(\"\\n\")}","messagePattern":"Found external imports in \\.d\\.ts files:\\\\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"Herebyfile.mjs","lineNumber":1948,"sourceCode":"    for (const dtsFile of dtsFiles) {\r\n        const content = await fs.promises.readFile(dtsFile, \"utf-8\");\r\n        const relPath = path.relative(mainPackageDir, dtsFile);\r\n        for (const [i, line] of content.split(\"\\n\").entries()) {\r\n            // Match: import ... from \"specifier\" / export ... from \"specifier\"\r\n            const fromMatch = line.match(/(?:import|export)\\s.*?\\sfrom\\s+[\"']([^\"']+)[\"']/);\r\n            if (fromMatch && !fromMatch[1].startsWith(\".\") && !fromMatch[1].startsWith(\"#\")) {\r\n                importErrors.push(`${relPath}:${i + 1}: external import declaration \"${fromMatch[1]}\"`);\r\n            }\r\n            // Match: import(\"specifier\")\r\n            for (const m of line.matchAll(/import\\([\"']([^\"']+)[\"']\\)/g)) {\r\n                if (!m[1].startsWith(\".\") && !m[1].startsWith(\"#\")) {\r\n                    importErrors.push(`${relPath}:${i + 1}: external dynamic import \"${m[1]}\"`);\r\n                }\r\n            }\r\n        }\r\n    }\r\n    if (importErrors.length) {\r\n        throw new Error(`Found external imports in .d.ts files:\\n${importErrors.map(e => \"  \" + e).join(\"\\n\")}`);\r\n    }\r\n\r\n    const extraFlags = getReleaseBuildFlags(options.setPrerelease || nativePreviewReleaseVersion ? getVersion() : undefined);\r\n\r\n    const platformBuilders = platforms.map(({ npmDir, npmPackageName, nodeOs, nodeArch, goos, goarch }) => async () => {\r\n        const packageJson = {\r\n            ...inputPackageJson,\r\n            bin: undefined,\r\n            files: [\"lib\", \"NOTICE.txt\"],\r\n            imports: undefined,\r\n            dependencies: undefined,\r\n            name: npmPackageName,\r\n            os: [nodeOs],\r\n            cpu: [nodeArch],\r\n            exports: {\r\n                \"./package.json\": \"./package.json\",\r\n            },\r\n        };\r","sourceCodeStart":1930,"sourceCodeEnd":1966,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/Herebyfile.mjs#L1930-L1966","documentation":"Thrown by the native-preview npm packaging task in Herebyfile.mjs after the JS API build (`npm run -w @typescript/native-preview build`) is copied into the package. It scans every dist/**/*.d.ts line-by-line for `import`/`export ... from` declarations and dynamic `import()` specifiers that are neither relative (\".\") nor subpath imports (\"#\"), and fails the build if any are found. The guard exists because the shipped platform packages set `dependencies: undefined` (Herebyfile.mjs:1958), so an external type import would be unresolvable for consumers.","triggerScenarios":"Running the native-preview package build or `native-preview:release` when a generated .d.ts under the package's dist/ contains something like `import type { X } from \"vscode-jsonrpc\";` or `import(\"some-package\")` — i.e. the dts-bundling step did not inline a dependency's types into the shipped declarations.","commonSituations":"A source file in _packages imports types from an npm dependency (e.g. vscode-jsonrpc) without the bundler inlining it; a change to the JS API build/bundler config that stops inlining external types; adding a package.json dependency that is used in public API types but not wired into the dts-bundle step.","solutions":["Read the file:line entries listed in the error message, open the offending dist .d.ts, and trace the specifier back to the source file whose types leaked the external import","Make the shipped declaration self-contained: declare the needed shape locally in source, or import it via a relative path / \"#subpath\" import so the emitted .d.ts only references \".\"/\"#\" specifiers","If the type should be bundled, fix the dts-bundling JS API build (`npm run -w @typescript/native-preview build`) so it inlines the dependency's types, then rebuild","Re-run the hereby packaging task and confirm the scan passes"],"exampleFix":"// before (source whose types ship in dist)\nimport type { CancellationToken } from \"vscode-jsonrpc\";\nexport function doWork(token: CancellationToken): void;\n\n// after — declare the used shape locally so the .d.ts stays self-contained\ninterface CancellationToken { isCancellationRequested(): boolean; }\nexport function doWork(token: CancellationToken): void;","handlingStrategy":"validation","validationCode":"// Run the same scan the build uses, before invoking the packaging task\nimport glob from \"glob\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nfunction findExternalDtsImports(pkgDir) {\n  const errors = [];\n  for (const f of glob.sync(`${pkgDir}/dist/**/*.d.ts`)) {\n    const rel = path.relative(pkgDir, f);\n    const lines = fs.readFileSync(f, \"utf8\").split(\"\\n\");\n    lines.forEach((line, i) => {\n      const m = line.match(/(?:import|export)\\s.*?\\sfrom\\s+[\"']([^\"']+)[\"']/);\n      if (m && !m[1].startsWith(\".\") && !m[1].startsWith(\"#\")) errors.push(`${rel}:${i + 1}: ${m[1]}`);\n      for (const d of line.matchAll(/import\\([\"']([^\"']+)[\"']\\)/g)) {\n        if (!d[1].startsWith(\".\") && !d[1].startsWith(\"#\")) errors.push(`${rel}:${i + 1}: dynamic ${d[1]}`);\n      }\n    });\n  }\n  return errors;\n}\n// if (findExternalDtsImports(\"built/package\").length) fail fast with details","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never let public API types import from external packages — declare needed shapes locally or via relative/#subpath imports","Add a CI step that scans dist/**/*.d.ts for non-relative specifiers before the packaging task","After adding a dependency, rebuild the JS API and grep the emitted .d.ts for external specifiers"],"tags":["build","typescript","dts","packaging","npm"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}