ペロハム大学

ヤルゾー

プロを目指す人のためのTypeScript入門 読書メモ⑬ 第8章(2)

■ 思ったこと

次の案件はAngularなのだ、リンバスで気になったキャラはドンキとエビ蕎麦、頼れるエースは黒雲りょーしゅう、グtttッチ

■ 第8章 非同期処理(8.3.1~8.3.11)

  • 前回はコールバック関数を使って処理の後に使いたい関数を都度呼んでいたが…?

Promise

  • Promise使うと非同期処理が終わった後の処理を表す関数をセットできる!わぁ!便利そう!
    • 実行結果はPromiseオブジェクトを返す
    • 帰ってきたオブジェクトでthenメソッド作って、実行したいコールバック関数を渡す流れ
    • 仕組み的には、非同期処理が終わってPromiseの結果が決まると(=解決すると)thenに登録されたコールバック関数が呼ばれる感じ

一つのPromiseに複数thenが登録されていたら?

  • すべてが登録順に呼ばれるよ

Promiseの成功・失敗

  • Promiseの解決には成功もあれば失敗もある
  • その場合、帰ってきたオブジェクトにcatchメソッドも作ってあげればOK
  • こんな風にすれば一気に書けるぜ、errorの戻り値がanyなのは注意
result.then(() =>{
    console.log("やった、成功!");
},(error) =>{
    console.log("残念、失敗!");
});
  • 例によってfinallyメソッドも使えます、成功しても失敗しても呼ばれるやつだね

Promiseオブジェクトを作ってみよう

  • new Promise<型引数>(executor関数)で作れる、結果は変数に入れたり returnにしたり
  • executor関数っていうのは要するに引数だが、new Promiseの一環として即座に実行されるよ
  • executor関数の引数にも関数を渡さなければいけない、でもresolveって書いとけばおけ
    • resolveはnewするとPromiseが用意してくれるコールバック関数だ!
    • これが呼ばれるとPromiseが成功する、つまりthenに設定した関数が呼ばれてくれる
  • executor関数ももちろん失敗あるかもなので、第二引数にrejectセットしとけばおけ

Promiseの静的メソッドいろいろ

  • 静的メソッドは、インスタンス化しなくてもクラス名.メソッド名で使えるやつだったね
  • Promiseにもそーいうのがあるってことさ
  • 例えばPromise.resolvePromise.reject、即座に成功or失敗オブジェクトを作成できる
  • Promise.allは複数のPromiseを合成してくれる、どゆこと!?
    • Promiseのオブジェクト配列を引数として受け取って全部成功したら成功のオブジェクト返してくれる
    • 一個のthenでまとめて結果がゲッチューできるってことさ
  • 他にもPromise.allSettlandがある
    • allと動きはほぼ同じだけど、失敗時に即失敗せず最後まで実行してくれる
    • 結果が成功と失敗それぞれのステータスでオブジェクトで返ってくる感じだよん

Promiseはチェーンで実行せよ

  • ただ結果をどーにかするだけなら直接呼び出せるチェーン推奨!catchを忘れず繋げとこう
readFile("./file/foo.txt","utf8")
.catch(() => "error!!") //エラーならキャッチ
.then((result) =>{ // 問題なければ処理
    console.log(result);
});

dynamic import構文

  • import("モジュール名")という構文、モジュールを非同期で呼び出せマス
  • 実行されるまでモジュールが読み込まれない、必要になるまで読み込ませたくない人には便利
  • 結果はPromiseで返ってくるのでthenで取得して使っちゃおう

■ 感想

分割代入の配列バージョンに触れてなかったことに気づいた。const[foo, bar,baz] = arrってやればarrの中身が名前なくても順番に当てはまってくれるってやつ!あと、久しぶり過ぎてアロー関数で式返したいときのreturnも忘れてた、やば!!

プロを目指す人のためのTypeScript入門 読書メモ⑫ 第8章(1)

■ 思ったこと

ずっとゲームしてたがリンバスのEGOから人格逆引きツールを作りたくなって勉強のモチベも復活した!

■ 第8章 非同期処理(8.3.1~8.2.4)

前詰んだところ!

非同期処理

  • とは、裏で行われる処理
  • そして、時間がかかる処理!

時間がかかる処理ってどんなのよ

  • 通信、自分の端末とWebサーバの間には物理的に距離があるゆえ時間がかかる
  • あと、ファイルの読み書きも。HDDやSSDにアクセスする時間がかかるのさ
  • DB処理が関われば、サーバへの通信時間+処理時間でさらに時間はかかる

ブロッキング・ノンブロッキング

  • 時間のかかる処理はブロッキングなものとノンブロッキングなもの二種に分類される
  • TypeScriptでは非同期処理=時間がかかる処理=ノンブロッキング
  • 待ち時間もプログラムを実行し続けるため、複数クライアントに対応可能
  • では、ブロッキングな処理とは…完了するまでプログラムが停止するような処理!
  • 待ちの時間が生まれるので、結構タイムロス

シングルスレッドモデル

  • TypeScriptでは時間かかる処理がブロッキングなのはあんま歓迎されない
  • それは…実行モデルがシングルスレッドなため
  • 分かりやすく言うと、プログラムの複数個所が同時に実行されることはない!ということ
    • TypeScriptは常にプログラムの一か所のみが実行されてため
    • シングルスレッドかつブロッキングな処理なんてされたら、クライアント一人の使用でプログラムの実行がストップしてしまう
  • なので!複数クライアントが接続しそうな通信処理はノンブロッキングであってほしい

ところで、シングルスレッドって結局並行処理できないのになんか意味あるのか?

  • Node.jsは通信処理をOSにお願いすることで通信を実行している
  • なので、待ち時間とはOSの処理を待つことである
  • OSの処理は並行に行うことができる…そういうこと!

コールバック関数

  • では、TypeScriptで非同期処理はどうやって行うか?色々あるけど、コールバック関数が使える
  • コールバック関数とは、非同期処理が終わった後に呼び出される関数!
  • ノンブロッキングな処理は勝手にノンストップで始まるが、その終了を待たずに次の処理がはじまってしまう。ので、こいつを使うことで終了を教えてあげるのさ
  • readlineも、文字が入力されるまで処理の実行を待ってくれたよね、こんな感じでreadline((入力値)=>{処理})
  • 失敗を見越してエラーオブジェクトを引数に入れてあげるのも大事、詳細は各APIまで!

コールバック関数 ~タイマー編~

  • タイマーは一定時間後に特定の処理をすること、setTimeout関数で使おう
  • 一定時間待ってる間に次の処理を進めてくれるのさ
// 第1引数:コールバック関数
// 第2引数:数値(ミリ秒数)
setTimeout(() => {
    console.log("タイマー呼ばれた");
}, 3000);
console.log("タイマー設定");

同期処理と非同期処理の順序

  • TypeScriptはにおいて、同期的に実行中のプログラムに、非同期処理が割り込むことは、、ない!…とは??
    • 同期的に実行中のプログラム=上から下に実行中のプログラム
    • この状態で非同期処理が完了してもわざわざ中断してコールバック関数を呼んでくれない
    • 同期的な処理が全部終わったらやっと呼ばれるってことさ

■ 感想

この記事自体は3/7に書いてたのに全然更新してなった!もったいねえ!難しいのは次のPromiseとかからだね。

プロを目指す人のためのTypeScript入門 読書メモ⑪ 第7章

■ 思ったこと

久しぶりに新しい章に来た!そしてサクっと終わった!

■ 第7章 TypeScriptのモジュールシステム(7.1~7.4.4)

モジュールシステム

  • モジュールシステムって、多数のファイル(=モジュールも)に分割してプログラムを作る仕組みのこと!
  • データを提供するモジュール、機能(関数)を提供するモジュールなどいろいろ、うまく分解しよう
  • TypeScriptでは1ファイル1モジュールがほとんど
  • exportでほかのモジュールに提供、importで受け取る!

export

  • export const 変数すればおけ
  • export{x1,x2}てな感じで、変数リストでまとめてエクスポートもできる、asで別名も使える

import

  • エクスポートされた変数はimport {変数リスト} from "./xxx.js"でインポートすれば使える。asで別名で受け取ることもできる
    • 拡張子が実際はtsでもimport宣言時は.jsなので注意!
    • ファイルパスで./の省略はできない
    • import文はどこに書いても良いけど、だからこそファイルの先頭にまとめて書くのが一般的

defaultエクスポート・インポート

  • export default 式でエクスポートすると、import 変数名 from モジュール名;でインポートできるのよ
    • ここの変数名は、好きなものでOK!インポート側で決められるのだ
  • 実際、あまり使われない。入力補完も効かないしね・・

一括インポート

  • import * as 変数名 from モジュール名で、変数名の中にexportされたすべての変数を持つオブジェクトが代入される。変数名.変数で使おう!

ところでNode.jsって

  • TypeScripteの実行環境として使ってたね
  • 例えばreadlineもNode.jsがデフォルトで持っているモジュールをインポートして使ったわけだけど…

Node.jsの組込みモジュール

  • 組込みモジュールとは、追加でインストール不要…Node.jsに最初っから備わっているモジュールのこと!importすれば使えるよ
  • importする際に、fromが./から始まらないのはそういった、外部モジュールと見なしてOK、npmするやつとか

npm

  • Node.jsに同梱されるパッケージマネージャ
  • npmでインストールしたパッケージはnode_modulesディレクトリに保存される。importrequireで使ってみよう
  • フロントエンド開発でも必要なモジュールはnpmインストールするのが慣例

package.json

  • Node.jsのプロジェクトはpackage.jsonを持っている
    • プロジェクトのルート(一番上!)に配置される設定ファイル
    • Node.jsでプログラムが実行される時に読み込まれる
    • 依存関係を記述する役割もあり
  • npm initで作成されるので、それからnpm install パッケージ名で必要なパッケージをインストールしよう

dependencies / devDependencies

  • プロジェクトが依存するライブラリの一覧をバージョンとともに記述する
    • dependenciesは実行時に必要なライブラリ
    • devDependencieshはビルドするときに必要なライブラリ
  • npm installしたらpackage.jsonも更新されるよ
  • 逆に!手でpackage.jsonにライブラリを書き込んでnpm install実行するとそれがインストールできる

package-lock.json

  • npmが動作する際に自動で作成されるファイル
  • node_modulespackage.jsonの依存関係に従ってインストールされたディレクトリだけど・・その内容を表すスナップショット的なもの!
  • 主な役割はnode_modulesの情報を保持することで、再現性を高めること
  • 人間が触ることは基本的にない

@types

  • TypeScript向けの型定義が同梱されていないパッケージは、そのままだとコンパイルエラーとなる・・
  • npmはTypeScript専門ではなくJavaScript向けのため、結構ありがち
  • こういう時は@typeパッケージをインストールすれば手っ取り早いよ
    • パッケージに同梱されていない型定義を補ってくれる
    • 例えばnpm install expressだけだとexpressは型定義がない=型チェック不可でコンパイルエラーになるんだけど、npm install -D @types/expressで型情報をインストールすればエラーが消える
    • 補足!-dpackage.jsondevDependencieshに書き込んでねの意、型定義はコンパイルの時にしか使わないので…
  • ちなみに@typeパッケージは基本的に有志による。日本語化MODみたいだあ・・

自前で型定義を作るには

  • .d.tsで終わるファイルに書けばOK、この名前で作ればTypeScriptが型定義ファイルとして扱ってくれるぞ
  • declare modual "モジュール名"で特定のモジュール文字に対して型定義を宣言できる

■ 感想

Node.jsのモジュールって便利な共通部品みたいなものなのね! Va11-hall全ルートやった!めっっちゃ良い話。鋼鉄心臓少女がサントラに入ってないのだけつらい、この曲流れるとかなり雰囲気出るんだ・・Truthとちょっと似てるからかな?アナとドロシーの関係はたまらん。シロナガス島でもアウロラとアレックスが好きだったので…

プロを目指す人のためのTypeScript入門 読書メモ⑩ 第6章(3)

■ 思ったこと

今回は区切りがなかなか付けられない、一個一個が難しいなど理由から更新に時間がかかった!そしてその間にVA-11 Hall-A一週目もクリアした!家賃払えなかった!もっかいやる!

■ 第6章 高度な型(6.3~6.8.6)

ユニオン型の素晴らしいところ

  • 型の絞り込みに対応しているところだ!
  • コントロールフロー解析ともいう
  • 等価演算子(===)とか使って早期にこれはこの型、と絞っていく

typeof演算子

  • typeof 式という形の、式!
  • 式の型によって対応する文字列を返す、typeof 1なら"number"というように
  • string | numberのようなユニオン型に有効
  • if (typeof value === "number")みたいに受け取った値で処理を絞れる、elseは絶対stringだしね

代数型データ型(タグ付きユニオン、直和型)

  • という機能はTypeScriptにはないが、オブジェクト型とユニオン型を用いて代用できる
  • プロパティにユニオン型に対応するリテラル型をあらかじめ持たせといて、判別に使うのだ
    • 判別用の情報はタグと呼ばれる
  • データを使う側は、タグを頼りに型を絞ればOK
  • おかげでユニオン型がなんの型の時は、がやりやすくなる!

switch文でも絞り込める

  • ユニオン型の構成要素が膨大になるならこっちも検討するべし、網羅されてない型があると戻り値エラーなったりするので良いかんじ

lookup型

  • 構文はオブジェクト型[文字列のリテラル型]
  • 例の通り、型情報を再利用できるのさ
export type Human = {
  type: "human";
  name: string;
  age: number;
};

/**
 * ageをセットする関数
 *  @param human Human
 *  @param age  loo
kup型(number) 実際はHuman型のageプロパティの型
 *        …元の型が変わってもこれならOK。
 */
const setAge = (human: Human, age: Human["age"]) => {
// 処理
}

keyof型

  • 構文はkeyof 型
  • すでにある型の、プロパティを全部文字列リテラルの型にしちゃう
  • なんちゃら型のプロパティを
export type Human = {
  name: string;
  age: number;
};

// keyof HumanでHumanKeys型ができた!
// Humanオブジェクトはnameとageなので、keyof Humanは"name" | "age"型の意味
// プロパティは文字列のリテラル型となる
type HumanKeys = keyof Human;

// HumanKeys 型は文字列"name"か"age"だけが代入可能
let key: HumanKeys = "name";
key = "age";

keyof型・lookup型はジェネリクスと一緒に使ってみよう

  • lookup型はオブジェクトのプロパティ名いうとその型になるやつ
  • keyof型はオブジェクト指定するとそのプロパティ全部入りの文字列リテラル型のなる
  • ジェネリクスは型が決まってない時に使う、型引数を持つ関数だったね
  • 全部まぜると、こんな感じ
// オブジェクトのプロパティを名を受け取って中身を返す関数
// extendsを型引数の後ろにつけると、Kを必ずTの部分型にする制約がつく
// 意味としては変なのkeyに持ってこないように。
const get = <T, K extends keyof T>(obj: T, key: K): T[K] => {
  // オブジェクトの中のプロパティ値を取得する
  return obj[key];
};

type Cocktail = {
  adelhyde?: number;
  bronsonExtract?: number;
  powderedDelta?: number;
  flanergide?: number;
  karmotrine?: number;
  type: string[];
};

let karmotrine;
const setkarmotrine = (quantity: number) => {
  karmotrine = quantity;
};

setkarmotrine(4);
const sugarRush: Cocktail = {
  adelhyde: 2,
  powderedDelta: 1,
  karmotrine: karmotrine,
  type: ["甘め", "ガーリー", "ハッピー"],
};

const cocktailType = get(sugarRush, "type");
// const get: <Cocktail, "type">(obj: Cocktail, key: "type") => string[]
console.log(`シュガーラッシュは${cocktailType}なカクテルです。`);
// [console]シュガーラッシュは甘め,ガーリー,ハッピーなカクテルです。

const karmotrineQuantity = get(sugarRush, "karmotrine");
// const get: <Cocktail, "karmotrine">(obj: Cocktail, key: "karmotrine") => number | undefined
console.log(`カルモトリンは${karmotrineQuantity}%含まれています。`);
// [console]カルモトリンは4%含まれています。

keyof型のkeyはnumber型になる時もある

  • keyof型のkeyですが、実のところ文字列リテラル型だけではなく、number型でもOKなのです
  • 型のプロパティが数値の時のお話

アサーション

  • って何!?と思うが、できるだけ使用を避けた方がいいらしい、そうなの?
    • 型安全を意図的に破壊しちゃうんだって…
    • じゃあいつ使うのか??それは、型推論が完璧じゃない時にTypeScriptに正しい挙動を人間が教えてあげたい時なのよ
  • 構文は式 as 型、式の型を強制的に変えたるぜ!
  • でも、実際に値がその型に変わるわけではない…コンパイル時に型がコレだと認識してくれるだけ

式 as const

  • これはよく見る!
  • 式部分の型推論に対して、4つのすてきな効果がある
  • つまり…全部後から変更不可になるってこと!!
  • おさらいだけど、タプル型は要素数が固定されていて、いろんな型を入れられる型ね
const name1 = ["a", "b", "c", "d", "e"]
// const name1: string[]
const name2 = ["neko", "inu", "car"] as const;
// const name2: readonly ["neko", "inu", "car"]

// 配列はnumber型のインデックスに要素を代入しているオブジェクトなので
// インデックスの代わりにnumberを使うと全部とれる
type Names = (typeof name2)[number];
// type Names = "neko" | "inu" | "car"

恐怖!any型

  • 型安全を破壊するやつと言ったら、これ以上の存在はない
    • なんといっても、型チェックを無効化してくるのだ
    • つまり、何を代入してもエラーにならない!
  • とりあえず、使うな!どうしても必要ならasとか使え!

実は安全!unknown型

  • こいつもanyよろしくなんでも入る型だが、可能な操作が限られているので安全
  • 何が入ってるかわからないからunknown型
  • なんでも受け取って、typeofで絞ってあげるのがいい感じ

一応知っとけ!もっと高度な型

  • object型
    • そうそう、オブジェクトはプリミティブ以外のすべてだったね
    • ゆーて、空のオブジェクト型({}型)にはリテラル型でもなんでも入ってしまうので…本当にオブジェクトのみに制限したいなら不十分
    • というときに使う!!
  • never型
    • 何にも入らない型、unknown型の反対!
    • しかし、仮に受け取ったneverはどんな型にも代入し放題!な、なんそれ!
    • でも!型安全は守られるよ、だってneverに当てはまる型なんてないんですもの!
    • それってつまり、never型はすべての型の部分型・・ともいえる
  • 型述語(ユーザー定義ガード)
    • 型の絞り込みを行う仕組み!が、型安全の破壊者でもあるので注意(まだマシではある)
    • 特徴としては、返り値の型が引数名 is 型といった型述語になるよ
    • const 関数= (value: unknown): value is string | number的な
    • 実際の返り値はboolean、trueなら引数名に与えられた値を型として認めてくれるらしい。つまり使用する型が絞り込める
    • こんなんしなくてもifとかで絞ればいいじゃんと思うが、得てして構文エラーになるのでこれが必要

可変長タプル型

  • タプル型の中に...配列型を含めたもの
  • 注意点としては、一個のタプル型の中で一回しか使えないこと、オプショナルな要素(?)を...配列型より後ろで使えないこと
  • スプレッド構文のように型を展開効果もあり
// ...配列型は、その部分にその配列型の要素が任意個入ることを示す
type NumberAndStrings = [number,...string[]]

const arr1: NumberAndStrings = [25,"blow","rin","maliya"];
// 0個もOK
const arr2: NumberAndStrings = [25];

type Animals = ["neko","inu","usagi"];
type AnimalMember = ["alpaca",...Animals]
// type AnimalMember = ["alpaca", "neko", "inu", "usagi"]

組み込みの型

  • mapped types,conditional typesは詰みそうだったので飛ばしてしまいました・・
  • しかし!上記の中でも有用な機能が組込み型として標準ライブラリに用意されているとな!以下参照!
// T1にのプロパティをすべてReadonlyに
type T1 = Readonly<{
  name: string;
  age: number;
}>;

// T2のプロパティをすべてオプショナルに
type T2 = Partial<{
  name: string;
  age: number;
}>;

// T3のプロパティから一部をピックアップして新しいオブジェクト作る
type T3 = Pick<
  {
    name: string;
    age: number;
  },
  "age"
>;

// T4のプロパティから一部を取り除いた新しいオブジェクト作る
type T4 = Omit<
  {
    name: string;
    age: number;
  },
  "age"
>;

type Union = "te" | "st" | 1 | 2 | undefined;
// Unionからstring型のみ抜き出した新しいユニオン型作る
type T5 = Extract<Union, string>;

// Unionからstring型を取り除いた新しいユニオン型作る
type T6 = Exclude<Union, string>;

// Unionからundefined、nullを取り除いた新しいユニオン型作る
type T7 = NonNullable<Union>;

■ 感想

長くなり過ぎた!!力試しはなんとかできたけど、型引数を積極的に使えてなかったりswitchに苦手意識があったりで回答と完璧に一致はできず!使ってかないと覚えないね!そんで、これを書いている間に色々あったが。。55時間特番、楽しんでますタイムフリーで!0大集合の野田とフワちゃんの絡みがなんか好き(笑) そして世界樹リマスター!!たのしみすぎる!

プロを目指す人のためのTypeScript入門 読書メモ⑩ 第6章(2)

■ 思ったこと

最近メガテン3やってる、今ニヒロ機構!つよいぞスカクジャ、育ち切ったアマノウズメ嬢を悪魔合体させるかが悩み。

■ 第6章 高度な型(6.2~6.2.5)

リテラル型とはなんだ

  • プリミティブ型 = 基本的な型(string、number、boolean、undefinedなど…)をさらに細分化したのがリテラル
  • おさらい!リテラルは何らかの値を生み出すための式のことね!えーと、その型というと?
  • ・・例えば、type文は型に別名をつける文だね。なので、type FooString = 'foo';"なんてやればfoo型が作れちゃうのよ、これは"foo"という文字列のみが属する文字リテラル型!違うの入れると「型 '"hoge"' を型 '"foo"' に割り当てることはできません」なんて怒られちゃうよ!
  • 今作ったfoo型がまさにリテラル型、リテラルをそのまま型として使えるちゅーわけだね
  • ややこしいが、"foo"はリテラルとしてみればfooを表す式だし、リテラル型としてみれば"foo"しか入らない型になる
  • ちなみにtype使わないでconst foo: "foo" = "foo" ;でもOK

リテラル型は、4種類ある!

  • ズバリ、文字列・数値・真偽値・BinIntのリテラル型でしょう
  • こいつらも先ほどのfoo型よろしく、リテラルをそのまんま型にする構文の使い手
  • ちなみに、リテラル型は普段は意識してないだろうが、型推論で結構登場してたのよ?
const number = 0;  //これ!変数number は0型!!
const number: number = 0;  //これだとnumber 型
  • そうだったのか・・・!!定数は再代入できないってもしかしてそゆこと??

テンプレートリテラル

  • こいつは文字列型の一種
  • てか、テンプレートリテラル自体は覚えてる??「``」で囲われた文字列リテラルのこと!これが型になるのだろう
  • テンプレートリテラルといえば、変数を${式}で持てたけど・・今回は式ではなく型を持つ!つまり、${string}は文字列リテラルを表す式じゃなくて、stringを設定しろの型ということ!
  • `今日は${string}日`というテンプレートリテラル型がありましたら、必ず「今日は${string}日」という文字列を入れる、それだけさ

ところで、リテラル型はユニオン型と合わせると良いみたい?

  • 学んだ通り、リテラル型は型に特定の値しか入らなくするけれど、引数で使う意味はあんまりない(固定値だし…)
  • そこで、リテラル型をユニオン型にしてあげれば!まるでフラグのように扱える。文字列なのでパっとみ分かりやすいよ

リテラル型の・・wideningって何!?

  • そういう挙動がある
  • まず、型推論は常に行われている
  • そのうえで、const foo = "foo"であれば、もう再代入はしないと判断されてfoo型、let foo = "foo"だと、再代入される可能性もあるしstring型(=プリミティブ型)に変換される!これがリテラル型のwideningじゃい!!
  • オブジェクトリテラル作るときも型推論してもらってたけど、結構wideningされてる、readonlyでなければ再代入される可能性あるので…

■ 感想

リテラル型、奥が深い!!6章!マジで長くなりそう!ていうか…今やたら多幸感がある!!次の案件かなり重そうで不安しかないはずなのに。これがふわふわハッピーでしょうか?我が最愛の神(Yu&Rei)よ…

プロを目指す人のためのTypeScript入門 読書メモ⑨ 第6章(1)

■ 思ったこと

いよいよ骨太ナンバーワン、第6章よ!!がんばるZ!!

■ 第6章 高度な型(6.1~6.1.6)

ユニオン型

  • 例えばUser型はT型が入ることもあるし、U型が入ることもある
  • T | UでT型またはU型を表せる!いくつ書いてもOK
  • ・・ただ、User型にはどっちが入ってるか分からなくなる!
  • 存在しないプロパティにアクセスする可能性があるとエラーになる
type Animal = {
  name: string;
  species: string;
  age: string;
};
type Human = {
  name: string;
  age: number;
};
type Performer= Animal | Human;

const rappy: Performer = {
  name: "Rappy",
  species: "rabbit",
  age: "2",
}
const akira: Performer = {
  name: "Akira Kawashima",
  age: 43,
}

const gerSpecies = (performer: Performer): string => {
  // ここでエラーになる
  // プロパティ 'species' は型 'Performer' に存在しません。
  // プロパティ 'species' は型 'Human' に存在しません。
  return performer.species;
}
  • ちなみに上の例でageプロパティは「string | number」型!

インターセクション型(交差型)

  • T & UでT型であり、かつ!U型を表せる!こちらも複数書いてOK
  • こんな感じでtype T= U & {}やるとT型にU型が重複なしで結合されたがごとく!

オプショナルプロパティ再び

  • 復習!オプショナルなプロパティって型名?: 型これ!
  • こいつぁ必ずundefinedとのユニオン型になる
  • でも、型名?: 型型名: 型 | undefinedは意味が違うとな、、そうなの!?
  • 前者は値自体がなくてもオッケーだが、後者はないならundefined入れないとダメ
  • 型名?: 型は値を入れないことでundefinedを示せるってことだけど、ワンチャン書き忘れかもしれんし、型名: 型 | undefinedのように明示的に入れてあげた方が親切かも?

オプショナルチェイニング

  • プロパティアクセスの亜種、式を作る構文!
  • obj?.hogeみたいにできる。オブジェクトがnullやundefinedでもOKなのが特徴
  • これ入ってたらOKだけどundefinedなら処理しないよ、がif文書かずともカンタンに!
  • 関数呼び出し、メソッド呼び出しでも使える。?.()で処理があるときだけ実行できるのだ
    • とても便利だけど、es2020だと実行時エラーになった。調べると、es2018なら使えるみたい。フーム?
  • 一度?を書いたらそれ以降のプロパティアクセス!関数呼び出し!メソッド呼び出し!すべてすっ飛ばす!!だから、func?.().toStringなんて書いても問題ないぜ

■ 感想

知ってるようで知らなったユニオン型の挙動いろいろ…この本はほんとにわかりやすい!!

プロを目指す人のためのTypeScript入門 読書メモ⑧ 第5章(2)

■ 思ったこと

勉強は音楽聞くためにやってるとこもある。

■ 第5章 クラスの宣言と使用(5.2~5.6.4)

クラスの型

  • クラス宣言によって作られたオブジェクトは同時に型もできるわけだけど・・この型だって今できたのだ
  • なので、newしなくてもプロパティやメソッドが同じならクラス型で宣言できる。これができるのはクラス宣言だけ(式はダメってことさ)
  • ・・クラス作るなら式より宣言のほうがメリット多い!

名前空間

  • 名前空間とは、名前の「所属先」と「分類名」
  • const宣言は変数を作る構文、type文は型を作る構文、そしてクラス宣言はクラスオブジェクトとその型を同時に作る構文だ!
  • 変数名と型名で属する名前空間が異なる
  • そう思うと、クラス宣言は、変数名(クラス名)と型名(これもクラス名)を同時に作れるすごいやつだ
  • クラスはクラスオブジェクトが入った変数だってこと、忘れないでネ

instanceof 演算子

  • 復習!演算子は式を作る構文ね
  • 価 instanceof クラスオブジェクトで、その値がそのオブジェクトからインスタンス化されたものかを判断しbooleanで返す

implementsキーワード

  • class クラス名 implements 型{}で、今作ったクラスが型の部分型かチェックしてくれる
  • 書かなくてもエラーにはならないけどそれは例の型推論によるので、書いといたほうがいい。このクラスは部分型という意図も明確になるし!

例外処理

  • throwでエラーを発生させたら最後、そのブロック内の処理は強制終了し、外へ脱出を図りだす
    • 途中にcatchがあればそこで再開するけど、なければもう、クラッシュ!
    • このよーに、上から順とかもう関係なく別の場所に処理が移ることを大域脱出という
    • どこでエラーが起きても一つのとこに良くて感じかな
  • ちなみに、try-catchもいいけど、失敗を表す値を返して判断するのもアリよ
  • finallyに書いた処理は何が何でも実行される、catchがあればcatchのあと。必ず実行させたい処理とか書く感じかね

結局クラスは使うべきか?

  • カプセル化もできるし、メソッドたくさんあるときは向いている。
  • 実際どう使うかは君が確かめよう!

■ 感想

クラス、案件で結構使ったんだけどわりと特殊な条件下ではあった。なんかjavaみたいになってた!そして、電気グルーヴがANN55周年特番に登場ってマジ!?