我有一个带有字典的类,可以用管道函数填充字典,管道函数的形式如下:接受一个对象(字典),解构它的属性以用作参数,并返回一个具有新属性的对象(然后可以将新属性添加到字典中)。
是否有任何方法可以键入管道函数,以便只有先前添加的属性可以被反结构化?即:
type AugmentFun = (source: Record<string, any>) => Record<string, any>;
class Pipeable {
constructor(private dict: Record<string, any>) {}
static of = (dict: Record<string, any>) => new Pipeable(dict);
static augment = (source: Pipeable, fun: AugmentFun) => {
return Pipeable.of(Object.assign({}, source.dict, fun(source.dict)));
};
pipe = (...funs: AugmentFun[]) => funs.reduce(Pipeable.augment, this);
}
const p = new Pipeable({});
// This works & should not throw type errors
const res1 = p.pipe(
() => ({ a: 1, b: 2 }), // { a: 1, b: 2 }
({ a, b }) => ({ c: a + b }), // { a: 1, b: 2, c: 3}
({ c }) => ({ d: c ** 2 }) // { a: 1, b: 2, c: 3, d: 9}
);
// This should throw type errors but doesn't
const res2 = p.pipe(
() => ({ a: 1, b: 2 }), // { a: 1, b: 2 }
({ c }) => ({ d: c + 10 }) // Should be: "c" does not exist
);
(the augment()
方法是纯方法,但它也可以改变原始示例,这并不太重要)
1条答案
按热度按时间ntjbwcob1#
这是一个常见的问题;但遗憾的是,在TypeScript中对于未知数量的依赖函数的类型管道没有一流的支持。唯一的“* 非黑客 *”解决方案是使用重载。
这就要求我们拥有与我们想要支持的操作符数量相同的重载数量。由于缺乏替代方案,这种模式被用于RxJS中
.pipe
的类型化和其他库中的管道。Playground