为TypeScript HOF键入签名

时间:2014-02-06 22:41:03

标签: javascript typescript

以下JavaScript函数为给定函数添加了before和after建议。我正在尝试为此函数添加TypeScript类型签名。

function wrap(fn, before, after) {
    var id = function(x) { return x };
    before = before || id;
    after = after || id;

    return function() {
        var args = Array.prototype.slice.call(arguments);
        var modifiedArgs;

        try {
            modifiedArgs = before.apply(this, args);
        } catch (e) {
            console.log(e);
        }

        var result = undefined;
        try {
            result = fn.apply(this, modifiedArgs || args);
        } finally {
            try {
                after.apply(this, args);
            } catch (e) {
                console.log(e);
            }
        }

        return result;
    }
}

我能提出的类型是:

  • fn的类型为Function
  • after的类型为(_:any[]) => any[]
  • 返回类型为Function

before的类型应该是什么?它需要any[]并返回voidany[]。此外,是否可以编码返回类型与fn具有相同类型签名的事实?

2 个答案:

答案 0 :(得分:0)

之前可能是(_:any[]) => any[]

如果要在函数签名中对返回类型进行编码,请执行以下操作:

function wrap(fn, before, after) : Function {  ...function... }

答案 1 :(得分:0)

我最后把它写成:

module Foo {
    export interface Wrappable extends Function {
        (...rest) : any;
    }

    export function wrap<U extends Wrappable>(fn: U, 
                                              before: (...args) => any[], 
                                              after: (...args) => void): U {
        var id = function(x) { return x };
        before = before || id;
        after = after || id;

        return <U> function() {
            var args = Array.prototype.slice.call(arguments);
            var modifiedArgs;

            try {
                modifiedArgs = before.apply(this, args);
            } catch (e) {
                console.log(e);
            }

            var result = undefined;
            try {
                result = fn.apply(this, modifiedArgs || args);
            } finally {
                try {
                    after.apply(this, args);
                } catch (e) {
                    console.log(e);
                }
            }

            return result;
        }
    }
}

var orig = function(s: string): void {
    console.log("Hello!");
};

var before = function (s: string): any[] {
    console.log("before calling orig(" + s + ")");
    return [s];
};

var after = function (s: string): void {
    console.log("after calling orig(" + s + ")");
};

var f = Foo.wrap(orig, before, after);
f("1");
// f(); // ERROR
// f(1); // ERROR
// f("1", "1"); // ERROR

请注意,Foo.wrap的返回值是与第一个参数相同类型的函数,这是TS类型推断的令人印象深刻的壮举!