dts-buddy

repository·main·Indexed 43 days ago

https://github.com/sveltejs/dts-buddy

A tool for creating bundled .d.ts files using declare module syntax, specifically optimized for packages with subpath exports. It generates single-file type bundles that support autocompletion and 'go to definition' via .d.ts.map files, while correctly resolving tsconfig paths and tree-shaking public types. Version 0.8.3 provides both a CLI and a createBundle JavaScript API for programmatic control.

Tokens
2.4K
Snippets
8
Records
11
Agent score
54%

What's inside dts-buddy

  1. What is dts-buddy?

    main

    dts-buddy is a tool for creating .d.ts bundles. It is specifically designed to solve the difficulty of exposing types for packages with subpackages (e.g., my-lib and my-lib/subpackage).

    Instead of using standard TypeScript declaration strategies that often require many extra files, dts-buddy generates a single bundle using declare module blocks. This approach ensures compatibility across environments, provides autocompletion, and allows 'go to definition' to work via .d.ts.map files. The resulting bundles are treeshaken to include only public types.

  2. How dts-buddy handles tsconfig paths

    main
    Unlike tsc, which ignores the paths option in tsconfig.json when emitting declaration files, dts-buddy correctly resolves these paths. This allows you to use clean imports in your source code (e.g., import { Thing } from '#types') while still generating valid, working type definitions in your bundle.
  3. Set up dts-buddy using package.json inference

    main

    You can automate type generation by configuring your package.json. dts-buddy will automatically infer the entry points and the output location from your package.json configuration.

    To set this up:

    1. Define a central .d.ts file (e.g., types/index.d.ts).
    2. Add the types property to the top level of package.json pointing to that file.
    3. Add the types key to every entry in your exports map pointing to that same file.
    4. Include the types directory in your files array.
    5. Add dts-buddy to your prepublishOnly script.
    {
      "name": "my-lib",
      "version": "1.0.0",
      "type": "module",
      "types": "./types/index.d.ts",
      "files": [
        "src",
        "types"
      ],
      "exports": {
        ".": {
          "types": "./types/index.d.ts",
          "import": "./src/index.js"
        },
        "./subpackage": {
          "types": "./types/index.d.ts",
          "import": "./src/subpackage.js"
        }
      },
      "scripts": {
        "prepublishOnly": "dts-buddy"
      }
    }
  4. Use the createBundle JavaScript API

    main

    For programmatic control, you can use the createBundle function from the dts-buddy package. This allows you to define the tsconfig.json project, the output file, and a mapping of modules to their respective source files.

    // scripts/generate-dts-bundle.js
    import { createBundle } from 'dts-buddy';
    
    await createBundle({
      project: 'tsconfig.json',
      output: 'types/index.d.ts',
      modules: {
        'my-lib': 'src/index.js',
        'my-lib/subpackage': 'src/subpackage.js'
      }
    });
  5. Define multiple modules with the --module flag

    main

    If you need to bundle specific entry points that are not automatically detected via package.json exports, use the --module (or -m) flag. Each entry must follow the format <id>:<path>. You can provide this flag multiple times to include several modules in a single bundle.

    dts-buddy my-bundle.d.ts --module core:src/core.ts --module utils:src/utils.ts
  6. Use the dts-buddy CLI with manual configuration

    main

    If you cannot rely on package.json inference (for example, if you need to use a .d.ts file that re-exports from a .js file as an entry point), you can specify the output path and modules manually using the CLI. Use the -m flag to map a module name to its source file.

    dts-buddy types/index.d.ts -m my-lib:src/index.js -m my-lib/subpackage:src/subpackage.js
  7. Use create_module_declaration to generate module declarations

    main

    The create_module_declaration function is the core engine for generating bundled .d.ts files. It performs a three-step process: discovering included modules via dependency tracing, tree-shaking unused declarations, and generating the final TypeScript declaration code. It handles external imports, namespace imports, and re-mapping identifiers to ensure that only the public API is exposed in the resulting declaration file.

    Parameters

    ParameterTypeDescription
    idstringThe module identifier (e.g., the package name) for the declare module 'id' block.
    entrystringThe entry point file path used to start the dependency discovery.
    createdRecord<string, string>A map of already created files/modules.
    resolve(file: string, specifier: string) => string | nullA resolver function to locate modules.
    optionsobjectConfiguration options.

    Options

    OptionTypeDefaultDescription
    stripInternalbooleanundefinedIf true, declarations marked as internal (using @internal or similar) and their properties will be removed from the output.

    Returns

    An object containing:

    • content: The generated .d.ts file string.
    • mappings: A Map<string, Mapping> containing source mappings for the generated declarations.
    • ambient: An array of ModuleReference[] representing ambient imports.
    /**
     * @param {string} id
     * @param {string} entry
     * @param {Record<string, string>} created
     * @param {(file: string, specifier: string) => string | null} resolve
     * @param {{ stripInternal?: boolean }} options
     * @returns {{ 
     *   content: string;
     *   mappings: Map<string, Mapping>;
     *   ambient: ModuleReference[];
     * }}
     */
    export function create_module_declaration(id, entry, created, resolve, options) {
      // ... implementation
    }
  8. Create a declaration bundle with createBundle()

    main

    The createBundle function allows you to programmatically generate a bundled .d.ts file from a set of modules. It handles TypeScript path aliases, resolves ambient modules, and generates source maps to link the bundled declarations back to their original source files. This is useful for creating clean, single-file type definitions for libraries that otherwise have complex internal structures or many files.

    import { createBundle } from 'dts-buddy';
    
    await createBundle({
      output: 'dist/index.d.ts',
      modules: {
        '@my-lib/core': './src/core.ts',
        '@my-lib/utils': './src/utils.ts'
      },
      project: 'tsconfig.json',
      // Optional overrides
      include: ['src/**/*'],
      exclude: ['**/*.test.ts'],
      compilerOptions: {
        baseUrl: './'
      }
    });
  9. Configure createBundle options

    main

    The createBundle function accepts an options object with the following properties:

    OptionTypeDescription
    outputstringRequired. The path where the resulting .d.ts file will be written.
    modulesRecord<string, string>Required. A mapping of module IDs to their entry point file paths. The paths are resolved and converted to .d.ts internally.
    projectstringThe path to the tsconfig.json file. Defaults to 'tsconfig.json'.
    compilerOptionsts.CompilerOptionsTypeScript compiler options to merge with those found in the project tsconfig.
    includestring[]Files or patterns to include in the bundle. If omitted, uses tsconfig.json include or defaults to ['**'].
    excludestring[]Files or patterns to exclude. If omitted, uses tsconfig.json exclude.
    debugstringIf provided, the path to a directory where intermediate files and generated declarations will be written for debugging.
  10. Reference dts-buddy CLI options

    main

    The following flags are available when running the dts-buddy command:

    FlagAliasDescription
    --project-pThe location of your TypeScript configuration (defaults to tsconfig.json)
    --module-mDefine entry points as <id>:<path>. This can be used multiple times to specify multiple modules
    --debugA directory to emit .d.ts files for debugging
    --versionDisplay the current version of dts-buddy
    dts-buddy [bundle] \
      --project tsconfig.json \
      --module id1:path/to/file.ts --module id2:path/to/other.ts \
      --debug ./debug-dir
  11. Use the dts-buddy CLI

    main

    The dts-buddy CLI tool generates type definition bundles from your TypeScript project. By default, it attempts to resolve entry points from the exports field in your package.json. If no bundle path is provided as a positional argument, it defaults to the types field in package.json or index.d.ts.

    dts-buddy [bundle]