我想要得到什么?
我想创建函数wrap()
,它做以下事情:
const fn = (x: string) => 'some string';
interface CustomObject {
id: number;
title: string;
}
const wrapped = wrap<CustomObject>(fn);
// typeof wrapped must be: (x: string) => CustomObject
我试了什么?
我试着这样做,但有两个问题。
第一个问题这段代码不能正常工作,因为如果你开始指定第一个泛型参数,你必须还要指定所有其他非"with-default"泛型参数:
function wrap <Schema, Args extends any[]> (fn: (...args: Args) => any) {
return (...args: Args): Schema => fn(...args);
}
const myFunction = (bar: string) => 'some string';
const myFunctionWrapper = wrap<{ id: number }>(myFunction);
// -----------------------------------------^: Expected 2 type arguments, but got 1.
第二个问题
如果我为第二个泛型参数设置默认类型,我将丢失fn
参数的类型:
function wrap <Schema, Args extends any[] = any[]> (fn: (...args: Args) => any) {
return (...args: Args): Schema => fn(...args);
}
const myFunction = (bar: string) => 'some string';
const myFunctionWrapper = wrap<{ id: number }>(myFunction);
// typeof myFunctionWrapper: (...args: any[]) => { id: number } not (bar: string) => { id: number }
<标题>问题。- 我做错了什么?
- 这在TypeScript中可能吗?
听起来您正在寻找部分类型推断。唉,这在TS中是不可用的。
典型的解决方法是使用辅助函数对通用参数进行curry,该函数为每种Schema
类型生成一个wrap
函数:
function wrapper<Schema>()
{
return <Args extends any[]>
(fn: (...args: Args) => any) =>
wrap<Schema, Args>(fn);
}
function wrap<Schema, Args extends any[]> (fn: (...args: Args) => any)
: (...args: Args) => Schema
{
/* magic goes here */
}
const fn = (x: string) => 'some string';
const wrapped = wrapper<CustomObject>()(fn);
// wrapped is (x: string) => CustomObject
TS操场
当然,您可以存储和重用中间包装器函数:
const wrapAsFoo = wrapper<Foo>();
const foo1 = wrapAsFoo((input: string) => 1);
// foo1 is (input: string) => Foo
const foo2 = wrapAsFoo((input: number) => {});
// foo2 is (input: number) => Foo