我想通过函数参数动态创建一个具有动态指定键的接口实例
实际上我想做一些像这样简单的事情:
function callWith(key, value) {
return fnWithKeyValue =>
fnWithKeyValue({ [key]: value });
}
(我特别想要的是具有设置动态属性的React HOC,但我已尝试简化上述内容)
例如,假设我有一些功能或多或少超出了我的控制范围:
interface ValueType {
magicValue: number;
}
function MyCallback(v: ValueType) {
}
所以我想要成功编译:
callWith('magicValue', 123)(MyCallback);
但我希望这不能编译:
callWith('normalValue', 123)(MyCallback);
这对TypeScript来说是否可行?
答案 0 :(得分:1)
这样的事情怎么样:
function callWith<K extends string, V>(key: K, value: V): <R>(f: (a: Record<K, V>) => R) => R {
return fnWithKeyValue =>
fnWithKeyValue({ [key]: value } as Record<K, V>); // Note the cast here, I don't know of a way to avoid it.
}
这有点棘手,因为我们有一个泛型函数callWith
,它返回另一个泛型函数。但它所说的是,作为callWith
返回的函数的参数提供的函数必须接受正确类型的对象作为其参数,特别是Record<K, V>
。
但是,尽管签名很复杂,但它确实符合您的要求。第一个示例将编译没有问题,但第二个示例将创建一个错误,因为MyCallback
接受了"magicValue"
而不是"normalValue"
的对象:
interface ValueType {
magicValue: number;
}
function MyCallback(v: ValueType) {}
callWith('magicValue', 123)(MyCallback); // OK
callWith('normalValue', 123)(MyCallback); // Error: Property 'magicValue' is missing in type 'Record<"normalValue", number>'