(学習メモ)『サバイバルTypeScript』を学ぶPart1 〜静的型付け言語に触れる編〜

静的型付け言語を触ってみたいと思って、『サバイバルTypeScript』を初めてみました。

typescriptbook.jp

まずは「トップ」の章を見ただけですが、フロント/バックエンドの違いは当然あれど、普段使っているRubyとは全く違って面白かったです。
印象に残ったところをつらつらとメモしました。

構造的部分型

  • rubyで言うとhashのkeyが揃っていれば互換がある、みたいな感じ
type Summary = { name: string };
type Detail = { name: string; age: number };
 
const johnDetail: Detail = { name: "John", age: 28 };
const summary: Summary = johnDetail; // 代入できる。構造的部分型として互換があるため
 
const johnSummary: Summary = { name: "John" };
const detail: Detail = johnSummary; // 代入できない。構造的部分型として互換がない(ageを含まないため)

配列のループ

  • rubyではforは全然使わないけど、TypeScriptではどうなんだろう?
const numbers = [1, 2, 3];
 
for (const num of numbers) {
  console.log(num); // 1, 2, 3と出力される
}

タプル型

  • まさに静的型付け言語、というのを実感
let tuple: [string, number];
tuple = ["hello", 10]; // 代入できる
tuple = [10, "hello"]; // 順序が正しくないため、代入できない
tuple = ["hello", 10, "world"]; // 要素が多すぎるため代入できない

オブジェクトメソッド

  • 関数を持つオブジェクト
  • Rubyのハッシュに置き換えて考えると違和感があってとても面白い
const obj = {
  a: 1,
  b: 2,
  sum(): number {
    return this.a + this.b;
  },
};
console.log(obj.sum());

Shorthand property names

  • 便利〜となったが知らないと読めないだろうなーとも思ったのでメモ
const name = "John";
const age = 20;
const obj = { name, age };
console.log(obj);
//=> { name: 'John', age: 20 }

抽象クラス(abstract)

  • abstractを使った基底クラスではnewできない
  • Rubyではない機能で考えたことなかったが、確かにあってもいいよな、となった
abstract class Animal {
  abstract makeSound(): void;
 
  move(): void {
    console.log("roaming the earth...");
  }
}

ゲッターとセッター

  • get とか set を介してしか値の取得と変更をできないようにする
  • rubyは attr_xxx で設定し =で代入や .xxx で取得できるので、設計が結構違うんだなという気持ち

インターフェース

  • 少しだけ理解するのに時間がかかった
  • 基底クラスの考え方と似ている?と思ったけど
    • interfaceには実装がなく、約束がある
    • 基底クラスには実装があり、共通部分を提示する
    • ので、完全に別物か、となった
interface Printable {
  print(): void;
}
 
class MyClass implements Printable {
  print(): void {
    console.log("Hello, world!");
  }
}

ジェネリクス

  • <T>
  • 型を後から決められるようにする
// Tが型変数
function identity<T>(arg: T): T {
  return arg;
}
 
// 型変数Tにstringを割り当てる
const output1 = identity<string>("myString");
 
// 型変数Tにnumberを割り当てる
const output2 = identity<number>(100);

type importとtype export

  • 型だけimport/exportできるのは面白い

  • このほかにも PickとかOmitとか、Excludeとか、型情報付きのオブジェクトにする便利メソッドが豊富だなという印象