SEの部屋

変数の型について

変数の型について

TypeScriptは、JavaScriptに型情報を加えた静的型付け言語です。静的型付け言語とは、変数や関数などの型が実行前に静的にチェックされる言語のことで、コンパイル時にエラーが検出されるため、実行時エラーを事前に防止することができます。
TypeScriptには、いくつかの基本型が用意されており、これらの型を使用して、プリミティブ型(文字列、数値、真偽値など)や、オブジェクト型(配列、タプル、クラスなど)を表現することができます。また、型エイリアスやジェネリック型などの高度な型機能も備えています。

TypeScriptの型には、以下のような特徴があります。

  • 明確な型付け

TypeScriptでは、変数や関数などの型を宣言することが必要です。これにより、コードの可読性が向上し、開発効率も高まります。

  • 安全なリファクタリング

TypeScriptでは、変数や関数などの名前を変更する際に、型情報も同時に変更されるため、リファクタリングが安全に行えます。

  • エラー検出

TypeScriptは静的型付け言語であるため、コンパイル時に型エラーを検出することができます。これにより、実行時エラーを防止することができます。

  • 自己文書化型

TypeScriptの型は、ドキュメントとしての役割も果たします。型を見れば、その変数や関数がどのような型を受け取り、どのような型を返すかを理解することができます。

  • コードの品質向上

TypeScriptの型を使用することで、コードの品質を向上させることができます。例えば、タイプミスによるバグや、予期せぬ挙動を防止することができます。

TypeScriptの型を理解することで、コードの品質を向上させ、開発効率を高めることができます。

型の種類と詳細

any型

TypeScriptのany型は、任意の型を表す特殊な型です。any型は、コンパイル時に型チェックを行わず、実行時に動的に型が決まるため、型の安全性を犠牲にして柔軟性を高めることができます。つまり、any型を使うと、どのような値でも代入することができます。

let anyValue: any;
anyValue = 1;
anyValue = 'string';
anyValue = { a: 1, b: 'string' };

上記のコードでは、anyValueという変数に、number型、string型、オブジェクトリテラル型を代入しています。

any型は、JavaScriptの動的な性質を反映しており、TypeScriptをJavaScriptの拡張として使う場合に役立ちます。しかし、any型は型の安全性を失うため、できる限り使用を避け、型を明示的に指定することが望ましいです。なぜなら、any型を使用すると、コードが予期しない方法で動作する可能性があるため、バグを引き起こす原因になります。

また、TypeScriptにはunknown型という、any型よりも型の安全性が高い型があります。unknown型は、any型と同様に任意の型を表すことができますが、使用する前に型のチェックが必要なため、より型安全なコードを書くことができます。

number型

TypeScriptのnumber型は、数値を表すための型です。number型には、整数、浮動小数点数などの数値が含まれます。

let integer: number = 10;
let floatingPoint: number = 3.14;

上記のコードでは、integerという変数に10という整数値を代入し、floatingPointという変数に3.14という浮動小数点数を代入しています。
number型は、算術演算子(+, -, *, /)や比較演算子(>, <, >=, <=)などの演算子を使って、数値の計算を行うことができます。

let num1: number = 10;
let num2: number = 5;
let sum: number = num1 + num2;
let difference: number = num1 - num2;
let product: number = num1 * num2;
let quotient: number = num1 / num2;
let greater: boolean = num1 > num2;

上記のコードでは、num1num2という2つのnumber型の変数を定義し、sumdifferenceproductquotientgreaterという変数にそれぞれ演算の結果を代入しています。greaternum1num2よりも大きいかどうかを判定するために、boolean型で定義しています。

なお、TypeScriptのnumber型には、特別な値としてNaN(Not a Number)があります。NaNは数値として不正な値を表します。また、Infinity-Infinityという無限大の値も表すことができます。これらの値は、浮動小数点数の計算において、特別な値として扱われます。

string型

TypeScriptのstring型は、文字列を表すための型です。string型には、一連の文字列を表すための値が含まれます。

let hello: string = "Hello";
let world: string = "world";
let message: string = hello + " " + world + "!";

上記のコードでは、helloworldという2つのstring型の変数を定義し、messageという変数にhelloworldを結合した文字列を代入しています。
string型は、文字列を操作するためのメソッドやプロパティを提供します。代表的なものは以下の通りです。

  • lengthプロパティ

文字列の長さを返します。

  • charAt()メソッド

指定された位置にある文字を返します。

  • slice()メソッド

指定された位置から始まる一部の文字列を返します。

  • toUpperCase()メソッド

文字列を大文字に変換します。

  • toLowerCase()メソッド

文字列を小文字に変換します。

let myString: string = "hello world";
let length: number = myString.length; // 11
let firstChar: string = myString.charAt(0); // "h"
let substring: string = myString.slice(0, 5); // "hello"
let upperCase: string = myString.toUpperCase(); // "HELLO WORLD"
let lowerCase: string = myString.toLowerCase(); // "hello world"

上記のコードでは、myStringという変数にhello worldという文字列を代入し、それぞれのプロパティやメソッドを使って文字列を操作しています。
なお、TypeScriptのstring型は、number型やboolean型と同様にプリミティブ型の一種です。したがって、文字列を操作するための便利なメソッドを提供している一方で、文字列の操作を誤ることによって、意図しない動作を引き起こす可能性もあるため、注意が必要です。

boolean型

TypeScriptのboolean型は、真偽値(true/false)を表すための型です。boolean型には、trueまたはfalseの値が含まれます。

let isTrue: boolean = true;
let isFalse: boolean = false;

上記のコードでは、isTrueという変数にtrueという真偽値を代入し、isFalseという変数にfalseという真偽値を代入しています。

boolean型は、論理演算子(&&, ||, !)や比較演算子(==, !=, ===, !==, >, <, >=, <=)などの演算子を使って、真偽値の評価を行うことができます。

let num1: number = 10;
let num2: number = 5;
let isGreater: boolean = num1 > num2; // true
let isEqual: boolean = num1 == num2; // false
let notEqual: boolean = num1 != num2; // true
let logicalAnd: boolean = isGreater && notEqual; // true
let logicalOr: boolean = isGreater || notEqual; // true
let logicalNot: boolean = !isGreater; // false

上記のコードでは、num1num2という2つのnumber型の変数を定義し、それぞれの演算子を使って真偽値を評価しています。isGreaternum1num2よりも大きいかどうかを判定するために、boolean型で定義しています。
また、boolean型は、条件分岐の制御構文(if文、switch文)でよく使われます。

if (isGreater) {
  console.log("num1 is greater than num2");
} else {
  console.log("num1 is less than or equal to num2");
}

上記のコードでは、isGreatertrueの場合には、num1 is greater than num2という文言が出力されます。それ以外の場合には、num1 is less than or equal to num2という文言が出力されます。

なお、TypeScriptのboolean型は、プリミティブ型の一種であり、真偽値以外の値(例えば、nullundefined)を代入することはできません。

void型

TypeScriptのvoid型は、値が存在しないことを示す型です。つまり、void型の変数や関数は、戻り値を返さないことを示します。

function greet(name: string): void {
  console.log(`Hello, ${name}!`);
}

let result: void = greet("John"); // 戻り値はなし

上記のコードでは、greetという関数を定義しています。この関数は、引数としてnameという文字列を受け取り、その文字列を使ってHello, ${name}!というメッセージを表示する処理を行います。この関数の戻り値の型はvoid型です。

また、greet関数を呼び出すと、戻り値としてundefinedが返されます。これは、void型の変数が値を持たないことを示すための値です。
void型は、主に関数の戻り値として使われます。関数が値を返す必要がない場合、void型を指定することで、戻り値がないことを明示的に示すことができます。

function showMessage(): void {
  console.log("This is a message.");
}
showMessage(); // "This is a message."が表示される

上記のコードでは、showMessageという関数を定義しています。この関数は、戻り値として何も返さず、"This is a message."というメッセージを表示する処理を行います。
また、void型は、オブジェクトのプロパティとしても使われます。プロパティの値が存在しない場合に、そのプロパティの型としてvoid型を指定することができます。

let obj: { property: void } = { property: undefined };

上記のコードでは、objという変数を定義して、そのプロパティpropertyの型としてvoid型を指定しています。プロパティの値としてはundefinedを代入しています。

null型およびundefined型

TypeScriptにおいて、null型とundefined型は、それぞれnullundefinedの2つの特別な値を表す型です。
null型は、変数やプロパティが値を持たないことを示す型です。nullは、値が明示的に指定されていないことを表します。一方、undefined型は、値が未定義であることを示す型です。undefinedは、値がまだ代入されていない変数やプロパティの初期値として使用されます。

let myVar: string | null = null;
let myNum: number | undefined;

console.log(myVar); // nullが表示される
console.log(myNum); // undefinedが表示される

上記のコードでは、myVarという変数をstring | null型で宣言し、nullを代入しています。また、myNumという変数をnumber | undefined型で宣言しています。この場合、値がまだ代入されていないため、undefinedが自動的に割り当てられます。
また、null型とundefined型は、オプショナルな引数やプロパティの型としても使用されます。オプショナルな引数やプロパティは、値が必要な場合は引数やプロパティを渡し、不要な場合は省略することができます。オプショナルな引数やプロパティは、?を末尾に付けて宣言します。

function printMessage(message: string, times?: number): void { 
    if (times) { 
        for (let i = 0; i < times; i++) {
             console.log(message); 
          }  
       } else { 
            console.log(message); 
        }
}
printMessage("Hello, world!"); // "Hello, world!"が1回表示される 
printMessage("Hello, TypeScript!", 3); // "Hello,TypeScript!"が3回表示される

上記のコードでは、printMessageという関数を定義しています。この関数は、messageという必須の引数を受け取り、timesというオプショナルな引数を受け取ることができます。times引数が渡された場合は、messagetimes回表示します。times引数が省略された場合は、messageを1回だけ表示します。
以上が、null型とundefined型の基本的な使い方についての説明です。これらの型は、JavaScriptの実行時エラーを減らし、コードの信頼性を向上させるために重要な役割を果たします。


never型

TypeScriptにおけるnever型は、関数が正常に終了しない場合や、値が取得できないことを示す型です。never型は、通常、例外が発生したり、無限ループに陥ったりするような状況で使用されます。
具体的には、以下のような場合にnever型が使用されます。

  1. 関数が例外をスローする場合
  2. 関数が無限ループに陥る場合
  3. 関数が常に例外をスローする場合
  4. 型の結合に失敗する場合

以下に、それぞれの場合について説明します。

1. 関数が例外をスローする場合

function throwError(): never {
  throw new Error("error occurred");
}


2. 関数が無限ループに陥る場合

function infiniteLoop(): never {
  while (true) {}
}

上記の例では、infiniteLoopという関数があります。この関数は、never型を返します。infiniteLoop関数は、常にwhileループ内にあるため、処理が終了しなくなります。このような場合、never型が使用されます。

3. 関数が常に例外をスローする場合

function fail(message: string): never {
  throw new Error(message);
}

上記の例では、failという関数があります。この関数は、never型を返します。fail関数は、messageを引数として受け取り、Errorオブジェクトをスローするため、常に例外が発生します。このような場合、never型が使用されます。

4. 型の結合に失敗する場合

function unreachable(): never {
  return 2;
}

上記の例では、unreachableという関数があります。この関数は、never型を返します。unreachable関数は、数値型の値2を返そうとしていますが、never型が返されるため、実行されません。

以上が、never型の基本的な使い方についての説明です。never型は、例外や無限ループなど、プログラムのエラーを表現する際に非常に便利な型です。