Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injectable decorator is still required #1638

Open
2 of 4 tasks
ffMathy opened this issue Nov 14, 2024 · 1 comment
Open
2 of 4 tasks

Injectable decorator is still required #1638

ffMathy opened this issue Nov 14, 2024 · 1 comment

Comments

@ffMathy
Copy link

ffMathy commented Nov 14, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

In version 6.1.0, this release note was added:

injectable decorator is no longer required.

Can you detail how that works? Currently if I try to remove my @injectable() decorators on my classes, I get these errors everywhere:

Error while synchronizing SKU "01932c80-1010-743d-92c5-06c8887b2107" with error Error: Found unexpected missing metadata on type "SomeClass" at constructor indexes "0".
  
  Are you using @inject, @multiInject or @unmanaged decorators at those indexes?
  
  If you're using typescript and want to rely on auto injection, set "emitDecoratorMetadata" compiler option to true

Steps to reproduce

No response

Expected behavior

I expected Inversify to still work without that decorator on the class.

Possible solution

No response

Package version

6.1.4

Node.js version

23.0.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Stack trace

No response

Other

No response

@notaphplover
Copy link
Member

Hey @ffMathy, I have been investigating the issue. Tbh, it seems @injectable will continue being mandatory.

The issue

Currently, injectable decorator should not be required. Metadata readers are prepared to fetch tsc metadata from design:paramtypes.

Unfortunatelly, it seems design:paramtypes is only included in the class metadata if and only if there's at least one class decorator applied to the class.

Having emitDecoratorMetadata set to true:

import 'reflect-metadata';
import { injectable } from 'inversify';

@injectable()
class B {
  readonly foo: string = 'foo';
}

@injectable()
class A {
  constructor(public readonly b: B) {}
}

is transpiled into

Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
const inversify_1 = require("inversify");
let B = class B {
    foo = 'foo';
};
B = __decorate([
    (0, inversify_1.injectable)()
], B);
let A = class A {
    b;
    constructor(b) {
        this.b = b;
    }
};
A = __decorate([
    (0, inversify_1.injectable)(),
    __metadata("design:paramtypes", [B])
], A);

If we remove the injectable decorator:

import 'reflect-metadata';

class B {
  readonly foo: string = 'foo';
}

class A {
  constructor(public readonly b: B) {}
}

It's transpiled into

Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
class B {
    foo = 'foo';
}
class A {
    b;
    constructor(b) {
        this.b = b;
    }
}

To sum it up, @injectable is required if you expect typescript metadata to be provided.

I'll update docs and the next version will have docs updated. Until that, I'll leave this issue open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants