检查功能签名

And*_*ell 4 typescript

我正在研究服务定位器项目,我希望传递的函数需要一个参数.

这是一个片段:

"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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'ServiceDeclaration' has no compatible call signatures.
Run Code Online (Sandbox Code Playgroud)

我尝试创建一个新类型:

type ServiceFunction = (container: Pimple) => any;
Run Code Online (Sandbox Code Playgroud)

并尝试更改instanceof Functioninstanceof ServiceFunction但后来我收到以下错误:

error TS2693: 'ServiceFunction' only refers to a type, but is being used as a value here.
Run Code Online (Sandbox Code Playgroud)

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

Pal*_*leo 10

最简单的解决方案是使用变量并让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
    }
Run Code Online (Sandbox Code Playgroud)

作为替代方案,可以将条件包装在显式类型保护中:

function isFunction(f): f is Function {
    return f instanceof Function;
}
Run Code Online (Sandbox Code Playgroud)

小通知:类型Object | Function不优雅.您可以考虑使用更好的函数类型和/或更好的对象类型.


Huy*_*yen 5

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