Richard
Richard

Reputation: 16772

Why does Typescript not compile this InversifyJS decorator?

I'm copying the Inversify documentation almost exactly (version 1.2.2) and it fails to compile, giving me Typescript error TS1238. Why?

'use strict';
import './tools/typescriptImports';
import IServer = require('./iServer.ts');
import IDatabase = require('../database/iDatabase');
import express = require('express');
import bodyParser = require('body-parser');
import config = require('../config');
import types = require('../tools/types.ts');
import _ = require('lodash');
import async_ = require('async');
import { Inject } from "inversify";

@Inject("IDatabase") // <- error TS1238: Unable to resolve signature of class decorator when called as an expression. Supplied parameters do not match any signature of call target.
class Server implements IServer
{
    db : IDatabase;
    expressApp : express.Express;

    constructor(db : IDatabase)
    {
        this.db = db;
        ...
    }
}

Upvotes: 0

Views: 1617

Answers (2)

Remo H. Jansen
Remo H. Jansen

Reputation: 24979

We just release InversifyJS version 1.3.0 and it allows you to apply the Inject decorator to a class:

interface IKatana {
    power : number;
    hit() : boolean;
}

interface IShuriken {
    power : number;
    throw() : boolean;
}

@Inject("IKatana", "IShuriken")
class Warrior {

    private _katana : IKatana;
    private _shuriken : IShuriken;

    constructor(katana : IKatana, shuriken : IShuriken) {
        this._katana = katana;
        this._shuriken = shuriken;
    }
}

The following is not supported anymore:

class Warrior {

    private _katana : IKatana;
    private _shuriken : IShuriken;

    constructor(
        @Inject("IKatana") katana : IKatana, 
        @Inject("IShuriken") shuriken : IShuriken
    ) {
        this._katana = katana;
        this._shuriken = shuriken;
    }
}

Injections based on naming conventions are also not supported anymore:

class Warrior {

    private _katana : IKatana;
    private _shuriken : IShuriken;

    constructor(IKatana: IKatana, IShuriken: IShuriken) {
        this._katana = IKatana;
        this._shuriken = IShuriken;
    }
}

Upvotes: 2

John Weisz
John Weisz

Reputation: 31934

Looking at the source code, Inject can in no way be a class decorator. Class decorators are expected to return a constructor function, but the decorator returned by Inject is returning void (Inject is a decorator factory, which is returning the decorator function itself).

Inject in fact returns a parameter decorator, and - as its name implies - should be used to decorate a method parameter:

class Server implements IServer
{
    db : IDatabase;
    expressApp : express.Express;

    constructor(@Inject("IDatabase") db : IDatabase)
    {
        this.db = db;
        ...
    }
}

Upvotes: 3

Related Questions