我正在尝试使打字稿打字与一种模式一起工作,其中有一个函数对象和一个函数,该函数在对象中call(name, arg)
查找函数并使用.name
arg
假设我有一个将名称映射到函数的对象:
interface Registry {
str2numb: (p: string) => number
num2bool: (p: number) => boolean
}
const REGISTRY: Registry = {
str2numb: p => parseInt(p, 10),
num2bool: p => !!p,
}
我还有一个函数call(name, p)
,它从 中解析函数REGISTRY
并用p
. 现在,我想输入函数,如果提供了无效参数,它会抱怨:
const call = (name, p) => REGISTRY[name](p)
call('str2numb', 123)
// ^^^ Would like to see an error here
如何从 的类型中解析P
参数的类型p
(以及返回类型R
)Registry.str2numb
?甚至可能吗?
// How can I resolve P and R here?
// The resolved function is Registry[N]
// I have tried Registry[N]<P, R> but that doesn't work :-(
const call = <N extends keyof Registry>(name: N, p: P): R => REGISTRY[name](p)
我已经做到了这一点,但它不起作用:
type Fn<P, R> = (p: P) => R
const call =
<N extends keyof Funcs, F extends Funcs[N] & Fn<P, R>, P, R>
(name: N, p: P): R =>
REGISTRY[name](p)
call('str2numb', 123)
// ^^^ No error here
但是,这有效:
// This just returns the resolved function
const call1 = <N extends keyof Funcs>(name: N) => REGISTRY[name]
// The type of the returned function is correctly inferred from the name
call1('str2numb')(123)
// ^^^ Argument of type '123' is not assignable to parameter of type 'string'