TypeScript
TypeScript copied to clipboard
Alias for TypeScript declaration emitting
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.
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 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.
Voting for this to be supported
Support optional compile-time alias replacing too.
- It will allow to generate correct source code for node without odd plugins/transpilers. There is so many questions and custom solutions for it.
- 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.
Same as: https://github.com/Microsoft/TypeScript/issues/15479
Voting for this to be supported
any progress on this ?
I need this to be supported!!
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’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
tscfor 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
../../modulesyntax 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
tscresolve 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
tsc-alias works for me, thanks @zq0904 , same as tscpaths, resolve-tspaths .
@RyanCavanaugh any plan about this?
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
tscfor 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../../modulesyntax 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 havetscresolve 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 :(
Would love an update on this 🙏🏼
+1 would love an update.
+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
+1 this should be natively supported in tsc.