Are strongly-typed functions as parameters possible in TypeScript?
在typescript中,我可以将函数的参数声明为类型函数。有没有一种"类型安全"的方法可以做到这一点?例如,考虑一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); |
save回调不是类型安全的,我给它一个回调函数,其中函数的参数是字符串,但我给它传递一个数字,并且编译时不会出错。我可以使结果参数保存类型安全函数吗?
tl;dr版本:在typescript中是否有等效的.NET委托?
当然:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
如果需要,可以定义一个类型来封装:
1 2 3 4 5 6 7 8 | type NumberCallback = (n: number) => any; class Foo { // Equivalent save(callback: NumberCallback) : void { callback(42); } } |
以下是一些常见的.NET委托的类型脚本等价物:
1 2 3 4 5 6 7 8 9 | interface Action<T> { (item: T): void; } interface Func<T,TResult> { (item: T): TResult; } |
我意识到这篇文章已经过时了,但是有一种更紧凑的方法,它与所要求的稍有不同,但可能是一个非常有用的选择。在调用方法(本例中为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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 } ) |
总的来说,根据我的经验,这种方法使自己更简洁,更少混乱,总体上更清晰。
祝大家好运!
1 2 3 4 5 6 7 | type FunctionName = (n: inputType) => any; class ClassName { save(callback: FunctionName) : void { callback(data); } } |
这肯定符合函数式编程范式。