如何从 npm 声明 javascript 子模块的类型?

Posted

技术标签:

【中文标题】如何从 npm 声明 javascript 子模块的类型?【英文标题】:How to declare types for javascript submodules from npm? 【发布时间】:2020-11-10 23:20:40 【问题描述】:

我的项目中有 JS/TS 代码库。一些文件看起来像:

import Something from '@some-lib/things/something'; // index.jsx file here

const someFunction = () => 
  // do something with "Something"
;

在 VS Code 和 tsc 结果中我有错误:

找不到模块的声明文件 '@some-lib/things/something'。

'/Users/user/Projects/project/node_modules/@some-lib/things/something/index.jsx' 隐式具有“任何”类型。

尝试npm install ...(如果存在)或添加新声明 (.d.ts) 包含declare module '@some-lib/things/something';的文件

我尝试通过 creatig 文件 src/@types/@some-lib/index.d.ts 使用以下内容添加定义:

declare module '@some-lib/things/something' 
  const Something: (props: React.SVGProps<SVGSVGElement> & 
    size?: number,
    color?: string,
    inline?: boolean,
    className?: string,
  ) => React.ReactElement;

  export default Icon;

但我得到这个错误:

扩充中的模块名称无效。 模块“@some-lib/things/something”解析为“/Users/user/Projects/project/node_modules/@some-lib/things/something/index.jsx”处的无类型模块,无法扩展。

请帮帮我。如何从带有子目录/子模块的 npm 声明 JS 库的 TypeScript 类型?

【问题讨论】:

【参考方案1】:

我找到了解决办法。

如果你想为来自 npm-modules 的 js/jsx 文件创建 d.ts,你可以像这样导入:

// this is reference to ./node_modules/@some-lib/things/something/index.js
import Something from '@some-lib/things/something' 

你需要

    paths 添加到您的tsconfig.json

 "compilerOptios": 
    // ...
    "baseUrl": ".", // just require for "paths"
    "paths": 
      "@some-lib/*": ["src/types/some-lib"] // 'src/types' is just for example
    
  

    使用内容创建文件src/types/@some-lib/things/something.d.ts
declare module '@some-lib/things/something'  // equal to import
  const Something = number; // number just for example

  export = Something;

据我了解,您的d.ts 文件路径应该与node_modules 的路径相同,只是它的根在示例中以src/types/ 开始。

我真的希望这对你有帮助,祝你好运!

【讨论】:

【参考方案2】:

重复 Having error "Module 'name' resolves to an untyped module at..." when writing custom TypeScript definition file

应在模块声明中声明导入。

【讨论】:

抱歉之前的评论很丑...我需要添加到 tsconfig 中才能正常工作?我将导入添加到声明中,现在我有 2 个相同的错误:找不到模块的声明文件... 我的 tsconfig.json 看起来像这样: "compilerOptions": "module": "commonjs", "esModuleInterop": true, "target": "es2017", "lib": ["es2017", "esnext.asynciterable"], "noImplicitAny": true, "moduleResolution": "node", "sourceMap": true, "outDir": "lib", "emitDecoratorMetadata": true, "experimentalDecorators": true, "skipLibCheck": true, "strict": true , "include": [ "src" ] 此配置中没有“paths/typeRoots”选项。我的意思是,我如何告诉 TSC 我的 npm 子模块应该被来自自定义 d.ts 文件的信息替换? "compilerOptions": "typeRoots": ["node_modules/@types", "src/@types"]

以上是关于如何从 npm 声明 javascript 子模块的类型?的主要内容,如果未能解决你的问题,请参考以下文章

通过GIT安装私有NPM模块,并让它更新?

如何在 AngularJS 中声明子模块

用于无类型 npm 模块的 TypeScript 自定义声明文件

如何从 typescript 使用 npm 模块?

运行 NPM 子进程导致“找不到模块”

phantomjs:如何在phantomjs中使用npm模块?