当我在类中时,如何通过 TypeScript 中类的名称来执行该类的方法?

问题描述 投票:0回答:1

我正在开发一个类来自动为 Express 创建路由并调用控制器中的函数。但是,当我尝试执行

this[methodName](req, res)
时,我遇到错误消息:“元素隐式具有“任意”类型,因为“字符串”类型的表达式不能用于索引“AbstractActionController”类型。在类型“AbstractActionController”.ts(7053) 上找不到带有“字符串”类型参数的索引签名。我已经广泛搜索了答案,但还没有找到。我相信我需要指定类型,但我不确定如何这样做。

import AbstractActionControllerInterface from './interfaces/AbstractActionControllerInterface'
import { Application, Request, Response } from 'express'

class AbstractActionController implements AbstractActionControllerInterface {
    public alias: string
    private app: Application

    constructor(alias: string, app: Application) {
        this.alias = alias === 'index' ? '' : alias
        this.app = app

        this.registerActionRoutes()
    }

    /**
     * registerActionRoutes
     *
     * Called to log the routes with Action indicator in a controller.
     */

    private registerActionRoutes() {
        const classMethods = Object.getOwnPropertyNames(
            Object.getPrototypeOf(this),
        )

        for (const methodName of classMethods) {
            if (methodName !== 'constructor' && methodName.includes('Action')) {
                let route = methodName.split('Action')[0]

                route = route === 'index' ? '' : route

                this.app.all(
                    `${this.alias}/${route}`,
                    (req: Request, rep: Response) => {
                        if (typeof this[methodName] === 'function') {
                            this[methodName](req, rep)
                        }
                    },
                )

                console.log(
                    `[Lua]\x1b[33m Route ${this.alias}/${route} attached. \x1b[0m`,
                )
            }
        }
    }
}

export default AbstractActionController

我尝试使用 [key: string]: 任何类型,但是 this 没有索引🤔🤔也许是我不知道的东西。

javascript typescript express model-view-controller logic
1个回答
0
投票

您可以使用类型谓词来缩小操作函数的类型(类型谓词以前称为用户定义的类型防护)。

这是最简单的版本,会缩小你的功能:

function isActionFunction(fn: any): fn is (req: Request, res: Response) => void {
    return typeof fn === 'function';
}

这是代码的更新版本,显示了其在上下文中的用法:

import { Application, Request, Response } from 'express'

function isActionFunction(fn: any): fn is (req: Request, res: Response) => void {
    return typeof fn === 'function';
}

class AbstractActionController {
    public alias: string
    private app: Application

    constructor(alias: string, app: Application) {
        this.alias = alias === 'index' ? '' : alias
        this.app = app

        this.registerActionRoutes()
    }

    /**
     * registerActionRoutes
     *
     * Called to log the routes with Action indicator in a controller.
     */

    private registerActionRoutes() {
        const classMethods = Object.getOwnPropertyNames(
            Object.getPrototypeOf(this),
        ) as Array<keyof typeof this & string>;

        for (const methodName of classMethods) {
            if (methodName.endsWith('Action')) {
                let route = methodName.split('Action')[0]

                route = route === 'index' ? '' : route

                this.app.all(
                    `${this.alias}/${route}`,
                    (req: Request, rep: Response) => {
                        const fn = this[methodName];
                        if (isActionFunction(fn)) {
                            fn(req, rep)
                        }
                    },
                )

                console.log(
                    `[Lua]\x1b[33m Route ${this.alias}/${route} attached. \x1b[0m`,
                )
            }
        }
    }
}

export default AbstractActionController
© www.soinside.com 2019 - 2024. All rights reserved.