如何根据函数参数创建界面

时间:2018-05-19 00:04:05

标签: typescript

我想通过函数参数动态创建一个具有动态指定键的接口实例

实际上我想做一些像这样简单的事情:

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来说是否可行?

1 个答案:

答案 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>'