### ๐ Search Terms declaration emit inline type import resolution ### ๐ Version & Regression Information - This changed between versions 5.3.3 and 5.4.0-beta - This changed in PR #56857 ### โฏ Playground Link https://www.typescriptlang.org/dev/bug-workbench/?emitDeclarationOnly=true&baseUrl=true&ts=5.4.0-beta#code/PTAEAEBMFMGMBsCGAnRAXAlgewHYCgQIBnACywHcBRAWwzQLHFIprrWkgDEN5oAuUIgAOQ4DkQA3DAHN0WZMHIZI06GgC0AM0Sw08gJ4A6SIbRE8DCJp7Rx1fqHgYARsAw4YAD2OnzGakLyaKAAVIJEoAAi0NoArvBolJ6ByMGayFjUoABEhm447Mji8MAwcQkA+tDJQUTZANx41SnBAN5RMYjxiTWp4aBlXQmgAL6NzUGh-QBCiETQAOrukBSg6Zk5ee6FxYrLFETAznPQSh4UPmYNFoTg1rx2Dk6u29BFiCWD3VW9ZpfmEz67S+wzmoFm8yW53IozWGSyuT20MOx3mZxW5GuljuNkeAme+R2HyRGJRJ3RFxMZjwr2Q2lg0HBJyhGNArRGTV+oFp9MZEMW+3IAGFcEQ0MhYrp5GyOTAEChGbBRcF+SyKAJVYKRTgxRKpchxlyQSrmYLGjdGPdbIh7PiXOpYph4IdSArIOo0PohNBDkoVGp1EqcNZpP8aQFJp7vaAAKoASThG1yeUMeQJy2q10BwR5OkZS39aE4Oj0yH0bLwoCr3J1aEQBQwcmQAAohAqCmryAJ44ZNdCAJQCCRYZSNDnYq14wQiMSSGRNvaFrQlgy+cMtNkF1RFldlkaJhGp4BH54Op0ukhuj1en2L7eB3AhrFypDIRXKmti+uYJsCLdqYt9X0ABtABydwvwbJtQIAXXNQgAFZDAAZgECoKiIfQChINQMFgH4WgqZ4KgARl7U1oWMTpuksJCABYBH8Fpm2TY80xcQk3l2Y0CNqbJ+3IyFBU5DdjVAAB5ZwACs4DQQx0mgaAAC9oGbVpK2rCC6yg0s8BGftzSYyMbymMF0Mw7DcPw7MiJcUiD02FN2JeDxM0aIA ### ๐ป Code ```ts repro // @declaration // @showEmit // @showEmittedFile: app/navigator/widget-factory.d.ts // @filename: lib/index.d.ts import * as DefaultExport from "./internal/default_exports"; export { DefaultExport as default }; export * as BaseWindow from "./internal/windows/basewindow.d.ts"; // @filename: lib/internal/default_exports.d.ts export { default as BaseWindow } from "./windows/basewindow"; // @filename: lib/internal/windows/basewindow.d.ts interface BaseWindow {} export interface BaseWindowConstructor {} declare const BaseWindow: BaseWindowConstructor; export default BaseWindow; // @filename: lib-utils/shared-types/widget-config.d.ts import type UI from "../../lib/index"; export interface WidgetFactory { instantiator(parentWindow: UI.BaseWindow): void; } // @filename: app/navigator/widget-factory.ts import {WidgetFactory} from "../../lib-utils/shared-types/widget-config"; declare const instantiator: WidgetFactory['instantiator']; // 5.3: __synthetic_export_lib_1.BaseWindow.default // 5.4: import("../../lib/internal/default_exports").BaseWindow export default Object.freeze({ instantiator }); // Our tools inject this before we pass the file to TS. import type * as __synthetic_export_lib_1 from "../../lib/index"; ``` ### ๐ Actual behavior ```typescript // app/navigator/widget-factory.d.ts declare const _default: Readonly<{ instantiator: (parentWindow: import("../../lib/internal/default_exports").BaseWindow) => void; }>; export default _default; import type * as __synthetic_export_lib_1 from "../../lib/index"; ``` ### ๐ Expected behavior ```typescript // app/navigator/widget-factory.d.ts declare const _default: Readonly<{ instantiator: (parentWindow: __synthetic_export_lib_1.BaseWindow.default) => void; }>; export default _default; import type * as __synthetic_export_lib_1 from "../../lib/index"; ``` ### Additional information about the issue More background in previous conversation around this: #38111 and this public blog post: https://www.bloomberg.com/company/stories/10-insights-adopting-typescript-at-scale/ The JavaScript runtime we are using TypeScript on is not based on npm style packages (no `node_modules` resolution or `package.json` manifest). For the `.d.ts` that we publish to be able to work consistently across different versions it's important that the inter-package import paths only resolve to the 'public' files and not internal implementation `.d.ts` files. To encourage TypeScript to pick these safer paths when emitting `.d.ts` we add unused imports to the bottom of each file before passing them to the TS compiler. In general this is still working in 5.4.0-beta, however during our testing at least 8 packages's `.d.ts` emit regressed with the beta. The playground above re-creates one of these.