带有 react-dnd 的 TypeScript 2.0 给出错误“JSX 元素属性可能不是联合类型”

Posted

技术标签:

【中文标题】带有 react-dnd 的 TypeScript 2.0 给出错误“JSX 元素属性可能不是联合类型”【英文标题】:TypeScript 2.0 with react-dnd gives error "JSX element attributes may not be a union type" 【发布时间】:2017-03-09 05:47:04 【问题描述】:

在 TypeScript + React 项目中,我使用的是 react-dnd 及其 DefinitelyTyped typings:

interface ExampleScreenProps  a, b, c 
interface ExampleScreenState  x, y, z 

class ExampleScreen extends React.Component<ExampleScreenProps, ExampleScreenState>  

export default DragDropContext(html5Backend)(ExampleScreen);

这会在另一个组件中呈现:

import ExampleScreen from "./ExampleScreen";

<ExampleScreen a="a" b="b" c="c" />

这在 TS 1.8 中有效,没有任何错误。当我升级到 TS 2.0 时,出现以下编译错误:

错误:(90, 10) TS2600: JSX 元素属性类型 '(ExampleScreenProps & children?: ReactNode; ) | (ExampleScreenProps & children...' 可能不是联合类型。

这是type definition for DragDropContext

export function DragDropContext<P>(
    backend: Backend
): <P>(componentClass: React.ComponentClass<P> | React.StatelessComponent<P>) => ContextComponentClass<P>;

我不能把它放在一起。抱怨的错误是什么?它似乎不喜欢ComponentClass&lt;P&gt; | StatelessComponent&lt;P&gt;的联合,但那些不是元素属性,元素属性只是&lt;P&gt;。我尝试明确传递&lt;P&gt;

export default DragDropContext<ExampleProps>(HTML5Backend)(ExampleScreen);

但同样的错误仍然存​​在。我可以通过断言输出来解决它:

export default DragDropContext(HTML5Backend)(ExampleScreen) as React.ComponentClass<ExampleProps>;

但我不喜欢使用断言,而且我不了解实际问题,或者我做错了什么。这是可以修复的打字问题吗?

【问题讨论】:

考虑到这一点,我猜这个错误可能是因为组件类的&lt;P&gt;有隐式props key, children, ref但是无状态组件没有所有这些props,所以结果是不一样。不过,我不明白为什么 TS 不能推断出类型是 ComponentClass 而不是 StatelessComponent 如果这与this 相同,那么显然它正在this PR 中解决。 【参考方案1】:

您可以使用以下方法安装新类型:

npm i @types/react-dnd --save-dev

如果您已经安装了其他类型,请使用以下方法将其删除:

typings uninstall --save --global react-dnd

之后它应该会按预期工作。

【讨论】:

【参考方案2】:

typescript 2.4.2 没有构建错误 并使用依赖项:

    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-dnd":"^2.4.0"

    "@types/react": "^16.0.5",
    "@types/react-dom": "^15.0.0",
    "@types/react-dnd":"^2.0.33",

【讨论】:

以上是关于带有 react-dnd 的 TypeScript 2.0 给出错误“JSX 元素属性可能不是联合类型”的主要内容,如果未能解决你的问题,请参考以下文章

react-dnd 中的动画

如何使用 react-dnd 从材质 UI 中拖放 TableHeaderColumn?

react-dnd 拖拽 九宫格

react-dnd 拖拽

如何实现 react-dnd useDragLayer?

如何将项目拖放到 react-dnd 中的空白部分?