Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescriptの資料を2023年の振り返りをもとに修正 #63

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 112 additions & 14 deletions docs/typescript/1st/js-basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ TypeScript では以下に置き換えて型定義を行います。
```ts
const nullValue: null = null;
```
- never: 値を持たない型

```ts
const error = (message: string): never => {
throw new Error(message);
};

const infiniteLoop = (): never => {
while (true) {}
};
```

<details><summary>Advanced</summary>

Expand Down Expand Up @@ -136,19 +147,16 @@ TypeScript では以下に置き換えて型定義を行います。

obj2.nonWidening = "fuga"; // コンパイルエラー Assigned expression type "fuga" is not assignable to type "hoge"
```
- optional property
オブジェクトプロパティをオプショナル(任意)なプロパティとして定義

- never
値を持たない型

```ts
const error = (message: string): never => {
throw new Error(message);
};

const infiniteLoop = (): never => {
while (true) {}
};
```
```ts
type User = {
name: string
age: number
gender?: string
}
```

</details>

Expand Down Expand Up @@ -346,11 +354,26 @@ const mulB = (x) => x * x; // 1行のみの場合はreturnとブロックを省
Arrow Function については次のような特徴があります。

- 名前をつけることができない(常に匿名関数)
- fnA などは変数名で匿名関数を変数に代入しているというイメージ
- `this` が静的に決定できる
- `function` キーワードに比べて短く書くことができる
- `new` できない(コンストラクタ関数ではない)
- `arguments` 変数を参照できない

```ts
const arguments = "hoge";

function regular() {
console.log(arguments);
}
const arrow = () => {
console.log(arguments);
};

regular(1, 2); //=> [Arguments] { '0': 1, '1': 2 }
arrow(1, 2); //=> hoge
```

`function` キーワードと Arrow Function の大きな違いとして、`this` という特殊なキーワードに関する挙動の違いがあります。
Arrow Function ではこの `this` の問題の多くを解決できるという利点があります。

Expand Down Expand Up @@ -656,6 +679,63 @@ const result = array.map((item) => {

TypeScript の場合も、使い方は同じです。

<details><summary>Advanced</summary>

`Array.prototype.map`の他にもいくつか配列のインスタンスメソッドを紹介します。

- `Array.prototype.some`
配列内の少なくとも 1 つの要素が指定した関数の条件を満たす場合に true を返す。
全ての要素が指定した関数の条件を満たさない場合に false を返す。

```js
const array = [1, 2, 3, 4, 5];

const even = (element) => element % 2 === 0;

console.log(array.some(even));
// true
```

- `Array.prototype.every`
配列内の全ての要素が指定した関数の条件を全て満たす場合に true を返して、一つでも条件を満たさないものがあれば false を返す。

```js
const array = [1, 30, 39, 29, 10, 13];

const isBelowThreshold = (currentValue) => currentValue < 40;

console.log(array1.every(isBelowThreshold));
// false
```

- `Array.prototype.filter`
指定された配列の中から指定された関数の条件を満たす要素だけを抽出したシャローコピーを作成します。
```js
const ages = [10, 40, 30, 20, 50]
const result = ages.filter(age => age >= 18)
console.log(result)
// [40, 30, 20, 50]
```

- `Array.prototype.reduce`
隣り合う 2 つの配列要素に対して左から右へ同時に関数を適用し、単一の値にする。

```js
const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue
);

console.log(sumWithInitial);
// 10
```

</details>

#### 演習問題

`/typescript/src/standard/exercise5.ts` を解いてみてください。
Expand Down Expand Up @@ -760,6 +840,23 @@ errorPromise("catchでエラーハンドリング").catch((error) => {
});
```

Promise にはいくつかのメソッドが用意されているため 1 つだけ紹介します。
複数の非同期処理が終わるのを待ってから次の処理を実行させたい場合などがあります。
そういった場合は、`Promise.all`というメソッドを使用します。

```js
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});

Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// [3, 42, "foo"]
```

### Async Function(ES2017)

ES2017 以降、 `Async Function` という非同期処理を行う関数を定義する構文が導入されました。
Expand Down Expand Up @@ -789,18 +886,19 @@ async function asyncMain() {
console.log("この行は非同期処理が完了後に実行される");
}
```

<details><summary>Promise で書くと…</summary>

```js
function doAsync() {
return new Promise((resolve, reject) => {
// 非同期処理
resolve();
})
});
}
function asyncMain() {
// doAsyncの非同期処理が完了するまでまつ
doAsync().then(()=>{
doAsync().then(() => {
// 次の行はdoAsyncの非同期処理が完了されるまで実行されない
console.log("この行は非同期処理が完了後に実行される");
});
Expand Down
62 changes: 31 additions & 31 deletions docs/typescript/1st_extra/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ const obj2: THoge & TFuga = {

</details>

### Generics

型定義の中で型変数を持てます。
名前の後に `< >` で囲った名前の列を与えて表現をします。

```ts
type Foo<S, T> = {
foo: S;
bar: T;
};

const obj1: Foo<string, number> = {
foo: "foo",
bar: 1,
};

const obj2: Foo<number, string> = {
foo: 2,
bar: "foo",
}
```

上記コードのようにすると、 `Foo` は2つの型変数 `S`, `T` を持ち、 `foo` , `bar` が型変数 `S`, `T` の型となる object の型を表します。
そのため、 `Foo<string, number>` とすると、その型を持つ変数は `foo: string` , `bar: number` を持つ object となります。
このように動的に型を指定することができるので、より再利用性が高い柔軟なコードを書くことができます。

#### 演習問題

`/typescript/src/advanced/exercise3.ts` を解いてみてください。

### Mapped-Types

(半)動的に型を生成出来ます。
Expand All @@ -126,7 +156,7 @@ const obj = {

#### 演習問題

`/typescript/src/advanced/exercise3.ts` を解いてみてください。
`/typescript/src/advanced/exercise4.ts` を解いてみてください。

<details><summary>Advanced</summary>

Expand Down Expand Up @@ -186,36 +216,6 @@ type Diff = "name";

#### 演習問題

`/typescript/src/advanced/exercise4.ts` を解いてみてください。

## Generics

型定義の中で型変数を持てます。
名前の後に `< >` で囲った名前の列を与えて表現をします。

```ts
type Foo<S, T> = {
foo: S;
bar: T;
};

const obj1: Foo<string, number> = {
foo: "foo",
bar: 1,
};

const obj2: Foo<number, string> = {
foo: 2,
bar: "foo",
}
```

上記コードのようにすると、 `Foo` は2つの型変数 `S`, `T` を持ち、 `foo` , `bar` が型変数 `S`, `T` の型となる object の型を表します。
そのため、 `Foo<string, number>` とすると、その型を持つ変数は `foo: string` , `bar: number` を持つ object となります。
このように動的に型を指定することができるので、より再利用性が高い柔軟なコードを書くことができます。

### 演習問題

`/typescript/src/advanced/exercise5.ts` を解いてみてください。

## 先行して使える構文
Expand Down
20 changes: 10 additions & 10 deletions typescript/src/advanced/exercise3.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
/*
* 以下の `Detail` 型を、 `Mapped Type` を用いて全て optional なパラメータを持つ型にしてください。
* 以下のコードは冗長なコードである。 generics を使って `greet` という関数一つにまとめてください。
* `some process` は `message` の型の影響を受けないものとします。
* */

// 以下のコードのコメントアウトを外して修正を行う
// {
// type Detail = {
// address: string
// gender: boolean
// age: number
// function greetString(message: string): void {
// // some process
// console.log(message)
// }

// type OptionalDetail = // ここに Detail のパラメータを全て optional にする処理を記述

// const optionalDetail: OptionalDetail = {
// age: 22
// function greetNumber(message: number): void {
// // some process
// console.log(message)
// }

// console.log(optionalDetail.age)
// greetString('hello')
// greetNumber(1)
// }
22 changes: 14 additions & 8 deletions typescript/src/advanced/exercise4.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
/*
* 以下の Str. Num 型を表す Flatten<T> を定義してください
* 以下の `Detail` 型を、 `Mapped Type` を用いて全て optional なパラメータを持つ型にしてください。
* */

// 以下のコードのコメントアウトを外して修正を行う
// {
// type Flatten<T> = // ここにコードを記述する

// // 配列であれば要素の型を抜き出す
// type Str = Flatten<string[]> // type Str = string

// // 配列でなければそのままの型を抜き出す
// type Num = Flatten<number> // type Num = number
// type Detail = {
// address: string
// gender: boolean
// age: number
// }

// type OptionalDetail = // ここに Detail のパラメータを全て optional にする処理を記述

// const optionalDetail: OptionalDetail = {
// age: 22
// }

// console.log(optionalDetail.age)
// }
22 changes: 8 additions & 14 deletions typescript/src/advanced/exercise5.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
/*
* 以下のコードは冗長なコードである。 generics を使って `greet` という関数一つにまとめてください。
* `some process` は `message` の型の影響を受けないものとします。
* 以下の Str. Num 型を表す Flatten<T> を定義してください
* */

// 以下のコードのコメントアウトを外して修正を行う
// {
// function greetString(message: string): void {
// // some process
// console.log(message)
// }

// function greetNumber(message: number): void {
// // some process
// console.log(message)
// }

// greetString('hello')
// greetNumber(1)
// type Flatten<T> = // ここにコードを記述する

// // 配列であれば要素の型を抜き出す
// type Str = Flatten<string[]> // type Str = string

// // 配列でなければそのままの型を抜き出す
// type Num = Flatten<number> // type Num = number
// }