基于第一个参数的功能参数动态类型

时间:2018-11-24 03:59:47

标签: function typescript visual-studio-code

现在,我有一个非常通用的功能,当我的客户端与服务器对话时,它会命中。因此,为了保持它的灵活性,我正在这样做:

public call(method: string, ...parameters: any[]) {}

在我的服务器上,我将所有方法保持在一起,例如:

MethodManager.methods({
    findOne: {
        function: function(collection: string, query: Object) {
            return model(collection).findOne(query).exec();
        }
    },
    find: {
        function: function(collection: string, query: Object, sortQuery: Object = {}) {
            return model(collection).find(query).sort(sortQuery).exec();
        }
    }
}

如您所见,每种方法可能具有不同的参数。当我在客户端上编写代码时,我无法充分利用Typescript的潜力,因为它是“ any”强制转换的。

我该如何做,以便Visual Studio代码在编写以下代码行时就可以识别出来:

this.socketManager.call('findOne', 

它会弹出一个这样的帮助列表:

(method: 'findOne', collection: string, query: Object)

但是当我键入:

this.socketManager.call('find',

它给了我

(method: 'find', collection: string, query: Object, sortQuery: Object = {})

而不是无益的:

(method: string, ...parameters: any[])

这可能吗?这将对发展产生巨大的帮助。

2 个答案:

答案 0 :(得分:0)

您可以使用Typescript中的函数重载来执行类似的操作:https://www.typescriptlang.org/docs/handbook/functions.html

这里是an example

function call(method: "find", collection: string, query: object): object;
function call(method: "findOne", collection: string, query: object, sortQuery: object): object[];
function call(method: "find" | "findOne", ...parameters: any[]): any {
    switch (method) {
        case "find": {
            const [collection, query] = parameters
            return {}
        }
        case "findOne": {
            const [collection, query, sortQuery] = parameters
            return [{}]
        }

    }
}

call("find", "collection", {})
call("findOne", "collection", {}, {})

call("find", "collection", {}, {}) // Error
call("findOne", "collection", {}) // Error

答案 1 :(得分:0)

我设法通过编写一个遍历所有方法文件的脚本来实现此目的,对它们进行解析并获取函数和参数。该脚本正在服务器代码的编译(增加更改)上运行,然后在客户端上重新创建生成的methods.ts文件,该文件在启动时加载。

export function SERVER_METHODS(socketManager) {
    return {
        findOne: (collection: string, query: Object, cb?: Function)  => {
            socketManager.call('findOne', collection, query, cb);
        },
        find: (collection: string, query: Object, sortQuery: Object = {}, cb?: Function)  => {
            socketManager.call('find', collection, query, sortQuery, cb);
        },
        ...
    };
}

然后我像这样使用它:

public methods = SERVER_METHODS(this);

现在不要这样做:

this.socketManager.call('findOne', ...)

我正在这样做:

this.socketManager.methods.findOne(

这给了我该函数的参数。完全手动的解决方案,但是它可以工作,并且现在可以自动化。