存折传媒--高级编程师(1103) 2025-09-09 16:36 采纳率: 0%
浏览 6

monorepo的ts类型识别和提示

monorepo仓库下的play测试项目,导入组件库的组件时发生props类型提示丢失

我发现在node_modules下的play项目里的导入组件是有类型提示的,没有丢失。
可能是我的ts配置文件的问题,但是我查看了declaration设置时false,就是让ts从源码去识别数据类型,但是现实识别的结果就是any

  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-09-09 16:37
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你提到的问题是关于 Monorepo 项目中 TypeScript 类型识别和提示丢失,尤其是在 play 测试项目中导入组件库的组件时,出现 props 类型提示丢失 的情况。你发现当在 node_modules 中的 play 项目中导入组件时类型提示正常,但你自己项目的类型提示却变成了 any

    这个问题通常与 TypeScript 配置、模块解析、类型声明文件(.d.ts)构建工具配置 有关。以下是详细的分析和解决方案:


    ✅ 问题原因分析

    1. TypeScript 配置错误

      • 如果 tsconfig.json 中没有正确配置 typestypeRoots,TS 可能无法找到正确的类型定义。
      • declaration: false 是为了防止生成 .d.ts 文件,但它不影响类型识别,除非你使用了 noEmit 模式。
    2. 模块解析问题

      • 如果你的 play 项目使用的是 相对路径 导入组件库,而组件库本身并没有导出类型信息(如 .d.ts 文件),TS 会默认将这些模块视为 any
    3. 类型声明缺失

      • 组件库可能没有提供完整的类型声明文件(.d.ts),或者你在项目中没有正确引用它们。
    4. Monorepo 工具配置问题

      • 如果你使用的是 LernaNxTurborepo 等 Monorepo 工具,需要确保它们的配置支持 TypeScript 类型识别。

    🔧 解决方案步骤

    1. 检查并优化 tsconfig.json

    确保你的 tsconfig.json 包含以下关键设置:

    {
      "compilerOptions": {
        "target": "es5",
        "module": "esnext",
        "strict": true,
        "jsx": "react",
        "moduleResolution": "node",
        "esModuleInterop": true,
        "skipLibCheck": false,
        "outDir": "./dist",
        "rootDir": ".",
        "types": ["node", "react", "react-dom"],
        "typeRoots": ["./node_modules/@types", "./types"]
      },
      "include": ["src/**/*", "play/**/*"]
    }
    
    • types:指定全局类型库(如 React、Node.js 等)
    • typeRoots:指定类型声明文件的查找路径
    • skipLibCheck:设为 false,确保类型检查生效

    2. 确认组件库是否提供类型声明

    如果你使用的组件库没有自带 .d.ts 文件,你需要手动添加类型声明或使用第三方类型包。

    ✅ 示例:安装类型包

    npm install @types/your-component-library --save-dev
    

    如果组件库是通过 npm 发布的,可以查看其文档是否有对应的类型包。


    3. 确保 play 项目正确引用组件库

    play 项目中导入组件库时,应该使用 绝对路径别名(Alias)来引用组件库的源码,而不是 node_modules 中的编译后代码。

    ✅ 示例:使用别名(如 @components

    tsconfig.json 中配置别名:

    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@components/*": ["../components/*"]
        }
      }
    }
    

    然后在 play 项目中:

    import { Button } from '@components/Button';
    

    这样 TS 就能从源码中识别类型。


    4. 使用 @types 声明文件(可选)

    如果你的组件库没有类型声明,可以创建一个 index.d.ts 文件来定义类型。

    ✅ 示例:types/components.d.ts

    declare module '@components/Button' {
      import React from 'react';
    
      interface ButtonProps {
        children: React.ReactNode;
        onClick?: () => void;
        disabled?: boolean;
      }
    
      const Button: React.FC<ButtonProps>;
      export default Button;
    }
    

    然后在 tsconfig.json 中添加:

    "typeRoots": ["./types"]
    

    5. 检查构建工具配置(如 Vite、Webpack、Rollup)

    如果你使用的是构建工具(如 Vite、Webpack),请确保它不会将组件库的源码打包到 node_modules 中。你应该让 play 项目直接引用组件库的源码(如 src/ 目录)。

    ✅ 示例:Vite 配置(vite.config.js)

    import { defineConfig } from 'vite';
    import react from '@vitejs/plugin-react';
    
    export default defineConfig({
      plugins: [react()],
      resolve: {
        alias: {
          '@components': './components'
        }
      }
    });
    

    🧠 总结

    | 问题 | 解决方案 | |------|----------| | 类型提示丢失 | 检查 tsconfig.jsontypestypeRoots 设置 | | 组件库无类型声明 | 安装类型包或手动编写 .d.ts 文件 | | 模块解析错误 | 使用别名(Alias)或绝对路径导入组件库 | | 构建工具干扰 | 确保构建工具不混淆源码和编译后的代码 |


    🛠️ 示例修改后的 tsconfig.json

    {
      "compilerOptions": {
        "target": "es5",
        "module": "esnext",
        "strict": true,
        "jsx": "react",
        "moduleResolution": "node",
        "esModuleInterop": true,
        "skipLibCheck": false,
        "outDir": "./dist",
        "rootDir": ".",
        "types": ["node", "react", "react-dom"],
        "typeRoots": ["./node_modules/@types", "./types"],
        "baseUrl": ".",
        "paths": {
          "@components/*": ["../components/*"]
        }
      },
      "include": ["src/**/*", "play/**/*", "types/**/*"]
    }
    

    如果你能提供具体的项目结构或 tsconfig.json 内容,我可以进一步帮你定位问题!

    评论

报告相同问题?

问题事件

  • 创建了问题 9月9日