1
1
---
2
- title : Deep Dive
2
+ title : 深入探讨
3
3
layout : docs
4
4
permalink : /zh/docs/handbook/declaration-files/deep-dive.html
5
- oneline : " How do d.ts files work, a deep dive "
5
+ oneline : " 深入解析 d.ts 文件如何工作 "
6
6
---
7
7
8
- ## Declaration File Theory: A Deep Dive
8
+ ## 声明文件理论:深入探讨
9
9
10
- Structuring modules to give the exact API shape you want can be tricky.
11
- For example, we might want a module that can be invoked with or without ` new ` to produce different types,
12
- has a variety of named types exposed in a hierarchy,
13
- and has some properties on the module object as well.
10
+ 构建模块以提供所需的精确 API 结构可能会相当复杂。例如,我们可能希望一个模块既可以在有 ` new ` 也可以在没有 ` new ` 的情况下被调用,以生成不同的类型,并且在层次结构中提供多种命名类型,同时还在模块对象上包含一些属性。
14
11
15
- By reading this guide, you'll have the tools to write complex declaration files that expose a friendly API surface.
16
- This guide focuses on module (or UMD) libraries because the options here are more varied.
12
+ 通过阅读本指南,你将掌握编写复杂声明文件的技巧,从而提供友好的 API 接口。本指南专注于模块(或 UMD)库,因为它们更加灵活,选择更多。
17
13
18
- ## Key Concepts
14
+ ## 关键概念
19
15
20
- You can fully understand how to make any shape of declaration
21
- by understanding some key concepts of how TypeScript works.
16
+ 通过理解一些 TypeScript 的关键概念,你可以完全理解如何进行各种结构的声明。
22
17
23
- ### Types
18
+ ### 类型
24
19
25
- If you're reading this guide, you probably already roughly know what a type in TypeScript is.
26
- To be more explicit, though, a _ type_ is introduced with:
20
+ 如果你在阅读本指南,你可能已经大致了解 TypeScript 中的类型。更明确地说,* 类型(type)* 是通过以下方式引入的:
27
21
28
- - A type alias declaration ( ` type sn = number | string; ` )
29
- - An interface declaration ( ` interface I { x: number[]; } ` )
30
- - A class declaration ( ` class C { } ` )
31
- - An enum declaration ( ` enum E { A, B, C } ` )
32
- - An ` import ` declaration which refers to a type
22
+ - 类型别名声明( ` type sn = number | string; ` )
23
+ - 接口声明( ` interface I { x: number[]; } ` )
24
+ - 类声明( ` class C { } ` )
25
+ - 枚举声明( ` enum E { A, B, C } ` )
26
+ - 引用类型的 ` import ` 声明
33
27
34
- Each of these declaration forms creates a new type name.
28
+ 这些声明形式中的每一种都创建了新的类型名称。
35
29
36
- ### Values
30
+ ### 值
37
31
38
- As with types, you probably already understand what a value is.
39
- Values are runtime names that we can reference in expressions.
40
- For example ` let x = 5; ` creates a value called ` x ` .
32
+ 和类型一样,你可能已经理解了值是什么。值是我们在表达式中可以引用的运行时名称。例如,` let x = 5; ` 创建了一个名为 ` x ` 的值。
41
33
42
- Again, being explicit, the following things create values:
34
+ 同样,明确地说,以下内容会创建值:
43
35
44
- - ` let ` , ` const ` , and ` var ` declarations
45
- - A ` namespace ` or ` module ` declaration which contains a value
46
- - An ` enum ` declaration
47
- - A ` class ` declaration
48
- - An ` import ` declaration which refers to a value
49
- - A ` function ` declaration
36
+ - ` let ` 、 ` const ` 和 ` var ` 声明
37
+ - 包含值的 ` namespace ` 或 ` module ` 声明
38
+ - 枚举声明
39
+ - 类声明
40
+ - 引用值的 ` import ` 声明
41
+ - 函数声明
50
42
51
- ### Namespaces
43
+ ### 命名空间
52
44
53
- Types can exist in _ namespaces_ .
54
- For example, if we have the declaration ` let x: A.B.C ` ,
55
- we say that the type ` C ` comes from the ` A.B ` namespace.
45
+ 类型可以存在于* 命名空间* 中。例如,如果我们声明 ` let x: A.B.C ` ,我们会说类型 ` C ` 来自于 ` A.B ` 命名空间。
56
46
57
- This distinction is subtle and important -- here, ` A.B ` is not necessarily a type or a value.
47
+ 这种区别是微妙而重要的——在这里, ` A.B ` 不一定是一个类型或一个值。
58
48
59
- ## Simple Combinations: One name, multiple meanings
49
+ ## 简单组合:一个名称,多种含义
60
50
61
- Given a name ` A ` , we might find up to three different meanings for ` A ` : a type, a value or a namespace.
62
- How the name is interpreted depends on the context in which it is used.
63
- For example, in the declaration ` let m: A.A = A; ` ,
64
- ` A ` is used first as a namespace, then as a type name, then as a value.
65
- These meanings might end up referring to entirely different declarations!
51
+ 给定一个名称 ` A ` ,我们可能会发现 ` A ` 有多达三种不同的含义:类型、值或命名空间。名称的解释取决于它所使用的上下文。例如,在声明 ` let m: A.A = A; ` 中,` A ` 首先用作命名空间,然后用作类型名称,最后用作值。这些含义可能最终指向完全不同的声明!
66
52
67
- This may seem confusing, but it's actually very convenient as long as we don't excessively overload things.
68
- Let's look at some useful aspects of this combining behavior.
53
+ 这可能会令人困惑,但只要我们不滥用,它实际上非常方便。让我们看看这种组合行为的一些有用方面。
69
54
70
- ### Built-in Combinations
55
+ ### 内置组合
71
56
72
- Astute readers will notice that, for example, ` class ` appeared in both the _ type_ and _ value_ lists.
73
- The declaration ` class C { } ` creates two things:
74
- a _ type_ ` C ` which refers to the instance shape of the class,
75
- and a _ value_ ` C ` which refers to the constructor function of the class.
76
- Enum declarations behave similarly.
57
+ 敏锐的读者会注意到,例如,` class ` 在* 类型* 和* 值* 列表中都出现过。声明 ` class C { } ` 创建了两个东西:一个* 类型* ` C ` ,指的是类的实例结构,以及一个* 值* ` C ` ,指的是类的构造函数。枚举声明的行为类似。
77
58
78
- ### User Combinations
59
+ ### 用户组合
79
60
80
- Let's say we wrote a module file ` foo.d.ts ` :
61
+ 假设我们写了一个模块文件 ` foo.d.ts ` :
81
62
82
63
``` ts
83
64
export var SomeVar: { a: SomeType };
@@ -86,17 +67,15 @@ export interface SomeType {
86
67
}
87
68
```
88
69
89
- Then consumed it:
70
+ 然后使用它:
90
71
91
72
``` ts
92
73
import * as foo from " ./foo" ;
93
74
let x: foo .SomeType = foo .SomeVar .a ;
94
75
console .log (x .count );
95
76
```
96
77
97
- This works well enough, but we might imagine that ` SomeType ` and ` SomeVar ` were very closely related
98
- such that you'd like them to have the same name.
99
- We can use combining to present these two different objects (the value and the type) under the same name ` Bar ` :
78
+ 这样工作得很好,但我们可能想象 ` SomeType ` 和 ` SomeVar ` 非常密切相关,以至于希望它们有相同的名称。我们可以使用组合将这两个不同的对象(值和类型)以相同的名称 ` Bar ` 展现出来:
100
79
101
80
``` ts
102
81
export var Bar: { a: Bar };
@@ -105,104 +84,95 @@ export interface Bar {
105
84
}
106
85
```
107
86
108
- This presents a very good opportunity for destructuring in the consuming code:
87
+ 这为使用其的代码中的解构提供了很好的机会:
109
88
110
89
``` ts
111
90
import { Bar } from " ./foo" ;
112
91
let x: Bar = Bar .a ;
113
92
console .log (x .count );
114
93
```
115
94
116
- Again, we've used ` Bar ` as both a type and a value here.
117
- Note that we didn't have to declare the ` Bar ` value as being of the ` Bar ` type -- they're independent.
95
+ 同样,我们在这里将 ` Bar ` 用作了类型和值。请注意,我们不需要将 ` Bar ` 值声明为 ` Bar ` 类型——它们是独立的。
118
96
119
- ## Advanced Combinations
97
+ ## 高级组合
120
98
121
- Some kinds of declarations can be combined across multiple declarations.
122
- For example, ` class C { } ` and ` interface C { } ` can co-exist and both contribute properties to the ` C ` types.
99
+ 某些类型的声明可以跨多个声明进行组合。例如,` class C { } ` 和 ` interface C { } ` 可以共存,并且都可以向 ` C ` 类型贡献属性。
123
100
124
- This is legal as long as it does not create a conflict.
125
- A general rule of thumb is that values always conflict with other values of the same name unless they are declared as ` namespace ` s,
126
- types will conflict if they are declared with a type alias declaration (` type s = string ` ),
127
- and namespaces never conflict.
101
+ 只要不产生冲突,这样的组合是合法的。一般来说,值总是与同名的其他值冲突,除非它们被声明为 ` namespace ` ;而类型如果用类型别名声明(` type s = string ` )则会冲突,命名空间之间则永远不会冲突。
128
102
129
- Let's see how this can be used.
103
+ 让我们看看如何使用这一点。
130
104
131
- ### Adding using an ` interface `
105
+ ### 使用 ` interface ` 添加成员
132
106
133
- We can add additional members to an ` interface ` with another ` interface ` declaration:
107
+ 我们可以通过一个 ` interface ` 声明向另一个 ` interface ` 添加额外的成员:
134
108
135
109
``` ts
136
110
interface Foo {
137
111
x: number ;
138
112
}
139
- // ... elsewhere ...
113
+ // ... 在其他地方 ...
140
114
interface Foo {
141
115
y: number ;
142
116
}
143
117
let a: Foo = ... ;
144
118
console .log (a .x + a .y ); // OK
145
119
```
146
120
147
- This also works with classes:
121
+ 这同样适用于类:
148
122
149
123
``` ts
150
124
class Foo {
151
125
x: number ;
152
126
}
153
- // ... elsewhere ...
127
+ // ... 在其他地方 ...
154
128
interface Foo {
155
129
y: number ;
156
130
}
157
131
let a: Foo = ... ;
158
132
console .log (a .x + a .y ); // OK
159
133
```
160
134
161
- Note that we cannot add to type aliases ( ` type s = string; ` ) using an interface.
135
+ 请注意,我们不能使用接口向类型别名( ` type s = string; ` )添加成员。
162
136
163
- ### Adding using a ` namespace `
137
+ ### 使用 ` namespace ` 添加成员
164
138
165
- A ` namespace ` declaration can be used to add new types, values, and namespaces in any way which does not create a conflict.
139
+ ` namespace ` 声明可以用来以不产生冲突的方式添加新的类型、值和命名空间。
166
140
167
- For example, we can add a static member to a class:
141
+ 例如,我们可以向类添加一个静态成员:
168
142
169
143
``` ts
170
144
class C {}
171
- // ... elsewhere ...
145
+ // ... 在其他地方 ...
172
146
namespace C {
173
147
export let x: number ;
174
148
}
175
149
let y = C .x ; // OK
176
150
```
177
151
178
- Note that in this example, we added a value to the _ static_ side of ` C ` (its constructor function).
179
- This is because we added a _ value_ , and the container for all values is another value
180
- (types are contained by namespaces, and namespaces are contained by other namespaces).
152
+ 请注意,在这个例子中,我们向 ` C ` 的* 静态* 部分(其构造函数)添加了一个值。这是因为我们添加了一个* 值* ,而所有值的容器是另一个值(类型由命名空间包含,命名空间又由其他命名空间包含)。
181
153
182
- We could also add a namespaced type to a class:
154
+ 我们也可以向类添加命名空间类型:
183
155
184
156
``` ts
185
157
class C {}
186
- // ... elsewhere ...
158
+ // ... 在其他地方 ...
187
159
namespace C {
188
160
export interface D {}
189
161
}
190
162
let y: C .D ; // OK
191
163
```
192
164
193
- In this example, there wasn't a namespace ` C ` until we wrote the ` namespace ` declaration for it.
194
- The meaning ` C ` as a namespace doesn't conflict with the value or type meanings of ` C ` created by the class.
165
+ 在这个例子中,在我们为 ` C ` 编写 ` namespace ` 声明之前,并没有命名空间 ` C ` 。` C ` 作为命名空间的含义与由类创建的值或类型 ` C ` 的含义不冲突。
195
166
196
- Finally, we could perform many different merges using ` namespace ` declarations.
197
- This isn't a particularly realistic example, but shows all sorts of interesting behavior:
167
+ 最后,我们可以使用 ` namespace ` 声明进行多种不同的合并。虽然这不是一个特别现实的例子,但展示了各种有趣的行为:
198
168
199
169
``` ts
200
170
namespace X {
201
171
export interface Y {}
202
172
export class Z {}
203
173
}
204
174
205
- // ... elsewhere ...
175
+ // ... 在其他地方 ...
206
176
namespace X {
207
177
export var Y: number ;
208
178
export namespace Z {
@@ -212,21 +182,19 @@ namespace X {
212
182
type X = string ;
213
183
```
214
184
215
- In this example, the first block creates the following name meanings:
185
+ 在这个例子中,第一个块创建了以下名称含义:
216
186
217
- - A value ` X ` (because the ` namespace ` declaration contains a value, ` Z ` )
218
- - A namespace ` X ` (because the ` namespace ` declaration contains a type, ` Y ` )
219
- - A type ` Y ` in the ` X ` namespace
220
- - A type ` Z ` in the ` X ` namespace (the instance shape of the class)
221
- - A value ` Z ` that is a property of the ` X ` value (the constructor function of the class)
187
+ - 一个值 ` X ` (因为 ` namespace ` 声明包含一个值 ` Z ` )
188
+ - 一个命名空间 ` X ` (因为 ` namespace ` 声明包含一个类型 ` Y ` )
189
+ - 一个在 ` X ` 命名空间中的类型 ` Y `
190
+ - 一个在 ` X ` 命名空间中的类型 ` Z ` (类的实例结构)
191
+ - 一个作为 ` X ` 值属性的值 ` Z ` (类的构造函数)
222
192
223
- The second block creates the following name meanings:
193
+ 第二个块创建了以下名称含义:
224
194
225
- - A value ` Y ` (of type ` number ` ) that is a property of the ` X ` value
226
- - A namespace ` Z `
227
- - A value ` Z ` that is a property of the ` X ` value
228
- - A type ` C ` in the ` X.Z ` namespace
229
- - A value ` C ` that is a property of the ` X.Z ` value
230
- - A type ` X `
231
-
232
- <!-- TODO: Write more on that. -->
195
+ - 一个值 ` Y ` (类型为 ` number ` ),是 ` X ` 值的属性
196
+ - 一个命名空间 ` Z `
197
+ - 一个作为 ` X ` 值属性的值 ` Z `
198
+ - 一个在 ` X.Z ` 命名空间中的类型 ` C `
199
+ - 一个作为 ` X.Z ` 值属性的值 ` C `
200
+ - 一个类型 ` X `
0 commit comments