Skip to content

Commit 4a96afc

Browse files
committed
translation from 11.05
1 parent 2b9e6f9 commit 4a96afc

File tree

32 files changed

+842
-0
lines changed

32 files changed

+842
-0
lines changed

description.en.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: |
3+
TypeScript course: free training for developers
4+
header: Typescript
5+
description: |
6+
In modern development, TypeScript has not just taken a firm place, but has replaced JavaScript in many places. Knowledge of TypeScript has become essential for any developer who works with either Node.js or the browser
7+
seo_description: |
8+
Sharpen your knowledge in a free Typescript course | Interactive exercises right in your browser | Free TypeScript course from CodeBasics
9+
10+
keywords:
11+
- typescript
12+
- typoscript
13+
- type script
14+
- тайпскрипт
15+
- ts
16+
- тс
17+
- тайп скрипт
18+
- онлайн курс
19+
- бесплатный курс
20+
- программирование
21+
- code basics
22+
- online course
23+
- free course
24+
- programming
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
Implement a description of the generalized type `MySet`, which is an analog of the JavaScript set `Set`. An example of using an object of this type:
3+
4+
```typescript
5+
const s: MySet<number> = ...;
6+
// Adding an item returns the number of items
7+
s.add(1); // 1
8+
s.add(10); // 2
9+
10+
s.has(1); // true
11+
s.has(8); // false
12+
```
13+
14+
The type includes two methods: `add()` and `has()`. The data inside must be stored in the `items` property.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
In this lesson we will talk more about Generic Types. Let's take an array as an example.
3+
4+
An array is a container type that stores values of any specified type inside it. The logic of array operation does not depend on the type of data stored inside. This definition automatically indicates that we are dealing with a generalized type.
5+
6+
To work with such a type, we need to instantiate the internal type at the moment when we want to start working with data of this type:
7+
8+
```typescript
9+
const numbers: Array<number> = [];
10+
numbers.push(1);
11+
12+
const strings: Array<string> = [];
13+
numbers.push('hexlet');
14+
```
15+
16+
The type that is specified inside the angle brackets is called **type parameter**. This name was chosen for a reason - specifying a parameter looks like a function call. Below we will see that this way of looking at generics helps us to better understand how they work.
17+
18+
Let's imagine that we want to define our own collection, which works like an array, but with additional features. Such collections are often made in ORMs to work with data loaded from a database. Let's first describe a specific version of this type that works only with numbers and a couple of standard methods:
19+
20+
```typescript
21+
type MyColl = {
22+
data: Array<number>;
23+
forEach(callback: (value: number, index: number, array: Array<number>) => void): void;
24+
at(index: number): number | undefined;
25+
}
26+
```
27+
28+
Here we see that the collection data is stored in a numeric array. There are two methods defined in the type, one of which (`forEach`) passes the elements of the collection to the colback, and the other (`at`) returns the elements of the collection at the specified index. One possible implementation of this type might look like this:
29+
30+
```typescript
31+
// The types can be omitted as they are specified in `MyColl`
32+
const coll: MyColl = {
33+
data: [1, 3, 8],
34+
forEach(callback) {
35+
this.data.forEach(callback);
36+
},
37+
at(index) {
38+
return this.data.at(index); // target >= ES2022
39+
},
40+
}
41+
42+
coll.at(-1); // 8
43+
```
44+
45+
Now let's try to generalize this type, i.e. make it generic. To do this, we need to do one simple thing: for elements of the collection, instead of `number` write `T` (or any other name starting with a capital letter) and add `T` as a type parameter to the definition:
46+
47+
```typescript
48+
type MyColl<T> = {
49+
data: Array<T>;
50+
forEach(callback: (value: T, index: number, array: Array<T>) => void): void;
51+
at(index: number): T | undefined;
52+
}
53+
```
54+
55+
This type definition can be viewed as a kind of function definition. When a specific type is specified, for example, `MyColl<string>`, then `T` in this situation is replaced by `string` inside the type definition. And if other generics are used inside the type, they "call" the type further. That is, it all works like nested function calls.
56+
57+
## Limitations of generics
58+
59+
Generics can have limitations. For example, we can say that the type that is passed to a generic must implement some interface. This is done using the `extends` keyword. Suppose we can make our `MyColl` type work only with types that implement the `HasId` interface:
60+
61+
```typescript
62+
interface HasId {
63+
id: number;
64+
}
65+
66+
type MyColl<T extends HasId | number> = {
67+
data: Array<T>;
68+
forEach(callback: (value: T, index: number, array: Array<T>) => void): void;
69+
at(index: number): T | undefined;
70+
}
71+
```
72+
73+
This allows us to use the `MyColl` type only with types that implement the `HasId` interface. For example, such code will not work:
74+
75+
```typescript
76+
const coll: MyColl<number> = {
77+
data: [1, 3, 8],
78+
forEach(callback) {
79+
this.data.forEach(callback);
80+
},
81+
at(index) {
82+
return this.data.at(index); // target >= ES2022
83+
},
84+
}
85+
```
86+
87+
Generics themselves are found everywhere in the code of libraries and frameworks. For example, in `React` component types are wrapped in generics so that you can specify props types. Generics can be used to create more generic types that can work with different data types, which we will explore in the next lessons.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: Generics (Types)
3+
tips:
4+
- >
5+
[Generic
6+
constraints](https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-constraints)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
Implement a description of a generic `MyArray` type that represents an analog of an array from JavaScript. Example of using an object of this type:
3+
4+
```typescript
5+
const coll: MyArray<number> = ...;
6+
coll.push(1); // 1
7+
coll.push(10); // 2
8+
coll.push(99); // 3
9+
10+
const newColl = coll.filter((value) => value % 2 == 0);
11+
console.log(newColl.items); // [10]
12+
```
13+
14+
The type includes two methods: [push()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) and [filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), matching the signature of Array methods. The data inside should be stored in the `items` property. For `push()`, accept the convention that the method takes only one parameter. Ignore the other parameters.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
Let's imagine that generics have disappeared from the language. Then code duplication will occur. We will have to describe the same algorithm for different data types many times.
3+
4+
Let's take for example the `last()` function returning the last element of an array. Below is its generalized version:
5+
6+
```typescript
7+
function last<T>(coll: T[]): T {
8+
return coll[coll.length - 1];
9+
}
10+
```
11+
12+
Generics can also be used in arrow functions:
13+
14+
```typescript
15+
const last = <T>(coll: T[]): T => {
16+
return coll[coll.length - 1];
17+
};
18+
```
19+
20+
Now let's try to implement the same behavior, but without using generics. To do this, we will have to create one function for each type. And the name of the function must be unique:
21+
22+
```typescript
23+
function lastForNumberType(coll: number[]): number {
24+
return coll[coll.length - 1];
25+
}
26+
27+
function lastForStringType(coll: string[]): string {
28+
return coll[coll.length - 1];
29+
}
30+
31+
// Here are definitions for all other types
32+
```
33+
34+
If there are several types, the number of functions to be defined will be defined as the product of the number of all possible types by the number of type parameters.
35+
36+
Implementing a generic using an overloaded function simplifies the task. Then you won't have to create new names:
37+
38+
```typescript
39+
function last(coll: number[]): number;
40+
function last(coll: string[]): string;
41+
// Here are definitions for all other types
42+
43+
function last(coll: any[]): any {
44+
return coll[coll.length - 1];
45+
}
46+
```
47+
48+
In the case of TypeScript, the logic will not even be duplicated, but this is a peculiarity of TypeScript. In other statically typed languages, the logic will have to be duplicated as well.
49+
50+
Whichever implementation we choose, two things must be observed:
51+
52+
* Values passed internally are not used in any way. They are only moved from one place to another
53+
* The logic always remains the same. There are no conditional constructs on data type
54+
55+
In Computer Science, the property of a function that allows values of different types to be processed in one way (using one algorithm) is called parametric polymorphism. That is, generics are TypeScript's implementation of parametric polymorphism.
56+
57+
Parametric polymorphism plays an important role in statically typed languages, where functions have to explicitly specify types. Almost all high-level statically typed languages have it. In Java and C# it is also called generics. C++ uses the name templates, but the meaning doesn't change, although templates in C++ are more than parametric polymorphism.
58+
59+
In contrast to statically typed languages, generics are not needed in dynamically typed languages such as JavaScript, Python, Ruby, PHP. In such languages, any generalized algorithm automatically works for all data types.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: Generics (Functions)
3+
tips:
4+
- >
5+
[TypeScript
6+
Generic Functions](https://www.geeksforgeeks.org/typescript-generic-functions/)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
Implement a description of the generalized type `MyMap`, which is an analog of the associative array from JavaScript. Example of using an object of this type:
3+
4+
```typescript
5+
const map: MyMap<string, number> = ...;
6+
map.set('one', 1);
7+
map.set('two', 2);
8+
9+
map.get('one'); // 1
10+
map.get('two'); // 2
11+
```
12+
13+
The type includes two methods `set()` and `get()`. The first method accepts two generic parameters: a key and a value. The second method accepts the key and returns the value. Values are stored inside the object as a JavaScript built-in class [Map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map).
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
Generics, like ordinary functions, can have several type parameters. In this lesson, we will analyze such generics.
3+
4+
The principle of generics does not change from the number of parameters. The only thing you need to keep an eye on is the names:
5+
6+
```typescript
7+
type Double<T, U> = {
8+
first: T;
9+
second: U;
10+
}
11+
12+
const value: Double<string, number> = {
13+
first: 'code-basics',
14+
second: 1,
15+
}
16+
```
17+
18+
## Type inference from function arguments
19+
20+
Let's imagine that we need to call a function with several parameters. The arguments are represented by generics.
21+
22+
For example, the function `join()` can be described as follows:
23+
24+
```typescript
25+
function join<T, U>(coll1: (T | U)[], coll2: U[]): (T | U)[] {
26+
return coll1.concat(coll2);
27+
};
28+
29+
join<number, string>([1, 2], ['one', 'two']); // [1, 2, 'one', 'two']
30+
```
31+
32+
But TypeScript allows us to do this more easily and not have to specify types for all parameters:
33+
34+
```typescript
35+
join([1, 2], ['one', 'two']); // [1, 2, 'one', 'two']
36+
```
37+
38+
TypeScript will infer the types for the function parameters itself. This is called type inference from function arguments. In this case, TypeScript will infer the types `number` and `string` for the parameters `T` and `U` respectively.
39+
40+
In the following lessons, we will learn about TypeScript's built-in generics that have two parameters. In real programming, such generics are often found in application code, such as in React.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: Generics with multiple parameters
3+
tips:
4+
- >
5+
[Typescript Generics
6+
Explained](https://rossbulat.medium.com/typescript-generics-explained-15c6493b510f)

0 commit comments

Comments
 (0)