检查功能签名

时间:2017-02-27 13:48:48

标签: typescript

我正在开发一个服务定位器项目,我希望传递的函数需要一个参数。

这是一个片段:

http://sivakumar/ReportServer

但是,当我尝试编译时,我收到以下错误:

"use strict";

/** Declaration types */
type ServiceDeclaration = Function|Object;

export default class Pimple {

    /**
     * @type {{}}
     * @private
     */
    _definitions: {[key: string]: ServiceDeclaration} = {};

    /**
     * Get a service instance
     * @param {string} name
     * @return {*}
     */
    get(name: string): any {
        if (this._definitions[name] instanceof Function) {
            return this._definitions[name](this);
        }
        return this._definitions[name];
    }
}

我尝试创建一个新类型:

error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'ServiceDeclaration' has no compatible call signatures.

并尝试将type ServiceFunction = (container: Pimple) => any; 更改为instanceof Function,但之后出现以下错误:

instanceof ServiceFunction

我环顾四周,但未能找到任何检查传入函数是否与指定签名匹配的示例。

2 个答案:

答案 0 :(得分:8)

最简单的解决方案是使用变量并让TypeScript推断其类型:

    get(name: string): any {
        let f = this._definitions[name]; // here, 'f' is of type Function|Object
        if (f instanceof Function)
            return f(this);              // here, 'f' is of type Function
        return f;                        // here, 'f' is of type Object
    }

作为替代方案,可以将条件包装在显式type guard

function isFunction(f): f is Function {
    return f instanceof Function;
}

小通知:类型Object | Function不优雅。您可以考虑使用更好的function type和/或更好的object type

答案 1 :(得分:3)

这是一个比Paleo更简单的解决方案。您可以使用instanceof Function,而不是使用typeof f === 'function'。点击here,查看我在TypeScript操场上创建的示例。如果您将鼠标悬停在两个input分支中的if变量上,则会看到您想要的结果。