Skip to content

Commit 2cb76bc

Browse files
authored
Merge pull request etroynov#73 from artsurkan/type-inference.md
translate type-inference
2 parents 9627f44 + 6381795 commit 2cb76bc

File tree

1 file changed

+53
-54
lines changed

1 file changed

+53
-54
lines changed

docs/types/type-inference.md

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,174 +1,173 @@
1-
# Type Inference in TypeScript
1+
# Логический вывод типа в TypeScript
22

3-
TypeScript can infer (and then check) the type of a variable based on a few simple rules. Because these rules
4-
are simple you can train your brain to recognize safe / unsafe code (it happened for me and my teammates quite quickly).
3+
TypeScript может логически вывести (а затем проверить) тип переменной на основе нескольких простых правил. Потому как эти правила просты, вы можете научить свой мозг распознавать безопасный / небезопасный код (это случилось со мной и моими товарищами по команде довольно быстро).
54

6-
> The types flowing is just how I imagine in my brain the flow of type information.
5+
> Поток типов - это то, как я представляю себе в уме распространение информации о типах.
76
8-
## Variable Definition
7+
## Определение переменной
98

10-
Types of a variable are inferred by definition.
9+
Типы переменной определяются по её определению.
1110

1211
```ts
13-
let foo = 123; // foo is a `number`
14-
let bar = "Hello"; // bar is a `string`
15-
foo = bar; // Error: cannot assign `string` to a `number`
12+
let foo = 123; // foo `число`
13+
let bar = "Hello"; // bar `строка`
14+
foo = bar; // Ошибка: невозможно `строке` присвоить `число`
1615
```
1716

18-
This is an example of types flowing from right to left.
17+
Это пример типов, распространяющихся справа налево.
1918

20-
## Function Return Types
19+
## Типы значений возвращаемых функцией
2120

22-
The return type is inferred by the return statements e.g. the following function is inferred to return a `number`.
21+
Тип возвращаемого значения определяется инструкцией возврата, например, предполагается, что следующая функция возвращает `число`.
2322

2423
```ts
2524
function add(a: number, b: number) {
2625
return a + b;
2726
}
2827
```
2928

30-
This is an example of types flowing bottom out.
29+
Это пример типов, распространяющихся снизу вверх.
3130

32-
## Assignment
31+
## Присвоение
3332

34-
The type of function parameters / return values can also be inferred by assignment e.g. here we say that `foo` is an `Adder`, that makes `number` the type of `a` and `b`.
33+
Тип параметров функции / возвращаемых значений также может быть определен посредством присваивания, например, здесь мы говорим, что `foo` является `сумматором`, и это делает `a` и `b` типом `число`.
3534

3635
```ts
3736
type Adder = (a: number, b: number) => number;
3837
let foo: Adder = (a, b) => a + b;
3938
```
4039

41-
This fact can be demonstrated by the below code which raises an error as you would hope:
40+
Этот факт может быть продемонстрирован с помощью приведенного ниже кода, который вызывает ошибку, как можно было и ожидать:
4241

4342
```ts
4443
type Adder = (a: number, b: number) => number;
4544
let foo: Adder = (a, b) => {
46-
a = "hello"; // Error: cannot assign `string` to a `number`
45+
a = "hello"; // Ошибка: невозможно `строке` присвоить `число`
4746
return a + b;
4847
}
4948
```
5049

51-
This is an example of types flowing from left to right.
50+
Это пример типов, распространяющихся слева направо.
5251

53-
The same *assignment* style type inference works if you create a function for a callback argument. After all an `argument -> parameter`is just another form of variable assignment.
52+
Логический вывод типов срабатывает с этим же стилем присвоения, если вы создаете функцию с параметром в виде колбэка. В конце концов, `argument -> parameter` - это просто еще одна форма присвоения переменных.
5453

5554
```ts
5655
type Adder = (a: number, b: number) => number;
5756
function iTakeAnAdder(adder: Adder) {
5857
return adder(1, 2);
5958
}
6059
iTakeAnAdder((a, b) => {
61-
// a = "hello"; // Would Error: cannot assign `string` to a `number`
60+
// a = "hello"; // Будет ошибка: невозможно `строке` присвоить `число`
6261
return a + b;
6362
})
6463
```
6564

66-
## Structuring
65+
## Структурирование
6766

68-
These simple rules also work in the presence of **structuring** (object literal creation). For example in the following case the type of `foo` is inferred to be `{a:number, b:number}`
67+
Эти простые правила также работают при использовании **структурирования** (создание литерала объекта). Например, в следующем случае тип `foo` определяется как `{a:number, b:number}`
6968

7069
```ts
7170
let foo = {
7271
a: 123,
7372
b: 456
7473
};
75-
// foo.a = "hello"; // Would Error: cannot assign `string` to a `number`
74+
// foo.a = "hello"; // Будет ошибка: невозможно `строке` присвоить `число`
7675
```
7776

78-
Similarly for arrays:
77+
Аналогично для массивов:
7978

8079
```ts
8180
const bar = [1,2,3];
82-
// bar[0] = "hello"; // Would error: cannot assign `string` to a `number`
81+
// bar[0] = "hello"; // Будет ошибка: невозможно `строке` присвоить `число`
8382
```
8483

85-
And of course any nesting:
84+
Ну и конечно же любое вложение:
8685

8786
```ts
8887
let foo = {
8988
bar: [1, 3, 4]
9089
};
91-
// foo.bar[0] = 'hello'; // Would error: cannot assign `string` to a `number`
90+
// foo.bar[0] = 'hello'; // Будет ошибка: невозможно `строке` присвоить `число`
9291
```
9392

94-
## Destructuring
93+
## Деструктуризация
9594

96-
And of course, they also work with destructuring, both objects:
95+
И, конечно же, они также работают с деструктуризацией, оба:
9796

9897
```ts
9998
let foo = {
10099
a: 123,
101100
b: 456
102101
};
103102
let {a} = foo;
104-
// a = "hello"; // Would Error: cannot assign `string` to a `number`
103+
// a = "hello"; // Будет ошибка: невозможно `строке` присвоить `число`
105104
```
106105

107-
and arrays:
106+
и массивы:
108107

109108
```ts
110109
const bar = [1, 2];
111110
let [a, b] = bar;
112-
// a = "hello"; // Would Error: cannot assign `string` to a `number`
111+
// a = "hello"; // Будет ошибка: невозможно `строке` присвоить `число`
113112
```
114113

115-
And if the function parameter can be inferred, so can its destructured properties. For example here we destructure the argument into its `a`/`b` members.
114+
И если параметр функции может быть логически выведен, то могут и его деструктурированные свойства. Например, здесь мы деструктурируем параметр на `a`/`b`.
116115

117116
```ts
118117
type Adder = (numbers: { a: number, b: number }) => number;
119118
function iTakeAnAdder(adder: Adder) {
120119
return adder({ a: 1, b: 2 });
121120
}
122-
iTakeAnAdder(({a, b}) => { // Types of `a` and `b` are inferred
123-
// a = "hello"; // Would Error: cannot assign `string` to a `number`
121+
iTakeAnAdder(({a, b}) => { // Типы `a` и` b` логически выводятся
122+
// a = "hello"; // Будет ошибка: невозможно `строке` присвоить `число`
124123
return a + b;
125124
})
126125
```
127126

128-
## Type Guards
127+
## Защита типа
129128

130-
We have already seen how [Type Guards](./typeGuard.md) help change and narrow down types (particularly in the case of unions). Type guards are just another form of type inference for a variable in a block.
129+
Мы уже видели, как [Защита типа](./typeGuard.md) помогает изменять и уточнять типы (особенно в случае объединений). Защиты типов - это просто еще одна форма логического вывода типа для переменной в блоке.
131130

132-
## Warnings
131+
## Предупреждения
133132

134-
### Be careful around parameters
133+
### Будьте осторожны с параметрами
135134

136-
Types do not flow into the function parameters if it cannot be inferred from an assignment. For example in the following case the compiler does not know the type of `foo` so it cannot infer the type of `a` or `b`.
135+
Типы не распространяются в параметры функции, если они не могут быть логически выведены из присвоения. Например, в следующем случае компилятор не знает тип `foo`, поэтому он не может определить тип `a` или `b`.
137136

138137
```ts
139-
const foo = (a,b) => { /* do something */ };
138+
const foo = (a,b) => { /* сделать что-нибудь */ };
140139
```
141140

142-
However, if `foo` was typed the function parameters type can be inferred (`a`,`b` are both inferred to be of type `number` in the example below).
141+
Однако, если был введен `foo`, тип параметров функции может быть логически выведен (`a`,`b` оба выведены как имеющие тип `number` в примере ниже).
143142

144143
```ts
145144
type TwoNumberFunction = (a: number, b: number) => void;
146-
const foo: TwoNumberFunction = (a, b) => { /* do something */ };
145+
const foo: TwoNumberFunction = (a, b) => { /* сделать что-нибудь */ };
147146
```
148147

149-
### Be careful around return
148+
### Будьте осторожны с возвращаемыми значениями
150149

151-
Although TypeScript can generally infer the return type of a function, it might not be what you expect. For example here function `foo` has a return type of `any`.
150+
Хотя TypeScript может обычно логически выводить тип возвращаемого значения функции, он может не соответствовать ожидаемому. Например, здесь функция `foo` имеет тип возврата `any`.
152151

153152
```ts
154153
function foo(a: number, b: number) {
155154
return a + addOne(b);
156155
}
157-
// Some external function in a library someone wrote in JavaScript
158-
function addOne(a) {
159-
return a + 1;
156+
// Какая-то внешняя функция в библиотеке, которую кто-то написал в JavaScript
157+
function addOne(c) {
158+
return c + 1;
160159
}
161160
```
162161

163-
This is because the return type is impacted by the poor type definition for `addOne` (`a` is `any` so the return of `addOne` is `any` so the return of `foo` is `any`).
162+
Это связано с тем, что на возвращаемый тип влияет плохое определение типа для `addOne` (`c` равно `any`, поэтому возвращаемое от `addIn` равно `any`, поэтому отсюда и `foo` равно `any`).
164163

165-
> I find it simplest to always be explicit about function returns. After all, these annotations are a theorem and the function body is the proof.
164+
> Я считаю, что проще всего всегда быть явным в описании возвращаемых значений функций. Ведь эти описания являются теоремой, а тело функции является доказательством.
166165
167-
There are other cases that one can imagine, but the good news is that there is a compiler flag that can help catch such bugs.
166+
Есть и другие случаи, которые нетрудно себе представить, но хорошая новость заключается в том, что есть флаг компилятора, который может помочь отловить такие ошибки.
168167

169168
## `noImplicitAny`
170169

171-
The flag `noImplicitAny` instructs the compiler to raise an error if it cannot infer the type of a variable (and therefore can only have it as an *implicit* `any` type). You can then
170+
Флаг `noImplicitAny` указывает компилятору выдавать ошибку, если он не может определить тип переменной (и, следовательно, может иметь ее только как *неявный* `any` тип). Далее вы сможете
172171

173-
* either say that *yes I want it to be of type `any`* by *explicitly* adding an `: any` type annotation
174-
* help the compiler out by adding a few more *correct* annotations.
172+
* либо сказать, что *да, я хочу, чтобы это было типом `any`* и *явно* добавить описание типа `: any`
173+
* либо помочь компилятору, добавив еще несколько *правильных* описаний.

0 commit comments

Comments
 (0)