我正在尝试编写一个函数,该函数需要一个值并将其包装在具有单个属性的对象中,该属性的名称以字符串形式提供。所以像
let wrapped = wrap(1, 'a'); // wrapped: { a: number }
到目前为止,我最近的是
function wrap<T, P extends keyof T, V extends T[P]>(value: V, prop: keyof T): T;
let wrapped = wrap(1, 'a'); // wrapped: { a: any }
它将类型参数推断为<{ a: any; }, "a", number>
我想要这样做的原因是因为我们需要在代码中组合很多对象,并且许多帮助函数仅返回值,但是我们需要将值作为对象的属性来组合它。我们不能仅仅使用常规的内联对象创建语法,因为这些函数都是异步的,我希望能够做类似的事情
combine(
largeStateFunction(), // Observable<LargeState>
wrap(singleValueFunction(), "oneMoreThing") // Observable<number>
).subscribe(state => // state: LargeState & { oneMoreThing: number }
{
// do work
});
这是否有可能不需要为wrap
提供类型参数?
答案 0 :(得分:0)
相当基本的东西:
function wrap<V, K extends string>(v: V, k: K): {[K2 in K]: V} {
return {[k]: v} as {[K2 in K]: V}
}
let wrapped = wrap(1, 'a'); // {a: number}
P.S。您原始的代码有一个缺陷:您尝试同时限制返回类型和推断返回类型,这通常会使TS陷入困境或产生any
。