处理未定义声明文件 (index.d.ts) 的正确方法

Posted

技术标签:

【中文标题】处理未定义声明文件 (index.d.ts) 的正确方法【英文标题】:Correct way to handle undefined declaration files (index.d.ts) 【发布时间】:2018-05-14 09:02:24 【问题描述】:

我收到以下错误

error TS7016: Could not find a declaration file for module 'react-native-camera'. '/Users/ilja/Documents/Repositories/blok/node_modules/react-native-camera/index.js' implicitly has an 'any' type.
  Try `npm install @types/react-native-camera` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-native-camera';`

作为快速修复,我在项目的根目录下创建了typings/index.d.ts(没有@types/react-native-camera)文件并用

填充它
declare module 'react-native-camera';

然后,在我的 tsconfig 文件中,我像这样将它添加到我的类型根中

"typeRoots": ["node_modules/@types", "./typings"],

但是我在构建时仍然遇到同样的错误,导致我认为我的实现不正确,我错过了什么?

编辑,我的完整 tsconfig 看起来像这样


  "compilerOptions": 
    "target": "ES6",
    "module": "commonjs",
    "lib": ["es7"],
    "allowJs": true,
    "checkJs": true,
    "jsx": "react-native",
    "removeComments": true,
    "outDir": "./dist",
    "typeRoots": ["node_modules/@types", "./typings"],
    "experimentalDecorators": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "strict": true
  ,
  "exclude": ["./node_modules", "./android", "./ios", "./assets", "./__tests__", "./dist"],
  "include": ["./src"]

【问题讨论】:

【参考方案1】:

typeRoots 选项指定在哪里查找可能包含类型信息的。 documentation 一直说编译器正在寻找

我已经复制了您描述的结构并遇到了与您相同的错误。然后我在typings 下创建了一个react-native-camera 并将index.d.ts 移到那里,这样我就得到了这个结构:

typings/
└── react-native-camera
    └── index.d.ts

有了这个结构,编译就可以正常运行了。

如果你想要那种结构,使用typings 目录结构很好。对于某些项目,我使用typings 目录。对于其他项目,我更喜欢更简单的东西:源树中的 .d.ts 文件,它声明了需要声明的所有内容。因此,如果我从您给出的描述开始,但转储 typings 并添加 src/definitions.d.ts 包含

declare module 'react-native-camera';

然后代码编译就好了。

使用什么实际上是一个偏好问题。通常,当项目变得如此复杂以至于 src/definitions.d.ts 最终难以管理或难以理解时,我会转而使用 typings 目录。

【讨论】:

我更愿意将此文件命名为 src/globals.d.tssrc/ambient.d.ts,因为项目可能会增长到包含其他“定义”,例如增强,可能还有 REST 接口的声明等。否则,很好的答案. +1 我和你一样,但后来我收到了这条线的错误import Camera from "react-native-camera":Import declaration conflicts with local declaration of 'Camera'.。我能做些什么来解决这个问题?【参考方案2】:

来自库定义部分的flowtype document,它说:

libdef 是一个特殊文件,用于通知 Flow 类型签名 您的某些特定的第三方模块或模块包 应用程序使用。如果您熟悉带有标题的语言 文件(如 C++),您可以将 libdefs 视为类似的概念。

一般最佳做法

尝试为您的项目使用的每个第三方库提供一个 libdef。

查看根路径中的.flowconfig,你会看到它已经在那里定义了。

[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
./libdefs.js

然后在根路径中寻找libdefs.js,它应该在那里。或者只是自己创建它。

对于每个模块,如下声明。以rxjs 为例:

declare module 'rxjs'  declare var exports: any; 

这是官方建议的方式,不需要index.d.ts修改。

【讨论】:

对 flowtype 用户有用,但不适用于这个问题。建议的定义样式会导致 TypeScript 出现编译错误,抱怨 'rxjs' 没有导出您可能尝试从中导入的任何内容

以上是关于处理未定义声明文件 (index.d.ts) 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

Typescript 生成带有 `#private;` 字段的声明 d.ts 文件

ts-jest - 运行 jest 时从类型 (.d.ts) 中声明 const 值未定义

是否可以发布带有环境模块声明的包?

IDE未找到声明的全局类型

如何在纱线包中创建 index.d.ts 文件?

如何在 index.d.ts 打字稿定义文件中引用 Redux 类型?