Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaration will not emit due to private name usage

I'm trying to convert a project to TypeScript, and I have most things set up, but I'm still struggling with getting the last few pieces put together. I want to be able to use this TypesScript project from a normal JavaScript project, so my understanding is that I need to emit d.ts files for my existing sources. My sources are all .js currently and we plan to slowly migrate to TS over time. My issue is getting the declarations to emit with the current exports/require statements.

A simple demonstration of the issue:

mod1.js

class MyClass {
    constructor(name) {
        this.name = name;
    }
}

module.exports = {
    MyClass,
};

mod2.js

const mod1 = require('./mod1');

module.exports = {
    MyClass: mod1.MyClass,
};

As soon as I try to export MyClass in mod2 in order to re-route the namespace one can access MyClass from when consuming the project, I get Declaration emit for this file requires using private name 'MyClass' from module '"mod1"'. An explicit type annotation may unblock declaration emit.ts(9006)

We have a lot of re-routes in our code base, groups of files that hold various classes, and then we use index.js files at each dir level to define which items are available in that namespace, and sometimes a bunch of UI elements which are instantiated class instances so we can make calls such as:

const {app, appui} = require('our-cool-app');
app.feature1.doSomething();
appui.component.someButton.click();

Is there an easy fix to get our d.ts files auto generated from the .js sources?

like image 784
iceblueorbitz Avatar asked Jan 31 '20 18:01

iceblueorbitz


2 Answers

The best way to fix this is to export the class with ES6 compatibility; MyClass is exported using CommonJS format when you write module.exports, but not in ES6 format. For MyClass you can do one of the following in mod1.js:

export class MyClass {
    constructor(name) {
        this.name = name;
    }
}

module.exports = {
    MyClass,
};

Or, my recommended way, as it's more visible:

class MyClass {
    constructor(name) {
        this.name = name;
    }
}

module.exports = {
    MyClass,
};

exports { MyClass };

Try one of these and see if you get results.

like image 140
Arcsector Avatar answered Oct 19 '22 21:10

Arcsector


I solved this for a similar by adding a JSDoc @type comment above the offending thing. In my case I had a class that had a getter which returned a different class and any usage of the getter would give this error. YMMV.

So this...

// File Foo.js
class Foo {
  get Bar() {
    return Bar;
  }
}
class Bar {};

// File Blah.js
const Foo = require('./Foo.js');
class Blah extends Foo.Bar {}      <--- Error would be here

Is fixed by this...

/**
 * @type Class
 */
get Bar() {
  return Bar;
}
like image 28
Arei Avatar answered Oct 19 '22 22:10

Arei