2

I have a module which is a collection of helper classes, each defined in their own files: controller.ts, stateService.ts and so on. From what I gather the way to have them all exported is to create an index.ts that imports all of them and then exports them (serving as an interface to the module).

By and large my files look something like this:

export default class Controller {
    public state: stateService; // This will become relevant in a moment

    // other things in the class
}

And my index.ts is a list of these:

export { default as Controller } from './controller';

My tsconfig.json is like so:

{
    "compilerOptions": {
        "moduleResolution": "node",
        "noImplicitAny": true,
        "preserveConstEnums": true,
        "outDir": "dist",
        "sourceMap": true,
        "noEmitOnError": true,
        "target": "es6",
        "module": "commonjs",
        "declaration": true,
        "experimentalDecorators": true,
        "suppressImplicitAnyIndexErrors": true
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules", "tests", "src/**/*.spec.ts"],
    "types": ["jest"]
}

Now I have an example project to test the module locally with npm link:

export default class OwnerController extends Controller {
    foo() {
        this.state.get(bar);
    }
}

I get the following error when I try to use my Controller class in a dependent project and access the state property:

[ts] Property 'state' does not exist on type 'OwnerController'. [2339]

In much the same way, class methods also get this error:

[ts] Property 'start' does not exist on type 'CarExampleApp'. [2339]

Can anyone advise as to what I'm doing wrong? (thanks!)

MysteriousWaffle
  • 439
  • 1
  • 5
  • 16
  • What is the `OwnerController` object? Is it something like `class OwnerController extends Controller { ... }`? – aravindanve Dec 02 '18 at 09:46
  • It is yeah, I'll update the above now – MysteriousWaffle Dec 02 '18 at 09:46
  • I don't see anything wrong with the code you have described. Are you linking a compiled module or are you directly importing the `index.ts` file at the root of your module. If you are using the compiled variant, have you checked the compiled definitions in `controller.d.ts`? maybe you'll find something there – aravindanve Dec 02 '18 at 10:06
  • I compile it and in package.json specify that `./dist/index.js` is the entry point to the module. – MysteriousWaffle Dec 02 '18 at 10:13
  • Within `controller.d.ts` I have this: ` export default class Controller { state: StateService; // other stuff }` So to me it looks fine, inside `index.d.ts` I just have export { default as Controller } from './controller'; There's another class in `controller.d.ts` with the `declare` keyword, is `declare` something I should use or `module`? I assume that even if there's a `controller.d.ts` I still need to import in `index.d.ts` for it to show up? – MysteriousWaffle Dec 02 '18 at 10:20
  • Hmm. `npm link` also has its quirks. Sometimes the code consuming the linked module doesn't see the latest version of the code. I'm not sure if this has been fixed in npm. Can you try `npm link` again? – aravindanve Dec 02 '18 at 12:58
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/184583/discussion-between-aravindan-ve-and-mysteriouswaffle). – aravindanve Dec 02 '18 at 12:59

1 Answers1

1

I found the issue eventually, @Aravindan has pointed out make sure to re-run npm link after you do a build just to check it's always on the latest version.

What turned out to be the issue for me is that the name of the dependent project was the same as the project it was dependent on in package.json.

MysteriousWaffle
  • 439
  • 1
  • 5
  • 16