Typescript 惯用语将属性添加到与方法定义内联的方法中

Typescript idioms around adding properties to methods inline with the method definition

打字稿中是否有任何习语可以在 class 内联方法定义中定义方法的属性?

我正在寻找类似于 .NET 属性的内容。

这是我目前所获得的示例

class FooController {
    foo(req: express.Request, res: express.Response) {
        res.send(JSON.stringify({ loc: 'FooController::foo 2 here '+req.params.fooId }));
    }
    bar(req: express.Request, res: express.Response) {
        res.send(JSON.stringify({ loc: 'FooController::bar here' }));
    }
}
FooController.prototype.foo['route'] = '/foo/:fooId';
FooController.prototype.foo['verb'] = 'get';
FooController.prototype.bar['route'] = '/bar';
FooController.prototype.bar['verb'] = 'post';

其中一个不同的函数将使用 FooController 并询问方法属性以在调用任何 FooController 方法之前设置路由table。

我不喜欢我的方法定义和我的 属性 定义之间的距离,尤其是当我的方法变得更大并且支持函数位于两者之间时。

这里有什么我可以做的更好的吗?如果除了属性之外,我应该使用不同的语言功能来表达这一点,我对此持开放态度。如果解决方案保留类型安全,我特别感兴趣。

我确实查看了 build a function object with properties in typescript,但由于延迟绑定和对象方法要求,我认为其中的解决方案不匹配。

我在 Visual Studio 2013 Update 3 中使用 1.0.3 版的打字稿编译器。

这是 TypeScript 装饰器的理想候选者:https://github.com/Microsoft/TypeScript/issues/2249。您重构的代码:

class FooController {
    @route(/*put your config here*/)
    foo(req: express.Request, res: express.Response) {
        res.send(JSON.stringify({ loc: 'FooController::foo 2 here '+req.params.fooId }));
    }
    @route(/*put your config here*/)
    bar(req: express.Request, res: express.Response) {
        res.send(JSON.stringify({ loc: 'FooController::bar here' }));
    }
}

请注意,您将需要很快就会发布的 TypeScript 1.5。

保持路由方法类型安全的最简单方法是定义一个接口:

interface IRoute {
    (req: express.Request, res: express.Response): void;

    route?: string;
    verb?: string;
}

然后将路由方法定义为实现 IRoute 接口的属性。然后你可以使用构造函数来定义额外的 routeverb 属性:

class FooController {

    constructor(){
        // Type-safety on these properties:
        this.foo.route = '/foo/:fooId';
        this.foo.verb = 'get'

        this.bar.route = '/bar';
        this.bar.verb = 'post';
    }

    // Use fat-arrow syntax to bind the scope to this instance.
    foo: IRoute = (req: express.Request, res: express.Response) => {
        this.bar(req, res);
    }

    bar: IRoute = (req: express.Request, res: express.Response) => {
        // TypeScript knows about the additional properties on `this.foo`.
        this.foo.route;

        res.send(JSON.stringify({ loc: 'FooController::bar here' }));
    }

}

构造函数和路由方法之间可能还有一点 "distance",但好处是:

  • 您获得类型安全
  • 您不必 fiddle 使用 FooController.prototype['foo']...
  • 在class定义中都是自包含的

Here's the above example in the TypeScript playground.