如何从函数参数继承缩小类型?
How to inherit narrowed type from function argument?
我有一个函数接受另一个函数作为参数。参数是联合类型的函数,也可能有或没有参数。
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 和打字稿中的一切都是对象。因此 {}
不能用作约束。为此,最好使用 Record<string, unknown>
。
Parameters
- returns 传递函数的所有参数的元组。
P.S。我希望你不介意我使用了箭头函数而不是 function
。不是说更好,只是风格的问题
我有一个函数接受另一个函数作为参数。参数是联合类型的函数,也可能有或没有参数。
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 和打字稿中的一切都是对象。因此 {}
不能用作约束。为此,最好使用 Record<string, unknown>
。
Parameters
- returns 传递函数的所有参数的元组。
P.S。我希望你不介意我使用了箭头函数而不是 function
。不是说更好,只是风格的问题