Skip to content
sumnail

型システムの基本を抑える

created at : 2024/05/24

TypeScript

TypeScriptの型システムを体形立てて理解するため、学び直したいと思います。

型システムを理解するメリットとしては、以下のことが考えられます。

  • 型安全性
    型を使用することでコード内の変数や関数が制御されます。
    型が違うことをいち早く気づけるので、バグを未然に防ぐことが出来ます。

  • ドキュメント、自己文書化
    関数の引数や戻り値の型を明示的に示すことで、他の開発者もコードが読みやすくなります。

  • リファクタリング
    型を使用することでリファクタリングでバグを仕込むことを防げます。

これ以外にもメリットを感じる部分は多いと思います。

型推論

TypeScriptにおいては変数や関数の型を明示的に宣言せずとも、自動的に型を推論することができます。これを型推論と呼びます。

型推論の基本

  • 変数の初期値から推論できる
  • 関数の戻り値から推論できる
  • オブジェクトの形状や、使い方も推論できる

サンプルコード

ts

// 変数の初期値から型を推論
let lastName = "taro"; // lastName: string
let age = 30; // age: number

// OK
lastName.length;

// NG lengthはnumber型なので、関数として()が使えない
// Error Message >>
// This expression is not callable. Type 'Number' has no call signatures.ts(2349)
lastName.length();

// 関数の戻り値から推論
function greet() {
    return "Hello, TypeScript!";
}
// greeting: string
const greeting = greet();
  
// 配列やオブジェクトの要素から推論
// person: { name: string, age: number }
const person = {
    name: "Bob",
    age: 25,
}; 

// fruits: string[]
const fruits = ["apple", "banana", "orange"];

割り当て可能性

変数に再代入する場面でも、TypeScriptは型が同じかチェックします。
期待される使われ方をしているかチェックすることを割り当て可能性と呼びます。

INFO

型エラーで良く遭遇するので、エラー内容を理解することも大切です。

サンプルコード

ts
let firstName = "suzuki";
// OK 文字列を再度代入しても、問題ない
firstName = "sato"

// NG 文字列以外を代入しようとすると、エラー
// Error Message >> 
// Type 'boolean' is not assignable to type 'string'.ts(2322)
firstName = true

型アノテーション

変数名だけを定義する場面など、初期値を持っていない変数は型を読み取れないことがあります。 TypeScriptは、変数の使われ方をみて型を理解してくれません。デフォルトではanyと理解されます。

サンプルコード

ts
// 初期値を設定せずに、変数の型を定義 >> any(何でもOK)
let code;

code = "foo";
code.toUpperCase();

code = 1;
code.toPrecision(1);

code.toUpperCase(); // any なのでエラーが出ない

// string
let itemName: string;

let cameraName: string = "Canon";
// >> 冗長(定義しないでも分かる)-> 型アノテーションによって何も変わらないなら付けない?
// 役立つ場合もある...

プロパティ

オブジェクトの持つプロパティがあるかもチェックできます。

サンプルコード

ts
let myFruits = {
    apple: 1,
    banana: 3,
    orange: 3
}

myFruits.grape;
// Error Message >> Property 'grape' does not exist on type 
// '{ apple: number; banana: number; orange: number; }'.ts(2339)