[eslint-plugin-react-hooks] 缺少类型声明

axzmvihb  于 7个月前  发布在  React
关注(0)|答案(2)|浏览(112)

版本:所有
严重性:低

问题

当在TypeScript环境中导入eslint-plugin-react-hooks时,会抛出一个"缺少类型声明"的错误。

原因

这是因为eslint-plugin-react-hooks包中没有包含任何类型声明。通常这些声明会在index.d.ts文件中。此外,eslint-plugin-react-hooks项目中也没有对应的@types/...包供用户依赖。

解决方法

用户可以按照错误信息中的说明,进行临时模块增强,为该包声明自己的类型。在我的项目中,我是这样做的:

  1. // ./src/@types/eslint-plugin-react-hooks.d.ts
  2. declare module 'eslint-plugin-react-hooks' {
  3. import type { ESLint } from 'eslint';
  4. const plugin: Omit<ESLint.Plugin, 'configs'> & {
  5. // eslint-plugin-react-hooks does not use FlatConfig yet
  6. configs: Record<string, ESLint.ConfigData>;
  7. };
  8. export default plugin;
  9. }

但这种方法不会自动与包保持同步,也不能保证正确性。它还可能不完整,不包含插件中不同配置的详细信息。

如何修复

有几种方法。

  1. 通常首选的解决方案是将所有内容都写成TypeScript,并让它为你自动生成声明文件。但我明白如果完全重写不在议程上的话 :)
  2. 可以在DefinitelyTyped仓库中添加一个@types/eslint-plugin-react-hooks包。但这样你的类型就会在你的实际代码中定义在一个完全不同的地方,而且如果你以后决定迁移到TypeScript,旧的@types/...包需要被弃用。听起来很混乱。
  3. 在我看来,最佳解决方案是向包中添加一个index.d.ts文件,声明该包的类型导出。然后将其定义为package.json中的类型声明。简单易行。
  1. // package.json
  2. + "main": "index.js",
  3. + "types": "index.d.ts",
  4. "files": [
  5. "LICENSE",
  6. "README.md",
  7. "index.js",
  8. + "index.d.ts",
  9. "cjs"
  10. ],

我很乐意自己来做这件事。我只是想先提交一个问题以确认维护者是否会批准。

重现步骤

  1. 安装typescript, eslint-plugin-react-hooks
  2. 创建一个.ts文件
  3. 导入eslint-plugin-react-hooks

代码示例

package.json

  1. {
  2. "scripts": {
  3. "build": "tsc"
  4. },
  5. "dependencies": {
  6. "eslint-plugin-react-hooks": "^4.6.2"
  7. },
  8. "devDependencies": {
  9. "typescript": "^5.5.2"
  10. }
  11. }

index.ts

  1. import reactHooksPlugin from 'eslint-plugin-react-hooks';

(你还需要一个tsconfig.json文件,但设置对此示例无关)

当前行为

TypeScript构建错误。

预期行为

无错误。

b5lpy0ml

b5lpy0ml1#

在尝试自己添加一个 index.d.ts 声明文件后,我很快意识到我并不理解这个 monorepo 的构建/捆绑系统。声明文件被排除在构建输出之外。
我找到了两个不同的 TODO 注解,解释了当前的构建过程对于一个 eslint 插件来说并不是很好。
./packages/eslint-plugin-react-hooks/npm/index.js

  1. // TODO: this doesn't make sense for an ESLint rule.
  2. // We need to fix our build process to not create bundles for "raw" packages like this.

./scripts/rollup/bundles.js

  1. // TODO: it's awkward to create a bundle for this but if we don't, the package
  2. // won't get copied. We also can't create just DEV bundle because it contains a
  3. // NODE_ENV check inside. We should probably tweak our build process to allow
  4. // "raw" packages that don't get bundled.

修复这个问题也将允许将声明文件添加到发布的包中,而不是被打包器忽略。
这让我想知道 eslint-plugin-react-hooks 是否应该像大多数独立的 npm 包一样放在自己的仓库里,以避免 monorepo 捆绑系统不适合它的尴尬情况。但我会把这个决定留给维护者。

展开查看全部
slmsl1lt

slmsl1lt2#

我打算把这里写的声明文件分享给未来在这个问题上工作的人:

  1. // index.d.ts
  2. import type { configs, rules } from './src/index';
  3. declare var plugin: {
  4. configs: typeof configs;
  5. rules: typeof rules;
  6. };
  7. export default plugin;
  1. // src/index.d.ts
  2. import type { Linter } from "eslint";
  3. import type RulesOfHooks from './RulesOfHooks';
  4. import type ExhaustiveDeps from './ExhaustiveDeps';
  5. export const configs: {
  6. recommended: Linter.Config;
  7. };
  8. export const rules: {
  9. 'rules-of-hooks': typeof RulesOfHooks;
  10. 'exhaustive-deps': typeof ExhaustiveDeps;
  11. };
  1. // both src/RulesOfHooks.d.ts and src/ExhaustiveDeps.d.ts
  2. import type { Rule } from "eslint";
  3. declare var rule: Rule.RuleModule;
  4. export default rule;
展开查看全部

相关问题