【发布时间】:2022-01-10 16:39:47
【问题描述】:
React 在一个名为 global.d.ts 的文件中定义了一些(不是全部)DOM 类型,这会导致问题。在 React 项目中使用 EventListener 类型(来自 TypeScript 库 dom)时似乎存在冲突,因为大多数其他类型都是由 React 声明的。
有没有办法在 React 项目中使用 EventListener 类型?我正在使用 next.js,所以在 tsconfig.json 中使用 exclude 丢弃 global.d.ts 文件以使 SSR 工作可能不是一个好主意?
预期内容(纯 TS):
https://codesandbox.io/s/nice-tdd-xnkov?file=/src/index.ts
window.onload = () => {
// NO Problem: Listener is correct.
// Explanation:
// EventListener is coming from typescript (lib.dom.d.ts)
// MouseEvent is coming from typescript (lib.dom.d.ts)
const listener: EventListener = (ev: MouseEvent) => {
console.log("Click!");
};
document.body.addEventListener("click", listener);
};
在 React 中不起作用:
https://codesandbox.io/s/react-dom-type-conflict-1y06r?file=/src/App.tsx
useEffect(() => {
// Problem: Listener is seemingly incorrect.
// Explanation:
// EventListener is coming from typescript (lib.dom.d.ts)
// MouseEvent is coming from react (global.d.ts)
const listener: EventListener = (ev: MouseEvent) => {
console.log("Click!");
};
document.body.addEventListener("click", listener);
}, []);
解释,为什么 React 声明这些类型(来自global.d.ts):
不包含 DOM 库的 React 项目需要这些 接口编译。 React Native 应用程序使用 React,但是有 没有可用的 DOM。 JavaScript 运行时仅适用于 ES6/ES2015。这些 定义允许此类项目仅使用
--lib ES6进行编译。警告:所有这些接口都是空的。如果你想输入 各种属性的定义(例如 HTMLInputElement.prototype.value),需要添加
--lib DOM(通过 命令行或 tsconfig.json)。
【问题讨论】:
-
you need to add --lib DOM (via command line or tsconfig.json). -
@Bugbeeb 我确实有(请参阅我发布的沙箱)。
-
嗯,我怀疑是因为 dom 是一个类型声明文件,所以全局反应类型覆盖了变量声明。如果你尝试写
declare var MouseEvent: ...,你会得到一个警告,因为它已经被定义了。有点像在两个不同的文件中写var x = 1和var x = 'a',第二个覆盖第一个 -
@Bugbeeb 我也认为这就是正在发生的事情。两者都是全局类型声明文件,但 React 的一个优先且不完整。
标签: reactjs typescript next.js definitelytyped