Skip to content

Commit 147b0c1

Browse files
committed
init translation of mixin
1 parent c8891b4 commit 147b0c1

File tree

1 file changed

+47
-57
lines changed

1 file changed

+47
-57
lines changed

docs/documentation/zh/reference/Mixins.md

Lines changed: 47 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
---
2-
title: Mixins
2+
title: mixin
33
layout: docs
44
permalink: /zh/docs/handbook/mixins.html
5-
oneline: Using the mixin pattern with TypeScript
5+
oneline: 在 TypeScript 中使用 mixin
66
translatable: true
77
---
88

9-
Along with traditional OO hierarchies, another popular way of building up classes from reusable components is to build them by combining simpler partial classes.
10-
You may be familiar with the idea of mixins or traits for languages like Scala, and the pattern has also reached some popularity in the JavaScript community.
9+
除了传统的面向对象层次结构之外,另一种常用的构建类的方式是通过组合较简单的部分类来实现可重用组件。你可能熟悉类似 Scala 等语言中的 mixin 或 trait 的概念,这种模式在 JavaScript 社区中也相当流行。
1110

12-
## How Does A Mixin Work?
11+
## mixin 是如何工作的?
1312

14-
The pattern relies on using generics with class inheritance to extend a base class.
15-
TypeScript's best mixin support is done via the class expression pattern.
16-
You can read more about how this pattern works in JavaScript [here](https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/).
13+
该模式依赖于使用类继承的泛型来扩展基类。TypeScript 最好的 mixin 支持是通过类表达式模式实现的。你可以在[这里](https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/)阅读更多关于此模式在 JavaScript 中的工作方式。
1714

18-
To get started, we'll need a class which will have the mixins applied on top of:
15+
作为起点,我们编写一个应用 mixin 的类:
1916

2017
```ts twoslash
2118
class Sprite {
@@ -29,22 +26,22 @@ class Sprite {
2926
}
3027
```
3128

32-
Then you need a type and a factory function which returns a class expression extending the base class.
29+
然后,你需要一个类型和一个工厂函数,该函数返回一个扩展基类的类表达式。
3330

3431
```ts twoslash
35-
// To get started, we need a type which we'll use to extend
36-
// other classes from. The main responsibility is to declare
37-
// that the type being passed in is a class.
32+
// 要开始,我们需要一个类型,我们将使用它来扩展
33+
// 其他类。其主要职责是声明
34+
// 传入的类型是一个类。
3835

3936
type Constructor = new (...args: any[]) => {};
4037

41-
// This mixin adds a scale property, with getters and setters
42-
// for changing it with an encapsulated private property:
38+
// mixin 添加一个 scale 属性,该属性具有用于更改它的 getter 和 setter
39+
// 以及一个封装的私有属性:
4340

4441
function Scale<TBase extends Constructor>(Base: TBase) {
4542
return class Scaling extends Base {
46-
// Mixins may not declare private/protected properties
47-
// however, you can use ES2020 private fields
43+
// mixin 可能不会声明私有/受保护属性
44+
// 但你可以使用 ES2020 私有字段
4845
_scale = 1;
4946

5047
setScale(scale: number) {
@@ -58,9 +55,9 @@ function Scale<TBase extends Constructor>(Base: TBase) {
5855
}
5956
```
6057

61-
With these all set up, then you can create a class which represents the base class with mixins applied:
58+
设置好这些之后,你可以创建一个表示已应用 mixin 的基类的类:
6259

63-
```ts twoslash
60+
```ts
6461
class Sprite {
6562
name = "";
6663
x = 0;
@@ -73,8 +70,8 @@ class Sprite {
7370
type Constructor = new (...args: any[]) => {};
7471
function Scale<TBase extends Constructor>(Base: TBase) {
7572
return class Scaling extends Base {
76-
// Mixins may not declare private/protected properties
77-
// however, you can use ES2020 private fields
73+
// 混合类可能不能声明私有/受保护属性
74+
// 但是,你可以使用 ES2020 私有字段
7875
_scale = 1;
7976

8077
setScale(scale: number) {
@@ -87,30 +84,29 @@ function Scale<TBase extends Constructor>(Base: TBase) {
8784
};
8885
}
8986
// ---cut---
90-
// Compose a new class from the Sprite class,
91-
// with the Mixin Scale applier:
87+
// Sprite 类组合一个新类,
88+
// 使用 Mixin Scale
9289
const EightBitSprite = Scale(Sprite);
9390

9491
const flappySprite = new EightBitSprite("Bird");
9592
flappySprite.setScale(0.8);
9693
console.log(flappySprite.scale);
9794
```
9895

99-
## Constrained Mixins
96+
## 有限制的 Mixin
10097

101-
In the above form, the mixin's have no underlying knowledge of the class which can make it hard to create the design you want.
98+
在上面的形式中,mixin 没有关于类的基础知识,这可能会使得创建你想要的设计变得困难。
10299

103-
To model this, we modify the original constructor type to accept a generic argument.
100+
为了模拟这一点,我们修改原始构造函数类型以接受一个泛型参数。
104101

105102
```ts twoslash
106-
// This was our previous constructor:
103+
// 这是我们先前的构造函数:
107104
type Constructor = new (...args: any[]) => {};
108-
// Now we use a generic version which can apply a constraint on
109-
// the class which this mixin is applied to
105+
// 现在我们使用一个泛型版本,它可以对应用此 mixin 的类施加约束
110106
type GConstructor<T = {}> = new (...args: any[]) => T;
111107
```
112108

113-
This allows for creating classes which only work with constrained base classes:
109+
这样可以创建仅适用于有约束基类的类:
114110

115111
```ts twoslash
116112
type GConstructor<T = {}> = new (...args: any[]) => T;
@@ -129,7 +125,7 @@ type Spritable = GConstructor<Sprite>;
129125
type Loggable = GConstructor<{ print: () => void }>;
130126
```
131127

132-
Then you can create mixins which only work when you have a particular base to build on:
128+
然后,你可以创建仅在有特定基类时才起作用的 mixins
133129

134130
```ts twoslash
135131
type GConstructor<T = {}> = new (...args: any[]) => T;
@@ -150,22 +146,20 @@ type Loggable = GConstructor<{ print: () => void }>;
150146
function Jumpable<TBase extends Positionable>(Base: TBase) {
151147
return class Jumpable extends Base {
152148
jump() {
153-
// This mixin will only work if it is passed a base
154-
// class which has setPos defined because of the
155-
// Positionable constraint.
149+
// 只有在传递了具有 setPos 定义的基类时,这个 mixin 才能起作用,这是由于 Positionable 的约束。
156150
this.setPos(0, 20);
157151
}
158152
};
159153
}
160154
```
161155

162-
## Alternative Pattern
156+
## 替代模式
163157

164-
Previous versions of this document recommended a way to write mixins where you created both the runtime and type hierarchies separately, then merged them at the end:
158+
本文档的先前版本推荐一种编写 mixins 的方式,其中你分别创建运行时层次结构和类型层次结构,然后在最后将它们合并:
165159

166160
```ts twoslash
167161
// @strict: false
168-
// Each mixin is a traditional ES class
162+
// 每个 mixin 都是一个传统的 ES
169163
class Jumpable {
170164
jump() {}
171165
}
@@ -174,24 +168,22 @@ class Duckable {
174168
duck() {}
175169
}
176170

177-
// Including the base
171+
// 包括基类
178172
class Sprite {
179173
x = 0;
180174
y = 0;
181175
}
182176

183-
// Then you create an interface which merges
184-
// the expected mixins with the same name as your base
177+
// 然后你创建一个接口,将期望的 mixins 与与基类同名的接口合并
185178
interface Sprite extends Jumpable, Duckable {}
186-
// Apply the mixins into the base class via
187-
// the JS at runtime
179+
// 通过运行时的 JS 将 mixins 应用到基类
188180
applyMixins(Sprite, [Jumpable, Duckable]);
189181

190182
let player = new Sprite();
191183
player.jump();
192184
console.log(player.x, player.y);
193185

194-
// This can live anywhere in your codebase:
186+
// 这段代码可以放在代码库中的任何位置:
195187
function applyMixins(derivedCtor: any, constructors: any[]) {
196188
constructors.forEach((baseCtor) => {
197189
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
@@ -206,21 +198,20 @@ function applyMixins(derivedCtor: any, constructors: any[]) {
206198
}
207199
```
208200

209-
This pattern relies less on the compiler, and more on your codebase to ensure both runtime and type-system are correctly kept in sync.
201+
这种模式更少地依赖于编译器,更多地依赖于你的代码库来确保运行时和类型系统正确地保持同步。
210202

211-
## Constraints
203+
## 约束
212204

213-
The mixin pattern is supported natively inside the TypeScript compiler by code flow analysis.
214-
There are a few cases where you can hit the edges of the native support.
205+
在 TypeScript 编译器内部,通过代码流分析本地支持 mixin 模式。有一些情况会使你触及本地支持的边缘。
215206

216-
#### Decorators and Mixins [`#4881`](https://github.com/microsoft/TypeScript/issues/4881)
207+
#### 装饰器和 Mixins [`#4881`](https://github.com/microsoft/TypeScript/issues/4881)
217208

218-
You cannot use decorators to provide mixins via code flow analysis:
209+
你不能使用装饰器通过代码流分析提供 mixins
219210

220211
```ts twoslash
221212
// @experimentalDecorators
222213
// @errors: 2339
223-
// A decorator function which replicates the mixin pattern:
214+
// 一个复制 mixin 模式的装饰器函数:
224215
const Pausable = (target: typeof Player) => {
225216
return class Pausable extends target {
226217
shouldFreeze = false;
@@ -233,24 +224,23 @@ class Player {
233224
y = 0;
234225
}
235226

236-
// The Player class does not have the decorator's type merged:
227+
// Player 类没有合并装饰器的类型:
237228
const player = new Player();
238229
player.shouldFreeze;
239230

240-
// The runtime aspect could be manually replicated via
241-
// type composition or interface merging.
231+
// 可以通过手动复制运行时方面来复制
232+
// 类型组合或接口合并。
242233
type FreezablePlayer = Player & { shouldFreeze: boolean };
243234

244235
const playerTwo = (new Player() as unknown) as FreezablePlayer;
245236
playerTwo.shouldFreeze;
246237
```
247238

248-
#### Static Property Mixins [`#17829`](https://github.com/microsoft/TypeScript/issues/17829)
239+
#### 静态属性 Mixins [`#17829`](https://github.com/microsoft/TypeScript/issues/17829)
249240

250-
More of a gotcha than a constraint.
251-
The class expression pattern creates singletons, so they can't be mapped at the type system to support different variable types.
241+
更多是一个要注意的地方,而不是一个约束。类表达式模式创建单例,因此无法在类型系统中映射它们以支持不同的变量类型。
252242

253-
You can work around this by using functions to return your classes which differ based on a generic:
243+
你可以通过使用函数返回基于泛型不同的类来解决这个问题:
254244

255245
```ts twoslash
256246
function base<T>() {

0 commit comments

Comments
 (0)