11---
2- title : Deep Dive
2+ title : 深入探讨
33layout : docs
44permalink : /zh/docs/handbook/declaration-files/deep-dive.html
5- oneline : " How do d.ts files work, a deep dive "
5+ oneline : " 深入解析 d.ts 文件如何工作 "
66---
77
8- ## Declaration File Theory: A Deep Dive
8+ ## 声明文件理论:深入探讨
99
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 ` 的情况下被调用,以生成不同的类型,并且在层次结构中提供多种命名类型,同时还在模块对象上包含一些属性。
1411
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)库,因为它们更加灵活,选择更多。
1713
18- ## Key Concepts
14+ ## 关键概念
1915
20- You can fully understand how to make any shape of declaration
21- by understanding some key concepts of how TypeScript works.
16+ 通过理解一些 TypeScript 的关键概念,你可以完全理解如何进行各种结构的声明。
2217
23- ### Types
18+ ### 类型
2419
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)* 是通过以下方式引入的:
2721
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 ` 声明
3327
34- Each of these declaration forms creates a new type name.
28+ 这些声明形式中的每一种都创建了新的类型名称。
3529
36- ### Values
30+ ### 值
3731
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 ` 的值。
4133
42- Again, being explicit, the following things create values:
34+ 同样,明确地说,以下内容会创建值:
4335
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+ - 函数声明
5042
51- ### Namespaces
43+ ### 命名空间
5244
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 ` 命名空间。
5646
57- This distinction is subtle and important -- here, ` A.B ` is not necessarily a type or a value.
47+ 这种区别是微妙而重要的——在这里, ` A.B ` 不一定是一个类型或一个值。
5848
59- ## Simple Combinations: One name, multiple meanings
49+ ## 简单组合:一个名称,多种含义
6050
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 ` 首先用作命名空间,然后用作类型名称,最后用作值。这些含义可能最终指向完全不同的声明!
6652
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+ 这可能会令人困惑,但只要我们不滥用,它实际上非常方便。让我们看看这种组合行为的一些有用方面。
6954
70- ### Built-in Combinations
55+ ### 内置组合
7156
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 ` ,指的是类的构造函数。枚举声明的行为类似。
7758
78- ### User Combinations
59+ ### 用户组合
7960
80- Let's say we wrote a module file ` foo.d.ts ` :
61+ 假设我们写了一个模块文件 ` foo.d.ts ` :
8162
8263``` ts
8364export var SomeVar: { a: SomeType };
@@ -86,17 +67,15 @@ export interface SomeType {
8667}
8768```
8869
89- Then consumed it:
70+ 然后使用它:
9071
9172``` ts
9273import * as foo from " ./foo" ;
9374let x: foo .SomeType = foo .SomeVar .a ;
9475console .log (x .count );
9576```
9677
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 ` 展现出来:
10079
10180``` ts
10281export var Bar: { a: Bar };
@@ -105,104 +84,95 @@ export interface Bar {
10584}
10685```
10786
108- This presents a very good opportunity for destructuring in the consuming code:
87+ 这为使用其的代码中的解构提供了很好的机会:
10988
11089``` ts
11190import { Bar } from " ./foo" ;
11291let x: Bar = Bar .a ;
11392console .log (x .count );
11493```
11594
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 ` 类型——它们是独立的。
11896
119- ## Advanced Combinations
97+ ## 高级组合
12098
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 ` 类型贡献属性。
123100
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 ` )则会冲突,命名空间之间则永远不会冲突。
128102
129- Let's see how this can be used.
103+ 让我们看看如何使用这一点。
130104
131- ### Adding using an ` interface `
105+ ### 使用 ` interface ` 添加成员
132106
133- We can add additional members to an ` interface ` with another ` interface ` declaration:
107+ 我们可以通过一个 ` interface ` 声明向另一个 ` interface ` 添加额外的成员:
134108
135109``` ts
136110interface Foo {
137111 x: number ;
138112}
139- // ... elsewhere ...
113+ // ... 在其他地方 ...
140114interface Foo {
141115 y: number ;
142116}
143117let a: Foo = ... ;
144118console .log (a .x + a .y ); // OK
145119```
146120
147- This also works with classes:
121+ 这同样适用于类:
148122
149123``` ts
150124class Foo {
151125 x: number ;
152126}
153- // ... elsewhere ...
127+ // ... 在其他地方 ...
154128interface Foo {
155129 y: number ;
156130}
157131let a: Foo = ... ;
158132console .log (a .x + a .y ); // OK
159133```
160134
161- Note that we cannot add to type aliases ( ` type s = string; ` ) using an interface.
135+ 请注意,我们不能使用接口向类型别名( ` type s = string; ` )添加成员。
162136
163- ### Adding using a ` namespace `
137+ ### 使用 ` namespace ` 添加成员
164138
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 ` 声明可以用来以不产生冲突的方式添加新的类型、值和命名空间。
166140
167- For example, we can add a static member to a class:
141+ 例如,我们可以向类添加一个静态成员:
168142
169143``` ts
170144class C {}
171- // ... elsewhere ...
145+ // ... 在其他地方 ...
172146namespace C {
173147 export let x: number ;
174148}
175149let y = C .x ; // OK
176150```
177151
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 ` 的* 静态* 部分(其构造函数)添加了一个值。这是因为我们添加了一个* 值* ,而所有值的容器是另一个值(类型由命名空间包含,命名空间又由其他命名空间包含)。
181153
182- We could also add a namespaced type to a class:
154+ 我们也可以向类添加命名空间类型:
183155
184156``` ts
185157class C {}
186- // ... elsewhere ...
158+ // ... 在其他地方 ...
187159namespace C {
188160 export interface D {}
189161}
190162let y: C .D ; // OK
191163```
192164
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 ` 的含义不冲突。
195166
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 ` 声明进行多种不同的合并。虽然这不是一个特别现实的例子,但展示了各种有趣的行为:
198168
199169``` ts
200170namespace X {
201171 export interface Y {}
202172 export class Z {}
203173}
204174
205- // ... elsewhere ...
175+ // ... 在其他地方 ...
206176namespace X {
207177 export var Y: number ;
208178 export namespace Z {
@@ -212,21 +182,19 @@ namespace X {
212182type X = string ;
213183```
214184
215- In this example, the first block creates the following name meanings:
185+ 在这个例子中,第一个块创建了以下名称含义:
216186
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 ` (类的构造函数)
222192
223- The second block creates the following name meanings:
193+ 第二个块创建了以下名称含义:
224194
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