How to make TypeScript not emit `/// <reference path="…" />` directives for ambient declaration files?

420 Views Asked by At

Background

I'm writing a package using Lit. To prevent accidental interpolation of nonsense values in templates, I have created src/lit.d.ts based on this answer:

declare module "lit" {
  import { html as htmlFromLit } from "lit/index";

  export * from "lit/index";

  export const html: (strings: TemplateStringsArray, ...values: Array<string | number /* etc */>) => ReturnType<typeof htmlFromLit>;
}

This way, I can write my code as usual and still get more type safety than Lit itself provides:

import { html } from "lit"; // ← standard, idiomatic import

export const h = html`<p>${null}</p>`;
//                         ~~~~ Argument of type 'null' is not assignable to parameter of type 'string | number'.

Problem

Consumers of my package get this compilation error:

node_modules/my-package/dist/index.d.ts:1:22 - error TS6053: File '/…/consuming-project/node_modules/my-package/src/lit.d.ts' not found.

1 /// <reference path="../src/lit.d.ts" />
                       ~~~~~~~~~~~~~~~

Content of /…/consuming-project/node_modules/my-package/dist/index.d.ts:

/// <reference path="../src/lit.d.ts" />
export declare const h: import("lit-html").TemplateResult<1>;

My observations/notes:

  • lit.d.ts is indeed not among the emitted files in dist/, but even if it were, the reference would not point to it, because the src directory isn't included in the published npm package.

  • There are no reference directives in the source code of my package; TypeScript injects them whenever it compiles a module that imports "lit".

  • Even if I could make TypeScript include lit.d.ts among the emitted files, I don't think I want to, because its purpose is only to aid the development of my-package.

  • If I manually remove the triple-slash directives in the emitted files before running npm pack, the consuming project compiles just fine.

  • The problem is still present in TypeScript 4.9.5 and 5.0.4.

How can I make TypeScript not emit these directives, or otherwise solve this problem?

Project details (for reference)

File tree

.
├── package.json
├── package-lock.json
├── src
│   ├── index.ts
│   └── lit.d.ts
└── tsconfig.json

package.json

{
  "name": "my-package",
  "version": "0.0.0",
  "scripts": {
    "build": "rimraf dist && tsc -p ."
  },
  "files": [ "dist/**/*" ],
  "type": "module",
  "main": "dist/index.js",
  "devDependencies": {
    "rimraf": "^3.0.2",
    "typescript": "^4.7.4"
  },
  "dependencies": {
    "lit": "^2.4.1"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "module": "es2015",
    "moduleResolution": "node",
    "outDir": "dist",
    "strict": true,
    "target": "es2019",
  },
  "include": [
    "src/**/*.ts",
  ],
}
0

There are 0 best solutions below