首页 文章

TypeScript中是否可以使用强类型函数作为参数?

提问于
浏览
382

在TypeScript中,我可以将函数的参数声明为Function类型 . 是否存在一种“类型安全”的方式来解决这个问题?例如,考虑一下:

class Foo {
    save(callback: Function) : void {
        //Do the save
        var result : number = 42; //We get a number from the save operation
        //Can I at compile-time ensure the callback accepts a single parameter of type number somehow?
        callback(result);
    }
}

var foo = new Foo();
var callback = (result: string) : void => {
    alert(result);
}
foo.save(callback);

保存回调不是类型安全的,我给它一个回调函数,其中函数的参数是一个字符串,但我传递一个数字,并编译没有错误 . 我可以在保存类型安全功能时创建结果参数吗?

TL; DR版本:TypeScript中是否有等效的.NET委托?

4 回答

  • 564
    type FunctionName = (n: returnType) => any;
    
    class ClassName {
        save(callback: FunctionName) : void {
            callback(data);
        }
    }
    

    这肯定与函数式编程范例一致 .

  • 71

    当然:

    class Foo {
        save(callback: (n: number) => any) : void {
            callback(42);
        }
    }
    var foo = new Foo();
    
    var strCallback = (result: string) : void => {
        alert(result);
    }
    var numCallback = (result: number) : void => {
        alert(result.toString());
    }
    
    foo.save(strCallback); // not OK
    foo.save(numCallback); // OK
    

    如果需要,可以定义一个类型来封装它:

    type NumberCallback = (n: number) => any;
    
    class Foo {
        // Equivalent
        save(callback: NumberCallback) : void {
            callback(42);
        }
    }
    
  • 7

    我意识到这篇文章已经过时了,但是有一个更紧凑的方法,与所提出的方法略有不同,但可能是一个非常有用的选择 . 实际上,您可以在调用方法时在线声明函数(在本例中为 Foosave() ) . 它看起来像这样:

    class Foo {
        save(callback: (n: number) => any) : void {
            callback(42)
        }
    
        multipleCallbacks(firstCallback: (s: string) => void, secondCallback: (b: boolean) => boolean): void {
            firstCallback("hello world")
    
            let result: boolean = secondCallback(true)
            console.log("Resulting boolean: " + result)
        }
    }
    
    var foo = new Foo()
    
    // Single callback example.
    // Just like with @RyanCavanaugh's approach, ensure the parameter(s) and return
    // types match the declared types above in the `save()` method definition.
    foo.save((newNumber: number) => {
        console.log("Some number: " + newNumber)
    
        // This is optional, since "any" is the declared return type.
        return newNumber
    })
    
    // Multiple callbacks example.
    // Each call is on a separate line for clarity.
    // Note that `firstCallback()` has a void return type, while the second is boolean.
    foo.multipleCallbacks(
        (s: string) => {
             console.log("Some string: " + s)
        },
        (b: boolean) => {
            console.log("Some boolean: " + b)
            let result = b && false
    
            return result
        }
    )
    

    multipleCallback() 方法对于可能成功或失败的网络调用非常有用 . 再次假设一个网络调用示例,当调用 multipleCallbacks() 时,可以在一个位置定义成功和失败的行为,这有助于为将来的代码读取器提供更大的清晰度 .

    一般来说,根据我的经验,这种方法有助于使整体更简洁,更简洁,更清晰 .

    祝你好运!

  • 7

    以下是一些常见.NET委托的TypeScript等价物:

    interface Action<T>
    {
        (item: T): void;
    }
    
    interface Func<T,TResult>
    {
        (item: T): TResult;
    }
    

相关问题