在打字稿中注释高阶函数

问题描述 投票:0回答:1

我正在使用相当大的JS代码库,试图将其迁移到打字稿,并且遇到了注释特定的高阶函数的问题...

doStuff()接受fn1作为参数并包装它,返回一个新函数,该函数接受fn1的参数中除第一个参数之外的所有参数。有点像这样:

const fn1 = (arg_1, arg_2, arg_3, arg_n) => { return 'Hello World' }

const doStuff = (fn) => (...args) => {
    argument1 = getSomeStuffHere()
    return fn(argument1, ...args)
}

const test = doStuff(fn1)
let result = test('arg2', 'arg3', 'arg4')

值得指出的是,有一个doStuff()和很多fnX()函数,其中包含许多不同类型组合的自变量。正确键入doStuff创建的函数很重要,“ any => any”将不起作用!

经过一番混乱之后,我终于想到了:

// just for testing simplified example
type MagicObj = {}
const myMagicObject = {}

type Wrapped<T, R> =
    T extends [MagicObj, any, any, any, any] ? (a: T[1], b: T[2], c: T[3], d: T[4]) => R :
    T extends [MagicObj, any, any, any] ? (a: T[1], b: T[2], c: T[3]) => R :
    T extends [MagicObj, any, any] ? (a: T[1], b: T[2]) => R :
    T extends [MagicObj, any] ? (a: T[1]) => R :
    T extends [MagicObj] ? () => R :
    unknown;

const doStuff = <T extends any[], R>(fn: (...args: T) => R): Wrapped<T, R> => (...args) => fn(myMagicObject, ...args)

// testing examples
const fn1 = (obj: MagicObj, p1: string, p2: boolean, p3: number): string => { return 'Hello World' }
const fn2 = (obj: MagicObj, p1: number, p2: string) => { return 'Hello Mars' }
const fn3 = (obj: MagicObj, p1: boolean) => { return 'Hello The Moon' }

const test1 = doStuff(fn1)
// const test1: (a: string, b: boolean, c: number) => string 
let result1 = test1('str', true, 123) 

const test2 = doStuff(fn2)
// const test2: (a: number, b: string) => string
let result2 = test2(123, 'str')

const test3 = doStuff(fn3)
// const test3: (a: boolean) => string
let result3 = test3(true)

这似乎是一种工作。 VSCodes类型提示智能感知巫术在示例底部显示了我对test1、2、3和结果变量的期望/期望,但是无论如何尝试由doStuff (...args) => fn(myMagicObject, ...args)返回的函数,报告错误Type '(...args: any[]) => any' is not assignable to type 'Wrapped<T, R>'.ts(2322)

任何想法如何做到这一点?

typescript higher-order-functions
1个回答
0
投票

如果我了解您要执行的操作,请改为输入doStuff()

const doStuff = <T extends any[], R>(
  fn: (magicObject: MagicObj, ...args: T) => R
): ((...args: T) => R) => (...args) => fn(myMagicObject, ...args);

这表示从第一个参数为MagicObj类型的任何函数到相同类型但已删除MagicObj参数的另一个函数的转换。通过使用rest tuples,它应适用于任意数量的参数。

对您有用吗?好的,希望对您有所帮助。祝你好运!

Link to code

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.