tsdx: Error when building a file that imports .d.ts file (no .ts file)

Current Behavior

TSDX (probably Rollup behind the scenes) struggles with building a src/index.ts file that imports generated types. Here’s a repo with a reproduction: https://github.com/pcowgill/tsdx-typechain/

This line - import { Greeter } from "../typechain/Greeter"; - isn’t working.

Greeter is a .d.ts file.

I might need to configure Rollup via TSDX, there might be a simple change to the tsconfig.json that can address it, or maybe something else needs to be done.

Error: Could not resolve '../typechain/Greeter' from src/index.ts

    at error (/Users/paulcowgill/Code/tsdx-typechain/node_modules/rollup/dist/shared/node-entry.js:5400:30)

    at ModuleLoader.handleResolveId (/Users/paulcowgill/Code/tsdx-typechain/node_modules/rollup/dist/shared/node-entry.js:12410:24)

    at ModuleLoader.<anonymous> (/Users/paulcowgill/Code/tsdx-typechain/node_modules/rollup/dist/shared/node-entry.js:12298:30)

    at Generator.next (<anonymous>)

    at fulfilled (/Users/paulcowgill/Code/tsdx-typechain/node_modules/rollup/dist/shared/node-entry.js:38:28)

Expected behavior

tsdx build completes and uses the .d.ts type files I imported in src/index.ts.

Suggested solution(s)

I’m not sure if I need a rollup plugin, a different set of choices in tsconfig.json, or something else. If it’s a rollup plugin I need, then just some docs for TSDX would be the change to make. If it’s a tsconfig.json change, then maybe the default TSDX tsconfig.json could be different to accommodate this type of usage too while still supporting the existing use cases.

Additional context

I used TypeChain to generate the types since it’s an Ethereum-related project, but I don’t think you need to worry about how the .d.ts types were generated to debug this issue. The type I’m trying to import is here https://github.com/pcowgill/tsdx-typechain/blob/primary/typechain/Greeter.d.ts

Your environment

Software Version(s)
TSDX 0.13.2
TypeScript 3.9.5
Browser n/a
npm/Yarn npm 6.14.4
Node 12.18.0
Operating System macOS 10.15.5

Thanks!!

About this issue

Most upvoted comments

@agilgur5 tsdx builds successfully when using the import type syntax rather than just import.

https://github.com/ethereum-ts/TypeChain/issues/247#issuecomment-648139358

Thanks those details are helpful.

Currently in Project 1 tsdx build works fine and i’m able to publish the npm package and pull it in Project 2 and make use of MyContractFactory.ts but any functions in MyContractFactory.ts that return types declared in MyContract.d.ts get returned as type any

Gotcha, yea I’m pretty sure that’s due to #113, which is actually TS’s own behavior – so TSDX and rpt2 don’t diverge on that (as of right now). You’ll need to copy over any declaration files into your dist/ folder (in the right location) so that they exist after publish as well. Or have typechain output to the dist/ folder initially. Basically declaration files are already compiled artifacts so TS doesn’t transform them in any way when compiling, it just references them for type-checking. So you have to manually copy those if you want your consumers to be able to use them too.

@agilgur5 Apologies I should’ve given more detail. I’m using the same typechain tool as @pcowgill . Thats why I believe I have a similar issue. I have 2 Typescript projects : Project 1 : Holds smart contracts and uses typechain to generate typescript bindings. Uses tsdx to build and then npm package. Project 2: Uses npm to install Project 1 and make use of generated typescript bindings.

Project 1 has the folder structure:

src/
  index.ts
  typechain/
    MyContract.d.ts
    factories/
        MyContractFactory.ts

MyContract.d.ts and factories/MyContractFactory.ts are generated by typechain. MyContractFactory.ts imports & uses the types declared in MyContract.d.ts

index.ts is my own file contains just export * from './typechain/factories/MyContractFactory.ts';

Currently in Project 1 tsdx build works fine and i’m able to publish the npm package and pull it in Project 2 and make use of MyContractFactory.ts but any functions in MyContractFactory.ts that return types declared in MyContract.d.ts get returned as type any

It looks like the prettier + estlint config out of the box with tsdx doesn’t like that syntax, though.

Any idea how to fix this linting error when using this new approach?

Ack, I’m pretty sure that’s because the version of Prettier we use doesn’t support TS 3.8, which introduced type-only imports. Prettier v2+ supports TS 3.8. See also #657 / #632. TS 3.8 support has some build-chain issues though: https://github.com/formik/tsdx/pull/679#issuecomment-631478298 (and a number of breaking changes per #632). Will have to see if those have improved in the past few months as it blocks a few breaking upgrades (also the fact that they’re breaking means it’ll take time to release them). If you’re able to use pieces of TS 3.8 though then maybe those issues are only for certain features of TS 3.8 and not the whole thing.

It looks like the prettier + estlint config out of the box with tsdx doesn’t like that syntax, though.

Any idea how to fix this linting error when using this new approach?

Parsing error: '=' expected prettier/prettier

which refers to this line in the code:

import type { Greeter as GreeterType } from './types/Greeter';

Here’s a link to the reproduction for this error.

And here are the TypeScript docs for this syntax. Thanks!

One nit was that you didn’t put the specific error here so there’s a few clicks to get to it in the README, especially on mobile.

Good point. I just added the error to the description of this issue!