0

Suppose a class adds itself to an other class as follows

bar.ts:

import { Foo } from './foo';

export class Bar {}

Foo.prop = Bar;

And file foo.ts

export class Foo {
    public static prop: any;
}

Now, if would like to use this in index.ts

import { Foo } from './foo';

console.log(Foo.prop); // -> undefined

It is undefined. It looks like that bar.ts is not used at all (probably tree shaking). So I can fix that as follows:

import { Foo } from './foo';
import { Bar } from './bar';

new Bar(); // trick!
console.log(Foo.prop); // -> Bar

Is there a way to tell typescript to include Bar anyway, because the solution I showed is ugly.

For completeness, here is my tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "sourceMap": true,
    "noImplicitAny": false,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2017",
    "outDir": "./dist",
    "baseUrl": "./",
    "lib": ["es2017", "dom", "dom.iterable"]
  },
  "exclude": ["node_modules", "**/*.spec.ts", "dist"]
}
Jeanluca Scaljeri
  • 26,343
  • 56
  • 205
  • 333

1 Answers1

0

Foo.prop = Bar;

is what is causing the issue, you're doing this in Bar.ts, do this in Foo.ts, now when you create a new object of Foo in index.ts, tree shaking won't remove Bar.ts.

As a general rule, if you need to add a dependency to a class,always do that in the file where the class is defined (Foo.ts in this case)

DesTroy
  • 390
  • 4
  • 17
  • I understand, but thats not going to work for me, unfortunate. The reason I want this is because of a dependency injection library ( https://www.npmjs.com/package/di-xxl ) At the end you have decorators like `@Injectable` which registeres the class to the DI class (basically the same thing as my question describes). I just migrated that lib to typescript and now it doesn't work any more :( – Jeanluca Scaljeri May 27 '19 at 07:11
  • You could use a typescript based DI Library, like typedi(extremely simple) or inversify ( A bit confusing in the start, but powerful if you understand it well!) – DesTroy May 27 '19 at 11:06
  • Only other solution I see here it so do what you have done, and force create an object of type Bar in index.ts. – DesTroy May 27 '19 at 11:07
  • 1
    I've written a tool which injects the imports such that typescript uses the files. Works pretty well. I think that angular does more or less the same thing with its `@Injectable({ providedIn: 'root'})` – Jeanluca Scaljeri May 28 '19 at 07:31