gpt4 book ai didi

reactjs - 如何将其他类型导入我的 TypeScript 自定义声明文件?

转载 作者:搜寻专家 更新时间:2023-10-30 20:34:18 25 4
gpt4 key购买 nike

我的 TypeScript + React + Webpack + Jest + Enzyme 可以正常工作。

我觉得有必要在我的测试规范中提供一些可访问的全局函数。我可以通过指向 setupTestFrameworkScriptFile 来做到这一点Jest 配置中的选项到 .js 文件,我有这样的东西:

const Enzyme = require("enzyme");
const React = require("react");

const getMuiTheme = require("material-ui/styles/getMuiTheme").default;

global.mountWithContext = (node) => {
return Enzyme.mount(node, {
context: {
muiTheme: getMuiTheme()
},
childContextTypes: {
muiTheme: React.PropTypes.object
}
});
};

在我的规范文件上,我可以调用 mountWithContext(),当我运行测试时它会正常工作。但是我的编辑器不识别这个函数。

为了解决这个问题,我创建了一个 /typings/declarations.d.ts 文件:

declare function mountWithContext(node: any): any;

现在我的规范文件可以识别 mountWithContext 函数,但是类型是“错误的”。正确的定义应该是这样的:

declare function mountWithContext(node: React.ReactElement<any>): Enzyme.ReactWrapper<P, S>;

React.ReactElement 被正确识别,因为 @types/react/index.d.ts 文件包含以下内容:

export = React;
export as namespace React;

enzyme 的情况并非如此。没有导出全局 Enzyme。查看 @types/enzyme/index.d.ts 有这样的东西:

export interface ReactWrapper<P, S> extends CommonWrapper<P, S> {
(...)
}

但即使我这样做:

declare function mountWithContext(node: React.ReactElement<any>): ReactWrapper<P, S>;

这是行不通的。 ReactWrapper 仍然无法识别。

我试图在这个 declarations.d.ts 文件中导入,这将允许我正确使用类型,但我的函数声明将不再在我的规范文件中被识别。我也试过像这样添加一个三斜杠指令:

/// <reference path="../node_modules/@types/enzyme/index.d.ts" />

文件被识别了,但是 ReactWrapper 类型仍然没有。

那么...我怎样才能为我的自定义 mountWithContext 全局函数声明一个具有所有正确类型的 TypeScript 函数声明,如下所示:

declare function mountWithContext(node: React.ReactElement<any>): ReactWrapper<P, S>;

最佳答案

如果我们想声明 global.mountWithContext 函数存在并且具有指示的类型,我们可以将以下内容添加到项目中的空声明文件中。

import React from 'react';
import enzyme from 'enzyme';

declare global {
namespace NodeJS {
interface Global {
mountWithContext<P, S>(node: React.ReactElement<any>): enzyme.ReactWrapper<P, S>;
}
}
}

详情

下面是对上面每个结构的分解:

  1. declare global block :这个构造的目的是修改,如果你愿意的话,通过引入新的声明或修改现有的声明来扩充全局范围,从 < strong> 非全局上下文中,例如模块。我们的声明文件是一个模块,因为它包含一个从 Enzyme 导入 ReactWrapper 的顶级 import 子句。这样的 block 称为“全局增强”,也可能出现在实现文件中。

  2. 包裹在 namespace NodeJS 结构中的 interface Global:在我们的测试中,我们正在访问 mountWithContext 函数作为由 Node 环境提供的全局变量,顺便命名为 global。此变量已由 Node 的类型声明声明在与其他环境全局变量(例如 process)相同的级别。但是,我们需要通过添加新成员来扩充其类型。此全局 globaltypeinterface Global 已在 namespace 内声明NodeJS,由 Node 的官方声明。我们通过声明 interface Global 的新成员来实现这一点。我们的增强需要包装在包含 Globalnamespace 中,否则它将被视为一个单独的 interface。粗略地说,词法范围适用。 (回想一下,TypeScript 接口(interface)可以在同一范围内多次声明,并且这些声明将被合并)

注意事项

我们在哪里放置这个声明?任何会导致 TypeScript 获取它并将其包含在我们的编译上下文中的地方。按照惯例,我们将把它放在项目根目录中名为 globals.d.ts 的文件中。 (从技术上讲,它可以命名为其他名称并进入较低目录)。

重要的是要注意这个声明文件是我们应用程序代码的一部分,应该 checkin 源代码管理。它必须放在目录中的第三方声明旁边,例如typingsnode_modules/@types 或 < strong>jspm_packages/npm/@types.

同样重要的是要注意,此扩充仅影响 TypeScript 文件(.ts.tsx.d.ts)。如果我们宁愿声明此函数由 TypeScript 语言服务获取,只是为了在 .js.jsx, 文件中工作时提供智能感知,这种方法将不起作用.

关于reactjs - 如何将其他类型导入我的 TypeScript 自定义声明文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41896655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com