如何从函数参数继承窄类型?



我有一个接受另一个函数作为参数的函数。实参是函数的联合类型,也可以有实参,也可以没有实参。

type innerFn = () => void | (arg: string) => void | (arg: number) => void | (arg: {}) => void
function mainFn (innerFn: InnerFnType) {
function run(arg?: *any*) {
innerFn()
}
return run
}

我想知道是否运行参数可以根据传递给mainFn的函数来继承。

用例是:

const concreteInnerFn: InnerFnType = (arg: string) {
do something
}
const run = mainFn(concreteInnerFn)
run("hello")  // OK
run(25) // ERROR
run({hello: true}) // ERROR

例如,如果我使用(arg: string) => void作为innerFn,当我尝试使用run()时,它应该要求字符串类型的参数。

希望够清楚

你可以这样做:

type InnerFn =
| (() => void)
| ((arg: string) => void)
| ((arg: number) => void)
| ((arg: Record<string, unknown>) => void)
const main = <
Params extends Parameters<InnerFn>,
>(fn: (...params: Params) => void) =>
(...args: Params) => fn(...args)
/**
* Ok
*/
const result0 = main(() => { }) // ok
result0() // ok
const result1 = main((a: string) => { })// ok
result1('hello') // ok
const result2 = main((a: number) => { }) // ok
result2(42) // ok
const result3 = main((a: { age: number }) => { }) // ok
result3({ age: 42 })
/**
* Errors
*/
const result4 = main((a: Promise<number>) => { }) // expected error
const result5 = main((a: number[]) => { }) // expected error

游乐场

请不要使用{}作为类型,因为它是非常通用的类型。在javascript和typescript中,一切都是对象。因此,{}不能作为约束。对于这种目的,最好使用Record<string, unknown>

Parameters-返回传递函数的所有参数的元组。

注:我希望你不介意我用箭头函数代替function。我不是说它更好,这只是一个风格的问题。

最新更新