Warrick FitzGerald
Warrick FitzGerald

Reputation: 2835

Including legacy JS into a Typescript module

The business has an old JS file called legacy.js
The goal is to use this file in a new module that’s being written using
Typescript. We’ll call this the “jumper” module.

Another developer will then pull this module from git and use the module in a project called “jumperdemo” and get the following error:

Failed to compile.

../jumper/dist/index.js Module not found: Can't resolve 'Legacy' in '{base path}\jumper\dist'

Simple repo steps:

git clone https://github.com/warrick-eosny/jumper.git
cd jumper
npm install
tsc 
cd dist
npm link

cd ..

git clone https://github.com/warrick-eosny/jumpdemo.git
cd jumpdemo
npm install
npm link jumper
yarn start

It's becoming clear to me that this pattern does not work well, but what's unclear is what the better pattern would be.

I know I'm not the 1st person to want to include legacy JS into a TS module, so I'm clearly missing something important.

Upvotes: 2

Views: 1536

Answers (1)

Shaun Luttin
Shaun Luttin

Reputation: 141722

One Approach for Your Specific Situation

First change your *.d.ts file.

  • Remove declare module 'Legacy' to make a declaration for a ./relative module.
  • Add export default class... to match the legacy.js export style.
  • Move the file to src/legacy.d.ts so its path matches the legacy module's path.

Then change your src/index.ts file to import and instantiate the default export of the legacy class.

The result will look like this (with some code omitted).

// src/index.ts
import legacy from './legacy';
let oldObj = new legacy(); 

// src/legacy.js (unchanged)
export default class OldOldClass {
    runSuperOldLogic(someInput) {
        console.log('really old logic run ' + someInput);
    }
}

// src/legacy.d.ts
export default class OldOldClass {
    runSuperOldLogic(someInput: string): any;
}   

Two Alternate Approaches

The TypeScript docs have an article on migrating from JavaScript. There are too many approaches to detail all of them. Here are two that might fit your situation: use allowJs to consume local JavaScript without types; or, change legacy.js to legacy.ts and put types inline with the implementation.

And...

I forked your terrific minimal sample repo and made a PR for it here https://github.com/warrick-eosny/jumper/pull/1/jumper

Upvotes: 2

Related Questions