静的型付け言語を触ってみたいと思って、『サバイバルTypeScript』を初めてみました。
まずは「トップ」の章を見ただけですが、フロント/バックエンドの違いは当然あれど、普段使っている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とか、型情報付きのオブジェクトにする便利メソッドが豊富だなという印象