TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Alias for TypeScript declaration emitting

Open joshuaavalon opened this issue 6 years ago • 16 comments

Search Terms

  • alias
  • declaration

Suggestion

A way to configuration alias for declaration files.

Use Cases

Related: #10866

I understand that TypeScript team want to leaves module resolving for other tools like Webpack. However, most of the tools are focus on emitting JavaScript. If you want to emit TypeScript declaration, you need to use tsc.

This is important when you want to write library with TypeScript that you need to release declaration files.

For example, in Webpack, babel-loader does not emit declarations, ts-loader and awesome-typescript-loader uses tsc.

Alias is useful for you to write simpler import / export statement.

Examples

index.ts

export * from "~/foo";

index.d.ts

export * from "../../foo";

tsconfig.json

{
  "alias": {
    "~/*": ["src/*"]
  }
}

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.

joshuaavalon avatar Apr 16 '19 05:04 joshuaavalon

The example is so sparse I can't tell at all what's going on. Where did src go / come from? Where are these files on disk, and why? Where did ../../ come from? How did TS come up with those paths?

RyanCavanaugh avatar Apr 16 '19 16:04 RyanCavanaugh

@RyanCavanaugh Sorry for not enough information. Let me describe for the full details.

Folder structure Assume all index.ts export all from same level folder

Project/
├── src/
│   ├── index.ts
│   ├── model/
│   │    ├── index.ts
│   │    └── foo.ts
│   └── function/
│        ├── index.ts
│        └── baz/
│             ├── index.ts
│             └── bar.ts
├── webpack.config.js
└── tsconfig.json

To import Foo from foo.ts in bar.ts, you have to write the following.

import { Foo } from "../../model";

The problem become more serious when you have more level of nested folder.

In Webpack, we can use resolve to handle this (Support babel):

module.exports = {
  //...
  resolve: {
    alias: {
      "~": path.resolve(__dirname,  "src")
    }
  }
};

In Jest, we can use moduleNameMapper:

"moduleNameMapper": {
  "^~/(.*)": "<rootDir>/src/$1"
}

We also have tsconfig.json to support it in VSCode.

{
  "compilerOptions": {
    "rootDir": ".",
    "paths": {
      "~/*": ["src/*"]
    }
  }
}

Then, we can write the following instead

import { Foo } from "~/model";

These are enough when we are writing an application. However, when I try to write a package in TypeScript, I have to transpile it to JavaScript with TypeScript declaration.

Most of the TypeScript transpilers either does not transpile type declaration or use tsc, for example, babel suggest using tsc --emitDeclarationsOnly for declaration as babel does not do type-checking.

I have tested out how tsc --emitDeclarationsOnly. It emits ~/model without modification. There does not seem to have any tools to handle this for declarations. So, we have to fallback to "../../" because we have to support declarations.

This feature request is some sort of configuration that we can support alias feature in emitting declarations. If TypeScript can resolve with paths, it should able to emit declarations with correct paths.

joshuaavalon avatar Apr 17 '19 01:04 joshuaavalon

Voting for this to be supported

shuyu42 avatar May 30 '19 03:05 shuyu42

Support optional compile-time alias replacing too.

  1. It will allow to generate correct source code for node without odd plugins/transpilers. There is so many questions and custom solutions for it.
  2. d.ts files will be correct for webpack projects (where actual bundler transforms everything itself)

Currently we have to manually bundle .js and manage declarations as next step.

Neloreck avatar Jul 02 '19 15:07 Neloreck

Same as: https://github.com/Microsoft/TypeScript/issues/15479

Neloreck avatar Jul 02 '19 15:07 Neloreck

Voting for this to be supported

zhuguoxi avatar Jul 13 '20 13:07 zhuguoxi

any progress on this ?

nzhl avatar Feb 23 '21 10:02 nzhl

I need this to be supported!!

d2phap avatar May 09 '21 12:05 d2phap

I’ve read through the whole thread on #26722 for all the arguments between the community and the team behind TypeScript awhile ago. At the end of the day the TypeScript team declined to add support on tsc for compile-time alias resolve.

The pain point on this decision for me is that when developing an application, we can use Babel’s plugin or Webpack to resolve the path alias without any problem, there isn’t any tool to do the conversion on declaration files AFAIK. Hence, we have to fallback to the ../../module syntax when developing a library/package.

I think there’re a lot of TypeScript developers are already using Babel/Webpack for module alias on application development, so it’d be good to be able to do the same when we need to support declarations to keep the practice consistent. While there might be problems dealing with things like dynamic imports, but that could be handled by giving the developers option weather we want to have tsc resolve the module alias during compile time for us.

iamWing avatar Jul 08 '21 18:07 iamWing

I’ve read through the whole thread on #26722 for all the arguments between the community and the team behind TypeScript awhile ago. At the end of the day the TypeScript team declined to add support on tsc for compile-time alias resolve.

The pain point on this decision for me is that when developing an application, we can use Babel’s plugin or Webpack to resolve the path alias without any problem, there isn’t any tool to do the conversion on declaration files AFAIK. Hence, we have to fallback to the ../../module syntax when developing a library/package.

I think there’re a lot of TypeScript developers are already using Babel/Webpack for module alias on application development, so it’d be good to be able to do the same when we need to support declarations to keep the practice consistent. While there might be problems dealing with things like dynamic imports, but that could be handled by giving the developers option weather we want to have tsc resolve the module alias during compile time for us.

I agree with you that I tried tsc-alias to use this feature to solve my problem

tsc --emitDeclarationOnly --declarationDir esm && tsc-alias --directory esm

zq0904 avatar May 01 '22 12:05 zq0904

tsc-alias works for me, thanks @zq0904 , same as tscpaths, resolve-tspaths .

baurine avatar Jun 07 '22 09:06 baurine

@RyanCavanaugh any plan about this?

HomyeeKing avatar Aug 24 '22 02:08 HomyeeKing

I’ve read through the whole thread on #26722 for all the arguments between the community and the team behind TypeScript awhile ago. At the end of the day the TypeScript team declined to add support on tsc for compile-time alias resolve. The pain point on this decision for me is that when developing an application, we can use Babel’s plugin or Webpack to resolve the path alias without any problem, there isn’t any tool to do the conversion on declaration files AFAIK. Hence, we have to fallback to the ../../module syntax when developing a library/package. I think there’re a lot of TypeScript developers are already using Babel/Webpack for module alias on application development, so it’d be good to be able to do the same when we need to support declarations to keep the practice consistent. While there might be problems dealing with things like dynamic imports, but that could be handled by giving the developers option weather we want to have tsc resolve the module alias during compile time for us.

I agree with you that I tried tsc-alias to use this feature to solve my problem

tsc --emitDeclarationOnly --declarationDir esm && tsc-alias --directory esm

I've always been using rollup for library packing (in opposition to webpack). My workaround for the type declarations was the rollup-plugin-ts plugin, which squishes all type declarations in just one top-level index.d.ts file.

Unfortunately that tool lacks maintenance and it became outdated with the latest releases of rollup.

It's a pity that the TS team is so stubborn about admitting that the alias-resolution would be a very useful feature and indeed it would spare a lot of headaches for numerous TS users..

This feature request is over 3 years old and didn't get any attention from the team, not even just a prompt answer or a clue :(

zzeni avatar Dec 05 '22 23:12 zzeni

Would love an update on this 🙏🏼

Owen3H avatar Sep 06 '23 22:09 Owen3H

+1 would love an update.

jaswrks avatar Dec 02 '23 23:12 jaswrks

+1 The issues related to path aliases have been the biggest pain points in the TS toolchain for me. I haven't read the lengthy discussions on why the TS team doesn't want to replace alias paths in the compilation step, but I'm really hoping this can be resolved some day in a way that hides complexity from the user / developer.

I use TSUP to bundle a common package in a monorepo setup, and while TSUP can generate type definitions, I need to use TSC for that part instead in order to preserve go-to-definition within my repo, which is essential to me.

I was running into issues where parts of my types imported from common would use "any" for some of it's sub-types, and I found out it is because the some type definitions contain path aliases.

It's such a pain to have to invoke multiple tools and build steps to generate usable typescript output, and often gets in the way of watch tasks.

I will try tsc-alias as a workaround, but those type of tools really feel like a workaround for something that should be fixed on a more fundamental level.

I can confirm that tsc-alias works for me, but as I mentioned it breaks my current watch task... Hopefully the new turborepo watch mechanism (alpha) will be compatible

0x80 avatar May 17 '24 07:05 0x80

+1 this should be natively supported in tsc.

ehassaan avatar Aug 14 '24 18:08 ehassaan