我正在try 输入一个更高阶的函数.其基本思想是向HIGH传递一个函数FN,它返回一个接受完全相同的参数并提供相同返回类型的函数.

这是一种try 更好地理解这种语言的练习.我有一些东西可以工作,但会从输入参数中删除类型.请参见下面的类型Test1和Test2:

export function high<R>(fn: (...args: any[]) => R) {
  return (...args: any[]) => {
    const moddedArgs = args.map((el) =>
      typeof el === "string" ? el + "OMG" : el
    );

    return fn(...moddedArgs);
  };
}

const test1 = (nr1: number, str1?: string) => (str1 ?? "Wow").repeat(nr1);

test1(3, "yo");
// returns yoyoyo

test1(3);
// returns WowWowWow

const test2 = high(test1);

test2(3, "yo");
// returns yoOMGyoOMGyoOMG

type Test1 = typeof test1;
// type Test1 = (nr1: number, str1?: string) => string

type Test2 = typeof test2;
// type Test2 = (...args: any[]) => string

Playground Link

我try 对参数使用P型实参,但它并不能很好地处理可选参数.

有什么办法可以解决这个问题吗?

推荐答案

与其try 分别猜测fn个函数参数和返回类型的泛型,我们可以为整个函数使用一个泛型类型F,然后用ParametersReturnType个内置的TypeScrip实用程序类型提取其组成类型:

export function high<F extends (...args: any[]) => any>(fn: F) {
  return (...args: Parameters<F>): ReturnType<F> => {
    const moddedArgs = args.map((el) =>
      typeof el === "string" ? el + "OMG" : el
    );

    return fn(...moddedArgs);
  };
}

const test2 = high(test1);
//    ^? (nr1: number, str1?: string | undefined) => string

我们甚至可以更进一步,以防它在您的情况下可能有意义:通过断言修改后的函数具有与原始函数(上面的类型F)相同的exactly类型,我们也获得了它关联的JSDoc!

function high2<F extends (...args: any[]) => any>(fn: F) {
  return high(fn) as F // If we assert the returned function type as exactly F, we get its associated JSDoc as well!
}

const test22 = high2(test1);
//    ^? (nr1: number, str1?: string) => string
// In the IDE, we should have any JSDoc associated to test1, popup as well on test22, since it is said to be exactly the same type.

Playground Link

Typescript相关问答推荐

如何使用Generics保留构造函数的类型信息?

为什么缩小封闭内部不适用于属性对象,但适用于声明的变量?

react 路由6操作未订阅从react 挂钩表单提交+也不使用RTK查询Mutations

Select 下拉菜单的占位符不起作用

类型TTextKey不能用于索引类型 ;TOption

类型脚本可以推断哪个类型作为参数传递到联合类型中吗?

通过泛型函数本身推断受约束的泛型参数的类型脚本问题

使用TypeScrip5强制使用方法参数类型的实验方法修饰符

是否有可能避免此泛型函数体中的类型断言?

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

有没有办法传递泛型类型数组,以便推断每个元素的泛型类型?

Rxjs将省略的可观测对象合并到一个数组中

为什么类型脚本使用接口来声明函数?他的目的是什么.

为什么`map()`返回类型不能维护与输入相同数量的值?

Select 类型的子项

T的typeof键的Typescript定义

Svelte+EsBuild+Deno-未捕获类型错误:无法读取未定义的属性(读取';$$';)

如何在由函数参数推断的记录类型中具有多个对象字段类型

如何按成员资格排除或 Select 元组?

const nav: typechecking = useNavigation() 和 const nav = useNavigation() 之间有什么区别?