Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow `emitDeclaration` and `isolatedModules` together #29490

Open
SimenB opened this issue Jan 19, 2019 · 12 comments

Comments

Projects
None yet
6 participants
@SimenB
Copy link

commented Jan 19, 2019

Search Terms

isolated modules emit declaration

Suggestion

In the blog post introducing Babel 7, it's recommended to use --isolatedModules in the "Caveats" section (https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/).

We use Babel to transpile our TS to better work with other tools in the ecosystem (such as Emotion or Jest), but we'd also still like to generate declaration files so consumers of our libraries can enjoy the type information.

However, when trying to follow the advice of adding isolatedModules to our config, we get the following warning:

tsconfig.json:5:5 - error TS5053: Option 'declaration' cannot be specified with option 'isolatedModules'.

5     "declaration": true,
      ~~~~~~~~~~~~~

Use Cases

As mentioned, I'd like to create declaration files for libraries who are transpiled using babel. I'd also like to make sure that whatever guarantees isolatedModules adds to allowed syntax are present, outside of the type information.

Babel itself will complain if we use e.g. const enum, but that only happens at compile time - isolatedModules will also show a warning in the IDE while writing the code.

Examples

Same as we currently get with {"declaration": true, "emitDeclarationOnly": true}, but with added {"isolatedModules": true}.

Checklist

My suggestion meets these guidelines:

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

This comment has been minimized.

Copy link
Member

commented Jan 19, 2019

I am also looking for something similar. I will be using babel as a compiler via webpack for a monorepo, but still want features like project references for the editor experience in my monorepo and generating d.ts files for packages that are published.

For my situation having a way to enforce the same limitations on language features that aren't supported by isolated modules without the restrictions on other typescript features would be ideal. I think that just means having an alternative way of treating usage of const enum, namespace, and re-exporting types by name as errors.

@mheiber

This comment has been minimized.

Copy link
Contributor

commented Feb 28, 2019

Why does this restriction currently exist?
Related StackOverflow question asking about the restriction: https://stackoverflow.com/questions/49403410/why-declaration-can-not-be-used-together-with-isolatedmodules-in-typescript

@RyanCavanaugh RyanCavanaugh self-assigned this Feb 28, 2019

@DanielRosenwasser

This comment has been minimized.

Copy link
Member

commented Feb 28, 2019

Everyone in the room is currently trying to figure out why this is a restriction. 😅

@mheiber

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

It looks like the restriction was there since the branch for separate-compilation (now isolatedModules) was first merged into master.

The restriction was added (I think) in response to feedback which pointed out that declaration: true makes no sense for transpile (now transpileModule).

Maybe the same restrictions need not apply for isolatedModules and transpileModule, since allowing emit of declaration files makes sense for the former but not the latter.

@mheiber

This comment has been minimized.

Copy link
Contributor

commented Mar 20, 2019

@RyanCavanaugh @SimenB proposed above allowing emitDeclaration and isolatedModules together. This issue is marked Needs Proposal.

What else is required in order for this to be a full-fledged proposal?

@weswigham

This comment has been minimized.

Copy link
Member

commented Mar 20, 2019

FYI, for anyone still reading this: The reason is for the same reason you can't use const enums in isolated modules: type information. Since isolated modules compiles each file individually without the types of the files it depends on, any inferred type we would write to a declaration file would potentially be incorrect, as their calculation would be missing information from the rest of the compilation. There is a limited subset of declaration emit where no types are inferred in the output which could be supported, however.

@mheiber

This comment has been minimized.

Copy link
Contributor

commented Mar 20, 2019

Thanks Wesley! I understand now.

What's recommended way for a user of babel-typescript to also generate declaration files? Something like the following?

  • Have a main tsconfig used for building and checking
  • Have another tsconfig for declarations that extends the first tsconfig and has the following overrides: {"isolatedModules": false, "emitDeclarationOnly": true}

@SimenB would that meet your needs as well?

@SimenB

This comment has been minimized.

Copy link
Author

commented Mar 20, 2019

I'd have to run tsc twice? Would that bust the cache of tsconfig.tsbuildinfo?

@weswigham

This comment has been minimized.

Copy link
Member

commented Mar 20, 2019

I'd have to run tsc twice? Would that bust the cache of tsconfig.tsbuildinfo?

You should be able to specify a separate tsbuildinfo path for each build so they don't mangle one another's incremental data.

@mheiber

This comment has been minimized.

Copy link
Contributor

commented Mar 20, 2019

@weswigham it doesn't seem like specifying the a separate tsbuildinfo path may not be necessary

I'm seeing that the name of the tsconfig is automatically used as part of the name of the tsbuildinfo file.

Given these tsconfigs:

tsconfig.json

{
    "compilerOptions": {
        "incremental": true,
        "isolatedModules": true
    }
}

tsconfig-for-declarations.json

{
    "extends": "./tsconfig",
    "compilerOptions": {
        "emitDeclarationOnly": true,
        "isolatedModules": false,
        "declaration": true
    }
}

When I run both tsc and tsc -p tsconfig-for-declarations.json I see two separate buildinfo files on disk:

  • tsconfig-for-declarations.buildinfo
  • tsconfig.buildinfo

tested on Version 3.4.0-dev.20190320

@mheiber

This comment has been minimized.

Copy link
Contributor

commented Apr 21, 2019

@weswigham , you said:

There is a limited subset of declaration emit where no types are inferred in the output which could be supported, however.

Would this be the same limited subset that applies to TS files? If so, it seems like the restrictions would be worth it. Would implementing this change be a big effort or a small tweak? I know some people who may be interested in implementing.

@mheiber

This comment has been minimized.

Copy link
Contributor

commented May 20, 2019

@weswigham checking in on this issue again.

We'd really like to get the extra checks from --isolatedModules while also generating declaration files. Doing an extra pass would really slow down our pipeline.

Is more information needed? Some question here. Thanks for your help with this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.