Skip to content

init translation of module.d.ts #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 65 additions & 73 deletions docs/documentation/zh/declaration-files/templates/module.d.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ layout: docs
permalink: /zh/docs/handbook/declaration-files/templates/module-d-ts.html
---

## Comparing JavaScript to an example DTS
## JavaScript 与示例 DTS 进行比较

## Common CommonJS Patterns
## 常见 CommonJS 模式

A module using CommonJS patterns uses `module.exports` to describe the exported values. For example, here is a module which exports a function and a numerical constant:
使用 CommonJS 模式的模块使用 `module.exports` 来描述导出的值。例如,这里是导出函数和数值常量的模块示例:

```js
const maxInterval = 12;
Expand All @@ -23,46 +23,45 @@ module.exports = {
};
```

This can be described by the following `.d.ts`:
这可以通过以下 `.d.ts` 来描述:

```ts
export function getArrayLength(arr: any[]): number;
export const maxInterval: 12;
```

The TypeScript playground can show you the `.d.ts` equivalent for JavaScript code. You can [try it yourself here](/play?useJavaScript=true#code/GYVwdgxgLglg9mABAcwKZQIICcsEMCeAMqmMlABYAUuOAlIgN6IBQiiW6IWSNWAdABsSZcswC+zCAgDOURAFtcADwAq5GKUQBeRAEYATM2by4AExBC+qJQAc4WKNO2NWKdNjxFhFADSvFquqk4sxAA).
TypeScript 演练场可以展示 JavaScript 代码对应的 `.d.ts`。你可以[在这里自行尝试](/play?useJavaScript=true#code/GYVwdgxgLglg9mABAcwKZQIICcsEMCeAMqmMlABYAUuOAlIgN6IBQiiW6IWSNWAdABsSZcswC+zCAgDOURAFtcADwAq5GKUQBeRAEYATM2by4AExBC+qJQAc4WKNO2NWKdNjxFhFADSvFquqk4sxAA)

The `.d.ts` syntax intentionally looks like [ES Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) syntax.
ES Modules was ratified by TC39 in 2015 as part of ES2015 (ES6), while it has been available via transpilers for a long time, however if you have a JavaScript codebase using ES Modules:
`.d.ts` 语法有意地看起来像 [ES 模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)语法。ES 模块在 2015 年由 TC39 正式通过,作为 ES2015(ES6)的一部分,尽管它已经通过转译器长时间可用,但如果你有一个使用 ES 模块的 JavaScript 代码库:

```js
export function getArrayLength(arr) {
return arr.length;
}
```

This would have the following `.d.ts` equivalent:
这将具有以下 `.d.ts` 等效内容:

```ts
export function getArrayLength(arr: any[]): number;
```

### Default Exports
### 默认导出

In CommonJS you can export any value as the default export, for example here is a regular expression module:
CommonJS 中,你可以将任何值作为默认导出,例如下面是一个正则表达式模块:

```js
module.exports = /hello( world)?/;
```

Which can be described by the following .d.ts:
可以通过以下 `.d.ts` 来描述:

```ts
declare const helloWorld: RegExp;
export default helloWorld;
```

Or a number:
或者一个数字:

```js
module.exports = 3.142;
Expand All @@ -73,8 +72,7 @@ declare const pi: number;
export default pi;
```

One style of exporting in CommonJS is to export a function.
Because a function is also an object, then extra fields can be added and are included in the export.
CommonJS 中一种导出的方式是导出一个函数。因为函数也是一个对象,所以额外的字段可以被添加并包含在导出中。

```js
function getArrayLength(arr) {
Expand All @@ -85,16 +83,14 @@ getArrayLength.maxInterval = 12;
module.exports = getArrayLength;
```

Which can be described with:
可以这样描述:

```ts
export default function getArrayLength(arr: any[]): number;
export const maxInterval: 12;
```

Note that using `export default` in your .d.ts files requires [`esModuleInterop: true`](/tsconfig#esModuleInterop) to work.
If you can't have `esModuleInterop: true` in your project, such as when you're submitting a PR to Definitely Typed, you'll have to use the `export=` syntax instead. This older syntax is harder to use but works everywhere.
Here's how the above example would have to be written using `export=`:
请注意,在你的 .d.ts 文件中使用 `export default` 需要设置 [`esModuleInterop: true`](/zh/tsconfig#esModuleInterop) 才能正常工作。如果你的项目无法使用 `esModuleInterop: true`,比如当你向 Definitely Typed 提交 PR 时,你就不得不使用 `export=` 语法。这种较老的语法使用起来较困难,但在任何地方都可以正常工作。以下是如何使用 `export=` 来编写上述示例:

```ts
declare function getArrayLength(arr: any[]): number;
Expand All @@ -105,11 +101,11 @@ declare namespace getArrayLength {
export = getArrayLength;
```

See [Module: Functions](/zh/docs/handbook/declaration-files/templates/module-function-d-ts.html) for details of how that works, and the [Modules reference](/zh/docs/handbook/modules.html) page.
请查看[模块:函数](/zh/docs/handbook/declaration-files/templates/module-function-d-ts.html)以了解其工作原理的详细信息,以及[模块参考](/zh/docs/handbook/modules.html)页面。

## Handling Many Consuming Import
## 处理多种导入方式

There are many ways to import a module in modern consuming code:
在现代的消费者代码中,有许多导入模块的方式:

```ts
const fastify = require("fastify");
Expand All @@ -121,8 +117,7 @@ import fastify from "fastify";
import fastify, { FastifyInstance } from "fastify";
```

Covering all of these cases requires the JavaScript code to actually support all of these patterns.
To support many of these patterns, a CommonJS module would need to look something like:
要涵盖所有这些情况,需要 JavaScript 代码实际上支持所有这些模式。为了支持其中多种模式,一个 CommonJS 模块需要类似以下形式:

```js
class FastifyInstance {}
Expand All @@ -133,17 +128,17 @@ function fastify() {

fastify.FastifyInstance = FastifyInstance;

// Allows for { fastify }
// 允许 { fastify }
fastify.fastify = fastify;
// Allows for strict ES Module support
// 允许严格的 ES 模块支持
fastify.default = fastify;
// Sets the default export
// 设置默认导出
module.exports = fastify;
```

## Types in Modules
## 模块中的类型

You may want to provide a type for JavaScript code which does not exist
你可能希望为 JavaScript 代码提供一个不存在的类型:

```js
function getArrayMetadata(arr) {
Expand All @@ -158,7 +153,7 @@ module.exports = {
};
```

This can be described with:
这可以用以下方式描述:

```ts
export type ArrayMetadata = {
Expand All @@ -168,7 +163,7 @@ export type ArrayMetadata = {
export function getArrayMetadata(arr: any[]): ArrayMetadata;
```

This example is a good case for [using generics](/zh/docs/handbook/generics.html#generic-types) to provide richer type information:
这个例子是一个很好的使用[泛型](/zh/docs/handbook/generics.html#generic-types)来提供更丰富类型信息的案例:

```ts
export type ArrayMetadata<ArrType> = {
Expand All @@ -181,26 +176,24 @@ export function getArrayMetadata<ArrType>(
): ArrayMetadata<ArrType>;
```

Now the type of the array propagates into the `ArrayMetadata` type.
现在数组的类型会传播到 `ArrayMetadata` 类型中。

The types which are exported can then be re-used by consumers of the modules using either `import` or `import type` in TypeScript code or [JSDoc imports](/zh/docs/handbook/jsdoc-supported-types.html#import-types).
导出的类型可以被模块的消费者通过在 TypeScript 代码中使用 `import` `import type`,或者 [JSDoc 导入](/zh/docs/handbook/jsdoc-supported-types.html#import-types)来重复使用。

### Namespaces in Module Code
### 模块代码中的命名空间

Trying to describe the runtime relationship of JavaScript code can be tricky.
When the ES Module-like syntax doesn't provide enough tools to describe the exports then you can use `namespaces`.
描述 JavaScript 代码的运行时关系可能有些棘手。当类似 ES 模块的语法无法提供足够的工具来描述导出时,你可以使用 `命名空间`。

For example, you may have complex enough types to describe that you choose to namespace them inside your `.d.ts`:
例如,你可能有足够复杂的类型需要描述,选择将它们放你的 `.d.ts` 文件的命名空间中:

```ts
// This represents the JavaScript class which would be available at runtime
// 这代表在运行时可用的 JavaScript
export class API {
constructor(baseURL: string);
getInfo(opts: API.InfoRequest): API.InfoResponse;
}

// This namespace is merged with the API class and allows for consumers, and this file
// to have types which are nested away in their own sections.
// 这个命名空间与 API 类合并,允许消费者和这个文件拥有被嵌套在自己部分中的类型。
declare namespace API {
export interface InfoRequest {
id: string;
Expand All @@ -213,58 +206,57 @@ declare namespace API {
}
```

To understand how namespaces work in `.d.ts` files read the [`.d.ts` deep dive](/zh/docs/handbook/declaration-files/deep-dive.html).
要了解命名空间在 `.d.ts` 文件中的工作原理,请阅读 [`.d.ts` 深入研究](/zh/docs/handbook/declaration-files/deep-dive.html)

### Optional Global Usage
### 可选全局使用

You can use `export as namespace` to declare that your module will be available in the global scope in UMD contexts:
你可以使用 `export as namespace` 来声明你的模块将在 UMD 上下文中以全局范围可用:

```ts
export as namespace moduleName;
```

## Reference Example
## 参考示例

To give you an idea of how all these pieces can come together, here is a reference `.d.ts` to start with when making a new module
为了让你了解所有这些部分如何结合在一起,这里是一个参考的 `.d.ts`,可以在创建新模块时使用。

```ts
// Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
// Project: [~THE PROJECT NAME~]
// Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

/*~ This is the module template file. You should rename it to index.d.ts
*~ and place it in a folder with the same name as the module.
*~ For example, if you were writing a file for "super-greeter", this
*~ file should be 'super-greeter/index.d.ts'
// 类型定义 for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
// 项目: [~THE PROJECT NAME~]
// 定义者: [~YOUR NAME~] <[~A URL FOR YOU~]>

/*~ 这是模块模板文件。你应该将其重命名为 index.d.ts
*~ 并将其放在与模块同名的文件夹中。
*~ 例如,如果你正在为 "super-greeter" 编写文件,那么
*~ 文件应该是 'super-greeter/index.d.ts'
*/

/*~ If this module is a UMD module that exposes a global variable 'myLib' when
*~ loaded outside a module loader environment, declare that global here.
*~ Otherwise, delete this declaration.
/*~ 如果此模块是一个 UMD 模块,在加载到模块加载器环境之外时会暴露一个全局变量 'myLib',请在这里声明全局变量。
*~ 否则,请删除此声明。
*/
export as namespace myLib;

/*~ If this module exports functions, declare them like so.
/*~ 如果此模块导出函数,请这样声明。
*/
export function myFunction(a: string): string;
export function myOtherFunction(a: number): number;

/*~ You can declare types that are available via importing the module */
/*~ 你可以声明通过导入模块可用的类型 */
export interface SomeType {
name: string;
length: number;
extras?: string[];
}

/*~ You can declare properties of the module using const, let, or var */
/*~ 你可以使用 constlet var 声明模块的属性 */
export const myField: number;
```

### Library file layout
### 库文件布局

The layout of your declaration files should mirror the layout of the library.
你的声明文件的布局应该与库的布局相对应。

A library can consist of multiple modules, such as
一个库可以由多个模块组成,比如

```
myLib
Expand All @@ -275,7 +267,7 @@ myLib
+---- baz.js
```

These could be imported as
这些可以被导入为

```js
var a = require("myLib");
Expand All @@ -284,7 +276,7 @@ var c = require("myLib/bar");
var d = require("myLib/bar/baz");
```

Your declaration files should thus be
因此,你的声明文件应该是

```
@types/myLib
Expand All @@ -295,17 +287,17 @@ Your declaration files should thus be
+---- baz.d.ts
```

### Testing your types
### 测试你的类型

If you are planning on submitting these changes to DefinitelyTyped for everyone to also use, then we recommend you:
如果你计划将这些更改提交给 DefinitelyTyped,以供其他人使用,那么我们建议你:

> 1. Create a new folder in `node_modules/@types/[libname]`
> 2. Create an `index.d.ts` in that folder, and copy the example in
> 3. See where your usage of the module breaks, and start to fill out the index.d.ts
> 4. When you're happy, clone [DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped) and follow the instructions in the README.
> 1. `node_modules/@types/[libname]` 中创建一个新文件夹
> 2. 在该文件夹中创建一个 `index.d.ts`,并将示例复制进去
> 3. 查看你对模块的使用出现问题的地方,并开始填写 index.d.ts
> 4. 当你满意时,克隆 [DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped) 并按照 README 中的说明操作。

Otherwise
否则

> 1. Create a new file in the root of your source tree: `[libname].d.ts`
> 2. Add `declare module "[libname]" { }`
> 3. Add the template inside the braces of the declare module, and see where your usage breaks
> 1. 在你源代码树的根目录中创建一个新文件:`[libname].d.ts`
> 2. 添加 `declare module "[libname]" { }`
> 3. declare module 的大括号内添加模板,并查看你的使用出现问题的地方
Loading