考虑以下代码:
interface Foo<T1> {
foo: string;
baz: T1;
}
function toFoo<T2>(value: T2): Foo<T2> {
return {
foo: 'bar',
baz: value
};
}
// Actually this function is imported from an NPM package so I can't change it
// The example is given for a better illustration
function memoize<T3, T4>(func: (arg: T3) => T4): (arg: T3) => T4 {
// Some implementation...
return func;
}
const memoizedToFoo: {<T5>(value: T5): Foo<T5>} = // ???
toFoo
函数是一个通用函数。我需要制作一个通用的 toFoo
的内存版本。我无法更改 memoize
类型和实现。如何实现 memoizedToFoo
以便它与给定的接口(interface)匹配?
我尝试了这个,但它不起作用:
const memoizedToFoo<T5> = memoize(toFoo<T5>); // unexpected <T5>
最佳答案
你能改变你的memorize()
函数吗?工作太辛苦了。
以下内容将自动推断出正确的类型:
interface Foo<T1> {
foo: string;
baz: T1;
}
function toFoo<T2>(value: T2): Foo<T2> {
return {
foo: 'bar',
baz: value
};
}
function memoize<F extends Function>(func: F): F {
// Some implementation...
return func;
}
const memoizedToFoo = memoize(toFoo)
更新:由于您无法更改 memorize()
,因此您可以很好地覆盖它,如下所示:
// memorize.ts
import { memoize as origMemoize } from 'memoize'
// or if it is commonJS
import origMemoize from 'memoize'
export const memoize = origMemoize as <F extends Function>(func: F) => F
然后你就可以像原来一样使用它:
import { memoize } from './memoize'
// code away
请注意,此解决方案确实会牺牲一些类型安全性,因为 F
不限于 (arg: X) => Y
为了正确解决这个问题,我们需要: https://github.com/Microsoft/TypeScript/pull/22368
关于typescript - 如何生成通用函数值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54510404/