Type inference for functions passed to generic function wrappers like _.debounce
在TypeScript中,如果将函数表达式作为参数传递,则可以完美地推断出其参数的类型:
1 2 3 4 5 6 | var foo = (fn: (a: string) => void) => {}; foo(a => { // a is inferred to be a string alert(a.toLowerCase()); }); |
对于事件处理程序和其他回调而言,这确实很方便。 但是,如果函数表达式包装在通用包装函数的调用中,则该通用包装函数将函数作为参数并返回具有相同签名的函数(返回值除外),例如 Lodash的
1 2 3 4 5 6 7 8 9 | var debounce = < T >(fn: (a: T) => void) => { return (a: T) => { /* ... */ }; }; foo(debounce(a => { // a is inferred to be {} // type error: 'toLowerCase' doesn't exist on '{}' alert(a.toLowerCase()); })); |
TS游乐场
由于
我想念什么吗? 是否应该以其他方式编写
UPDATE-2017:现在可以使用! TS 2.5。
首先,当您调用不带类型参数的泛型函数时,编译器必须找出每个类型参数的类型。
因此,当您调用
因此,编译器认为它没有任何类型可以使用,对于
整个过程称为类型参数推断。
然后发生的是,编译器会注意到您没有为箭头函数的参数指定类型。它认为可以从
因此,尽管这并非绝对出色,但修复的确不是那么糟糕。只需为
1 2 3 4 | foo(debounce((a: string) => { // Everything is fine! alert(a.toLowerCase()); })); |
或使用类型参数:
1 2 3 4 | foo(debounce<string>(a => { // Everything is fine! alert(a.toLowerCase()); })); |