Typescript declaration file created with alias instead of relative path

8.4k Views Asked by At

Edit 1: Added GitHub URL to project

Edit 2: Removing baseUrl from tsconfig.json fixes all problems and using relative imports works fine.

Link: Github

How do I generate a typescript declaration file with relative paths instead of alias?

I am creating a library(samplelibrary) in UMD mode and publishing it in npm. The packed npm library has only build folder(with typings), package.json and README.md

When I try to consume the library in another typescript app, the build fails due to invalid type declaration file which is being generated. The type declaration file contains alias instead of relative path.

Compilation log:

ERROR in /workspace/myproject/node_modules/samplelibrary/build/typings/src/foo.d.ts(403,17): TS2307: Cannot find module 'utils/bar

How to fix this problem?

Actually created declaration file foo.d.ts:

declare const Foo: {
   bar: typeof import("utils/bar");
}

Expected file:

declare const Foo: {
   bar: typeof import("./utils/bar");
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "moduleResolution": "node",
    "jsx": "react",
    "sourceMap": true,
    "rootDir": "./",
    "baseUrl": "./src",
    "paths": {
      "@samplecompany/sampleproject": ["./"]
    },
    "outDir": "build",
    "removeComments": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "declaration": true,
    "declarationDir": "typings",
    "importHelpers": true
  },
  "files": ["types/untyped-modules.d.ts"],
  "include": [
    "src/**/*",
    "test/**/*",
    "build/**/*",
    "styleguide-renderer/**/*"
  ],
  "exclude": ["node_modules"]
}

Folder structure:

root
  -src
    -utils
       -bar.ts
    -foo.ts

utils/bar.ts

export const bar = {
   hello: "World"
}

src/foo.ts

import { bar } from "./utils/bar.ts

export default const Foo = {
    bar
};
3

There are 3 best solutions below

2
On BEST ANSWER

To fix this issue,

  • Remove baseUrl usage from your typescript config.
  • Use only relative imports in your project like ../somefile, ./somefolder/file, etc.,

Fixed here

2
On

You are out of luck: TypeScript doesn't rewrite import paths. See this declined suggestion. You'll need to refrain from using aliases in your library unless you configure the aliases in the consuming project too.

0
On

Well it seemed like it wouldn't work without major trickery but eventually, I figured it out. So the problem is the type declaration paths need to be rewritten. To do this you need some bundler/compiler to do it for you. I guess there are various packages that do it for tsc based compilation but in my case I am using Rollup so there weren't that many. Well, I found just one https://github.com/zerkalica/zerollup/tree/master/packages/ts-transform-paths

There are instructions there to help you to use it. But basically what you need to do is:

  1. Install yarn add -D @zerollup/ts-transform-paths ttypescript
  2. Include it in your rollup.config.js
  3. Add the plugin to your tsconfig.json with "plugins": [{ "transform": "@zerollup/ts-transform-paths" }]

And now my paths are rewritten from eg @react to "../../react/file". Yey!

And just for good measure, here are my configs:

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "declaration": true,
    "declarationDir": "./dist",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "baseUrl": ".",
    "paths": {
      "@context/*": ["src/context/*"],
      "@pm/*": ["src/pm/*"],
      "@react/*": ["src/react/*"],
      "@typings/*": ["src/typings/*"]
    },
    "plugins": [{ "transform": "@zerollup/ts-transform-paths" }]
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}
import alias from '@rollup/plugin-alias'
import typescript from 'rollup-plugin-typescript2'
import postcss from 'rollup-plugin-postcss'
import ttypescript from 'ttypescript'

import path from 'path'

import pkg from './package.json'

export default {
  input: 'src/index.ts',
  output: [
    {
      file: pkg.main,
      format: 'cjs',
    },
    {
      file: pkg.module,
      format: 'es',
    },
  ],
  external: [
    ...Object.keys(pkg.peerDependencies || {}),
  ],
  plugins: [
    alias({
      entries: [
        { find: '@context', replacement: path.resolve(__dirname, 'src/context') },
        { find: '@pm', replacement: path.resolve(__dirname, 'src/pm') },
        { find: '@react', replacement: path.resolve(__dirname, 'src/react') },
        { find: '@typings', replacement: path.resolve(__dirname, 'src/typings') },
      ]
    }),
    typescript({
      typescript: ttypescript
    }),
    postcss()
  ],
}