【发布时间】:2021-01-03 14:16:27
【问题描述】:
我正在开发一个开源 JS 框架,我想将 JSX 与 typescript 一起用于它的组件。但我对 JSX 的类型定义有疑问
TS 预期:
<Header title="Hello World" />
成为(对于任何类似反应的框架):
function Header(props: { title: string }) : JSXElement
虽然在此框架中,实际类型基于 Observables (RxJS):
function Header(props: Observable<{ title: string }>) : JSXElement | Observable<JSXElement>
例如一个简单的h1 标头组件:
function Header(props$) { // take in a stream of updates
return props$.pipe( // return a stream of JSX updates
map(props => <h1>{ props.title }</h1>)
);
}
因此,组件接收一个 Observable 属性并返回一个静态 JSX 元素或 JSX 元素流。
UPD 澄清: 框架已经按照我描述的那样工作,打字是问题。 Observables 在引擎 runtime 中处理,而不是在转换阶段,因此 JSX 转换为 createElement 就可以了。我只需要调整 TSX 的类型,例如:
// current:
createElement<P>(fn : (props: P) => JSXElement, props: P, ...children: JSXElement[])
// should be:
createElement<P>(fn : (props: Observable<P>) => JSXElement, props: P, ...children: JSXElement[])
我看到可以部分自定义JSX,但我还没有找到一种方法来覆盖它。我试图覆盖 JSX.Element 和 JSX.ElementType ,而对打字结果没有任何明显的变化。
甚至可以进行这种覆盖吗?
我应该覆盖哪些类型/接口?
谢谢!
~~我没有链接repo不要被怀疑在广告中~~
UPD:有关详细信息,您可以在此处找到框架:http://recks.gitbook.io/
【问题讨论】:
-
我几乎可以肯定,您不会在组件内收到您的 Observable。它将在 React.createElement 中丢失。我看到传递 Observable 的唯一方法是作为值。单个道具或通过上下文。
-
嘿,@Thomas!这是一个自定义框架,它提供了自己的
createElement和处理 Observables(进出)的引擎。所以它已经像我上面描述的那样工作了,我只想添加适当的类型来改善开发体验 -
@arslan2012,afaik,JSX 是 TS 中的一种特殊子语法,TSC 完全有能力进行转换。此外,
createElement(fn, props, ...children)转换对我来说很好,可观察部分在引擎中处理——所以我不需要自定义转换——只需输入。基本上我需要告诉 TScreateElement<P>(fn : (props: P) => any, props: P, ...children: any[])现在是createElement<P>(fn : (props: Observable<P>) => any, props: P, ...children: any[])。抱歉没有说清楚,会更新 Q 以更好地反映这一点。
标签: javascript typescript rxjs jsx typescript-typings