关于为特殊组件定义正确键入 JSX 的问题

问题描述

我正在开发一个实验性的 Web 组件库。 组件基本上都是类型

type Component<Props> = {
  new(): Props,init(props: Props): ...
}

并实现如下

// a bit simplified
@component('my-component')
class MyComponent {
  @prop()
  someProp = 0

  static init(props: MyComponent) {
    ...
  }
}

现在我想为此使用 JSX。在现实世界中,事情有点复杂,但在这里假设所有组件 props 在 JSX 中都是可选的。

// a bit simplified
function createElement<Props>(type: Component<Props>,props?: Partial<Props> | null,...) {
  ...
}

现在 createElement(MyComponent) 工作正常,但 <MyComponent/> 会导致编译错误

“类型 '{ }' 不能分配给类型 'IntrinsicAttributes & MyComponent'。属性 'someProp' 在类型 '{ }' 中缺失,但在类型 'MyComponent' 中是必需的。ts(2322)”

我该如何在全局 JSX 类型或其他地方解决这个问题? MTIA

[编辑 - 添加演示]:请在此处找到一个简化的演示(=> 参见 index.tsx 的第 39 行中的编译错误 - 我猜问题出在 jsx.d.ts 中):https://codesandbox.io/s/naughty-platform-8x3q5?file=/src/index.tsx

PS:顺便说一句,只是将 someProp = 0 更改为 someProp? = 0 并不是一个有用的解决方案。

解决方法

我想,我在这里尝试做的事情目前在 JSX 中是不可能的(至少在没有额外的函数调用的情况下是不可能的,例如 export default convert(MyComponent))。

在 JSX 命名空间中,您可以配置 interface ElementClassinterface ElementAttributesProperty 来告诉 JSX 如何检索类组件的具体 props 类型。这对于我的演示来说太有限了。

在我的演示中,组件 props 类型的检索比通过 ElementAttributesProperty 进行配置更复杂,恕我直言。

如果我对这个假设有误,或者您有其他意见或建议,请告诉我。

,

你的 JSX pragma 应该是这样的:

/** @jsx createElement */

const appendChild = (parent,child) => {
  if (Array.isArray(child))
    child.forEach(nestedChild => appendChild(parent,nestedChild))
  else
    parent.appendChild(
      child.nodeType ? child : document.createTextNode(child)
    )
}

export const createElement = (tag,props,...children) => {
  const element = document.createElement(tag)

  Object.entries(props || {}).forEach(([name,value]) => {
    if (name.startsWith('on') && name.toLowerCase() in window)
      element.addEventListener(name.toLowerCase().substr(2),value)
    else
      element.setAttribute(name,value.toString())
  })

  children.forEach(child => {
    appendChild(element,child)
  })

  return element
}


document.getElementById('root').appendChild(
  <div>Hello</div>
)

? 检查这个demo

我不知道你的虚拟 dom 我不能说它有什么问题。

? 我的建议:

  1. 先尝试让它在没有虚拟 dom 的情况下工作
  2. 不要忘记将其附加到文档中
  3. 在处理 props 之前,请确保它们不为 null 或 undefined。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...