如何覆盖通过@ types/package安装的不正确的TypeScript类型定义

Bor*_*ard 45 typescript

假设我想dotenv在我的TypeScript项目中使用模块并使用它安装.d.ts npm install @types/dotenv --save.然后我意识到类型不正确.例如,该config()函数不返回布尔值,而是返回更丰富的对象.

我该如何处理这种情况?我是否应该将下载的类型定义复制到另一个文件,手动更新并卸载@ types/dotenv?有没有更好的办法?(我需要立即修复,而不是在它被上游维护者合并之后.)

Dan*_*ser 16

我将从DefinitelyTyped复制声明文件,在本地修改它们,将PR发送到DefinitelyTyped,然后按照以下问题给出的建议立即使用更改:如何编写和使用不存在的自定义声明文件DefinitelyTyped?

将更新发送到DefinitelyTyped

  1. 转到DefinitelyTyped回购:https://github.com/DefinitelyTyped/DefinitelyTyped/
  2. 在本地克隆你的fork.(经常只是git clone https://github.com/YourUserName/DefinitelyTyped/)
  3. 为您的更新创建一个分支(例如git branch changes-to-xyz)
  4. 对您感兴趣的包进行更改.
  5. 添加和提交文件.(git add types; git commit)
  6. 然后将它们推送到DefinitelyTyped(git push -u origin changes-to-xyz)的分支

在本地使用这些更新

  1. local-types在项目中创建一个文件夹.
  2. 复制xyz你修改过的DefinitelyTyped文件夹(让我们称之为)local-types/xyz.
  3. local-types/xyz,跑npm init --scope types --yes.
  4. 从项目的根目录开始运行 npm install local-types/xyz

而已!

  • 为了正确工作,在生成包后,我必须在包前面手动添加“@types/”范围。另外,建议将本地软件包版本与软件包版本相匹配。 (3认同)
  • 对于`yarn`,将本地步骤#4更改为`yarn add file:local-types / xyz` (2认同)

deK*_*joo 13

我会检查版本dotenv和版本@types/dotenv是否对齐,我的原因是函数缺失.

如果他们是更干净的方式将自己修改.d.ts.为了做到这一点:npm remove @types/dotenv.types在项目上创建一个文件夹.复制整个文件夹中 dotenv发现node_modules/@types它.

然后修复你的d.ts并修改你tsconfig.json的告诉他也要在你的新文件夹中找到丢失的类型,typeRoots如下所示:

{
"compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "typeRoots": [
        "./node_modules/@types",
        "./types/",
    ]
},
"files": ["./app.ts"]
}
Run Code Online (Sandbox Code Playgroud)

(不要忘记添加./node_modules/@types或者你用npm获得的其他类型将不再被发现)

希望能帮助到你!

  • 如果没有 `@types/` 包,而是声明在 `module-package-name/index.d.ts` 或 `module-package-name/types/index.d.ts` 中怎么办? (5认同)

gol*_*pot 10

您可以@types/foo通过patch-package在本地为应用 程序打补丁

  1. npm i -D patch-package

  2. 只需修改node_moules/@types/foo即可满足您的需求。

  3. 运行npx patch-package @types/foo。这将在patches/其中创建一个差异文件,该差异文件记录了上一步的更改。

  4. 进行添加scripts: {postinstall: "patch-package"}package.json以便在安装后应用补丁。

  • 让我感到难过的是,这种依赖项向我的项目添加了 198 个传递依赖项……同时,警告未来尝试此解决方案的用户。 (13认同)
  • 哇这让我开心 (8认同)
  • 如果您不想让它让您的部门变得臃肿,只需使用 npx 来运行它即可。 (3认同)

Rog*_*ves 7

我试图覆盖 Fabric.js 包中的函数定义,其中的函数loadImage现在正在更新以返回 Promise,而不是将回调作为第二个参数,经过相当多的尝试和错误后,我找到了一种方法来覆盖只需导入如下文件即可原始类型:

import { fabric } from "fabric"

declare module "fabric" {
  namespace fabric {
    //@ts-ignore
    interface IUtil extends fabric.IUtil {
      loadImage(url: string): Promise<HTMLImageElement>
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,这种扩展自身的接口的组合(以及用于打字稿的 @ts-ignore 来忽略接口不应该递归定义自身的事实)是有效的


Eri*_*vic 5

此处未提及的一种方法是将类型声明放入index.d.ts文件中。就我而言,from的类型@types/react-bootstrap不正确。

我想使用bsClass文档中声明的,但在中不存在Popover。相反,他们包括了一个不存在的道具PopoverbsStyle

对我来说,解决方法是删除bsStyle并添加bsClass

import * as React from "react";
import { Sizes } from "react-bootstrap";

// Overwrite bad declaration from @types/react-bootstrap
declare module "react-bootstrap" {
    namespace Popover {
        export interface PopoverProps extends React.HTMLProps<Popover> {
            // Optional
            arrowOffsetLeft?: number | string;
            arrowOffsetTop?: number | string;
            bsSize?: Sizes;
            bsClass?: string; // This is not included in types from @types/react-bootstrap
            placement?: string;
            positionLeft?: number | string;
            positionTop?: number | string;
        }
    }
    class Popover extends React.Component<Popover.PopoverProps> { }
}
Run Code Online (Sandbox Code Playgroud)

更新资料

我终于忍住了,将PR上传到DefinitelyTyped,以添加一些缺少的bsClass / bsSize声明。

更新2:使用声明合并的示例

我想要React中标签的img loading="lazy"属性<img>,但尚未合并。我是这样解决的:

文件: global.d.ts

// Unused import - only used to make this file a module (otherwise declare global won't work)
// tslint:disable-next-line:no-unused
import React from "react";

// Extend HTMLImageElement to support image lazy loading
// https://addyosmani.com/blog/lazy-loading/
declare global {
    namespace React {
        interface ImgHTMLAttributes<T> {
            loading?: "lazy" | "eager" | "auto";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这仅在类型*缺失*时有帮助。可悲的是,当他们错了时,这并没有帮助。 (19认同)
  • 现在定义了 2 个“声明模块“react-bootstrap””——这个工作是否取决于 TS 在后台处理它们的顺序?是否能保证您的覆盖始终最后应用? (4认同)
  • 抱歉,但这应该如何“删除 bsStyle”?它不只是合并声明吗? (3认同)
  • 在侧节点上:您还可以使用“export {}”使文件成为模块,而不是导入未使用的文件 (2认同)