javascript - 是否可以在 TypeScript 中使用可以根据输入/输出类型链接的通用装饰器?
问题描述
对于我们的一些集成,我们在代码库中有相当“模板化”的实现,可以方便地放入“管道和过滤器”模式恕我直言。
可以使“组件”看起来像以下类型:
class Component1<In, Out, Xin, Xout>
class Component2<Xin, Xout, Yin, Yout>
class Component3<Yin, Yout> // only has 2 params but could be <Yin, Yout, None, None> for a custom 'None' type
这个想法是有一些东西允许这些被“链接”以允许这样的事情:
const c1 = new Component1<A,B,C,D>(...) //perhaps pass the param types in constructor? Other options?
const c2 = new Component2<C,D,E,F>(...)
const c3 = new Component3<E,F, None, None>(...)
const chain = c1.andThen(c2).andThen(c3) // The "last" item in the chain would "always" be a component of type <X,Y, None, None>
chain.run() // Not sure if this is needed but to make it clear that something "runs" this chain
我想不出任何创建这些组件的“通用”方法,其中可以在编译时“定义”这种链接,以限制哪些组件可以与其他组件连接(即,输入/输出类型应该匹配)。因此c1
只能跟在后面,c2
但不能跟在后面,但后面不能跟c3
任何东西c3
。
这甚至可能吗?有什么能让它足够接近吗?
(对于好奇的人:试图实现 Finagle 在 Scala 世界中提供的类似“可组合性”)
解决方案
这是我所拥有的:
class Component<T, U> {
constructor(private t: T, private u: U) {}
andThen<V>(component: Component<U, V>): Component<U, V> {
// implement andThen
return component;
}
static run<T>(component: Component<T, null>) {
// implement run
}
}
type A = 'a'; const a: A = 'a';
type B = 'b'; const b: B = 'b';
type C = 'c'; const c: C = 'c';
const c1 = new Component<A, B>(a, b);
const c2 = new Component<B, C>(b, c);
const c3 = new Component<C, null>(c, null);
c2.andThen(c1); // TS2345: A is not assignable to B
Component.run(c1.andThen(c2)); // TS2345: Component<B,C> not assignable to Component<B,null>
Component.run(c1.andThen(c2).andThen(c3));
我已经简化了代码:<Xin, Xout, Yin, Yout>
→<T,U>
但这很容易适应。
链按预期键入。在运行时,Component<...,X>.andThen(Component<Y,...>)
被检测为无效(第一个TS2345
)。
Component
稍微重构一下,调用.run
的不是链本身(即.run
,Component<..., null>
)。
相反,我把它run
作为一个静态方法,Component
它只将最后一个组件作为输入。用法在最后两行演示
最后但同样重要的是,该类一直保持非常通用和多态,因此可以链接许多组件!
(new Component<'a', 'b'>('a', 'b'))
.andThen(new Component<'b', 'c'>('b', 'c'))
.andThen(new Component<'c', 'd'>('c', 'd'))
.andThen(new Component<'d', 'e'>('d', 'e'))
.andThen(new Component<'e', 'f'>('e', 'f'))
.andThen(new Component<'f', 'g'>('f', 'g'))
我希望这就是你要找的。
推荐阅读
- javascript - Javascript 总是只使用 if 语句中定义的第一个变量
- r - FELM weights argument broken in R?
- arrays - Home work problem that I cant visualize to understand Python Numpy (Newbie)
- django - Django-filter 字段名称是一个 python 内置关键字
- arrays - 如何在 Flutter 中解析这个 JSON 数组?
- python - 使用变量时的Python SQLite3绑定错误
- rust - 在运行时查找结构的总大小
- python - 如何用另一个数据框中的值替换数据框中的缺失值?
- python - 返回 postgres 查询时 Psycopg2 无效的 json
- ubuntu - 是否可以仅在命令行上启动 Ubuntu 时运行 JavaFX?