初心者向けTypeScript入門 現役エンジニアが解説します!【基礎文法】

記事サムネイル

あなたはTypeScriptを知っていますか?
この記事は「TypeScriptをやってみたいけど初心者」「TypeScriptを聞いたことはあるけど文法は分からない」という方に向けて
読んでいただきたい記事になっています。
前提としてJavaScriptの知識はある程度ある方向けになっています。
この記事を読み終えるとTypeScriptの雰囲気や基礎文法は一通り知った状態になるでしょう。

この記事のポイント

  • TypeScriptの基本概念が分かる
  • 具体的なコード例で基礎文法が分かる
  • どのように使うのかが分かる
  • JSについては触れず、理解している前提でTypeScriptを解説

TypeScriptとは?

TypeScriptは、Microsoftが2012年に開発したJavaScriptのスーパーセットです。スーパーセットとは、元の言語との互換性を保ちつつ元の言語を拡張して作った言語のことです。
JavaScriptに型付けを加えたもので、静的型付けやクラスベースのオブジェクト指向プログラミングをサポートしています。
そもそも、JavaScriptは、Web開発において広く使用されているプログラミング言語です。
しかし、規模が大きくなるとコードの管理や保守が難しくなることがあります。そんな課題を解決するために登場したのがTypeScriptです。
つまり、JavaScriptのコードはすべてTypeScriptとしてあつかえます。
実際にTypeScriptのコードを実行する際はJavaScriptに変換(コンパイル)されて、そのコンパイルされたJavaScriptが実行されます。

  • JavaScriptのスーパーセットとなるプログラミング言語。
  • 静的型付け言語であり、プログラムの正しさが静的に検査できる。
  • ライブラリやIDEなどの開発環境が充実しており、大きなエコシステムを持っている。
  • Microsoftが2012年に開発し、オープンソースで公開した。

(https://typescriptbook.jpより引用)

詳細は別の記事で解説していますので、よろしければ併せてご覧ください。

TypeScriptとは何?将来性やJavaScriptとの違いについて解説します!

TypeScriptは稼げる、TypeScriptがトレンドと聞いたけれど、「TypeScriptとは何か分かっていない..」「どうやってTypeScriptの勉強を始めればいいか分からない... 」と悩…

型チェックの仕組み

型注釈(型アノテーション)

型を明示的に書くことを型注釈と言います。TypeScriptでは、型注釈を手がかりに検査が行われます。

const message1: string = "Hello, TypeScript"; //OK
const message2: string = 1; //エラー

型推論

見た目的にはJavaScriptと同じ記法です。しかし、TypeScriptでは文脈から自動で型を判断してくれます。
TypeScript対応のコードエディタ上で変数の上にカーソールをホバーすると、推論された型が表示されます。
型推論を利用することで、コードの記述量を減らすことができます。
型注釈で明示的に型を書くという考えも問題ないですが、コードが増えると型記述の負担も増えます。
もし型推論が間違えている場合には、開発者が型注釈や他の方法で正しい型を書き、TypeScriptへ伝える必要があります。

const message1:string = "Hello,"; 
const message2:string = "TypeScript"; //ここは型注釈

const message3 = message1 + message2 //型推論が効き、message3:stringと判断される

コンパイル

TypeScriptはそのままでは実行できません。実行可能なJavaScriptへ変換する必要があり、この変換のことをコンパイルと呼びます。
変換後のファイルはただのJavaScriptファイルなので、通常と同じく対応している環境で実行できます。

TypeScriptによる型チェックはこのコンパイルのタイミングで行われます。
つまり、コンパイル時にJavaScriptへの変換と型チェックを行っているということです。

コンパイルの方法

ご自身の環境で動かしたい場合は、この方法をお試しください。
一般的にはTypeScriptのコンパイラを使いコンパイルします。TypeScriptはtscコマンドを提供しています。
他にはwebpackやviteなど外部のビルドツールを使う方法もあります。
詳細は公式ドキュメントなどを参照してください。(TypeScript公式:https://www.typescriptlang.org/)

まず、Node.jsとnpm(Node Package Manager)がインストールされていることを確認します。
node -v (node --version)コマンドをターミナルなど実行し、バージョンが表示されればOKです。
npm (node package manager)はnodeをインストールすると同梱されています。
バージョンが表示されない場合は、nodeをインストールしてください。

node -v
npm -v

次に、TypeScriptとTypeScriptコンパイラをインストールします。(-gはPC全体のパッケージとしてインストールするという意味ですが、今はあまり気にしなくてOKです。)
TypeScriptをインストールするとtsc (TypeScript Compiler)が同梱されています。
今回はこのtscを使って、TypeScriptを実行可能なJavaScriptファイルへ変換します。

npm install -g typescript

tsc -v

新しいプロジェクトを作成し、tsc --initコマンドでTypeScriptの設定ファイル(tsconfig.json)を生成します。

mkdir my-ts-project
cd my-ts-project
tsc --init

.tsファイルを作成し、TypeScriptコードを書いてみましょう。

let message: string = "Hello, TypeScript!";
console.log(message);

その後、コンパイルしてJavaScriptに変換します。

tsc

これにより、デフォルト設定だとdistフォルダにJavaScriptファイルが生成されます。エラーがあればコンパイルエラーがターミナル上で出力されます。

基本的な型

ここではTypeScriptを使う際の型について紹介します。

プリミティブ型

  • boolean: 真偽値
  • number: 数値
  • string: 文字列
  • undefined: 値が定義されていない状態
  • null: 値が存在しない状態
  • bigint: 大きな整数
  • symbol: 一意(ユニーク)な値
const isOpen:boolean = false; 
const age:number = 20; 
const message:string = "TypeScript";
const notDefined: undefined = undefined;
const empty: null = null;
const bigNum: bigint = 100n;
const uniqueSymbol: symbol = Symbol("unique");

特殊な型

  • any: 何でも代入できる型。どうしようもない場合に最終手段として使用することを推奨。型チェックによるTypeScriptのメリットが弱まる。
  • unknown: any型と似て、何でも代入できる型。しかしunknownは、操作が制限されるため、anyと異なり型の安全性が保たれる。
  • void: 値が存在しないことを示す。関数が何も返さない場合に使用する。
  • never: 決して何も返さないことを示す。エラーを投げる関数や無限ループの関数の戻り値として使用する。
const a: any = 10; // 代入できる
console.log(a * 2); // 操作もできる
300
 
const b: unknown = 100; // 代入はできる

console.log(b * 3); // 型を絞り込むまで操作はできない 'b' is of type 'unknown'.
const c: number = b; // 不明な型なのでこのままでは代入もできない
 
// 戻り値のない関数
function doSomething(): void {}
 
// 戻り値を返すことがありえない関数、 neverを明示的に書かない場合、型推論によってvoidと判断される
function throwError(): never {
  throw new Error();
}

型エイリアス

定義した型に名前をつけられる機能です。型への参照を入れる変数という認識だとイメージしやすいと思います。
これを利用することで再利用性や可読性が高まります。

type Fruits="Apple" | "Peach"
let value:Fruits

value="Apple" //OK
value="PineApple" //エラー

オブジェクトの型

TypeScriptではオブジェクトの型も定義できます。
通常の書き方は以下です。

let john: {name:string; age:number} = {
  name: "John",
  age: 20
};

型を再利用することもできます。
方法は主に2つあり、上で紹介した型エイリアスを使う方法とインターフェースを使う方法です。
インターフェースとの細かい違いはいくつかあり、どちらを使うかは個人の考え方やプロジェクト方針によって意見が分かれます。
初心者のうちはどちらかを使えれば良いと思います。

//インターフェース
interface Person1 {
  name: string;
  age: number;
}

let john: Person = {
  name: "John",
  age: 20
};


//タイプ
type Person2 = {
  name: string;
  id:string;
}

let kevin: Person2 = {
  name: "John",
  id:"1"
};

読み取り専用オブジェクト

オブジェクトの値の書き換えを制限したい場合は、いくつかの記法が使えます。
readonlyas const(const アサーション)Readonlyユーティリティ型が使えます。
動作の違いなど若干ありますが、ここでは深掘りはしません。
初心者のうちは、必要に応じてどれかを使えれば問題ないと思います。

  • readonly:つけたプロパティ値の書き換えを制限する
  • as const:つけたオブジェクト全体の書き換えを制限する
  • Readonlyユーティリティ型:オブジェクト全体の書き換えを制限する
// readonly、一部値が固定される
const john: {
  readonly name: string; //nameは書き換えられなくなる
  age: number;
} = {
  name: "John",
  age: 30
};

// as const、オブジェクト全体の値が固定される
const kevin = {
  name: "Kevin",
  age: 30
} as const;

// Readonlyユーティリティ型、オブジェクト全体の値が固定される
let person: Readonly<{
  name: string;
  age: number;
}>;

オプションプロパティ

オブジェクトの値をオプショナルにしたい場合は、オプションプロパティ(?)を使います。
全ての値をオプショナルにしたい場合は、こちらの方法で全てに?をつけるか、ユーティリティ型のPartialを使います。

let obj1: { name: string; age?: number };
obj1 = { name: "John" }; // `age`プロパティがなくてもエラーにならない


// Partialで全てをオプショナルに
let obj2: Partial<{ name: string; age: number }>;
obj2 = {}; // どちらのプロパティもオプショナルになるため、エラーにならない

配列

配列の型の定義には、2種類の記法があります。

//パターン1
let numbers1:number[]

//パターン2
let numbers2:Array<string>

読み取り専用配列

配列の値の書き換えを制限したい場合も、2種類の記法が使えます。
つまり、読み取り専用の配列になります。

const numbers1: readonly number[] = [1, 2]; //readonlyをつける
const numbers2: ReadonlyArray<number> = [1,2]; //ReadonlyArrayを使う
 
numbers1[0] = 4; // 値を変更できない
numbers2.push(3); // 要素を追加できない

タプル型

固定された数の要素と、要素の型を指定できる特殊な配列です。
タプル型を使用することで、配列の要素数と要素の型を固定できます。これは、特定の構造を持つデータを扱う際に非常に便利です。

タプル型を定義するには、各要素の型を指定して配列を定義します。以下の例では、person というタプル型の変数を定義しています。

let person: [string, number];

person = ["Alice", 25]; // OK


person = [25, 20]; // エラー: 'number' 型は 'string' 型に割り当てられません
person = ["Alice"]; // エラー: タプル型 '[string, number]' の長さは '2' ですが、値の長さは '1' です。

ユニオン型(合併型)

これは変数が複数の異なる型のいずれかになることを指定するために使用されます。
ユニオン型は、パイプ (|) 記号を使って定義します。これにより、変数がいくつかの型のいずれかを取ることを許可します。

以下の例では、value という変数が string 型または number 型のいずれかを取ることができるようにしています。

let value: string | number;

value = "Hello"; // OK
value = 42; // OK
value = true; // エラー: 'boolean' 型は 'string | number' 型に割り当てられません

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

これは複数の型を組み合わせて、一つの型にするために使用されます。
インターセクション型は、アンパサンド (&) 記号を使って定義します。これにより、変数がすべての組み合わせた型のプロパティを持つことを要求します。

以下の例では、PersonEmployee という2つの型を組み合わせて、新しい型 PersonEmployee を作成します。

interface Person {
  name: string;
  age: number;
}

interface Employee {
  employeeId: number;
}

type PersonEmployee = Person & Employee;

let personEmployee1: PersonEmployee = {
  name: "John",
  age: 30,
  employeeId: 1234
};

型アサーション(型キャスト)

これはTypeScriptの型推論を上書きする機能です。型推論は優秀ですが、推論よりも開発者の方が正確な型を理解している場合があります。
そのような場合に推論された型を型キャストを使い、より正確な型をTypeScriptに知らせることができます。
ただし、number型のみの変数の型をstring型に型キャストするなど、制限のない上書きはエラーになるためできません。

型アサーションの書き方は2つあります。

let someValue: string | number = "this is a string";

// as構文、こちらがよく使われる
let strLength2: number = (someValue as string).length;
console.log(strLength2); // 16

// アングルブラケット構文
let strLength1: number = (<string>someValue).length;
console.log(strLength1); // 16

関数

関数の引数や戻り値の型を指定することで、誤った使い方を防ぎます。

function greet(name: string): string {
  return `Hello, ${name}`;
}

console.log(greet("Alice")); // Hello, Alice


//オプション引数も使える
function greet2(name?: string): string { //「?」を付けるとオプション引数になる
  if(name){
   return `Hello, ${name}`;
  }
  return `Hello, everyone!`;
}
console.log(greet2()); // エラーにならない  Hello, everyone!

クラス

TypeScriptは、クラスもサポートしています。
深掘りすると長くなるため今回は触れません。

class Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  speak(): void {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak(): void {
    console.log(`${this.name} barks.`);
  }
}

let dog = new Dog("Rex");
dog.speak(); // Rex barks.

発展:ジェネリクス

ジェネリクスは、型を引数のように扱うことができる機能で、TypeScriptの強力な特徴の一つです。
ジェネリクスを使用することで、再利用可能で型安全なコードを記述することができます。
これは入門としては範囲を超えると思うので、深掘りはしません。よろしければ調べてみてください。

function identity<T>(arg: T): T {
  return arg;
}

let output1 = identity<string>("Hello, TypeScript");
let output2 = identity<number>(42);

console.log(output1); // Hello, TypeScript
console.log(output2); // 42

まとめ

いかがでしたでしょうか?
TypeScriptは、JavaScriptのスーパーセットとして、静的型付けやオブジェクト指向プログラミングのサポートを提供する強力なプログラミング言語です。
広いコミュニティと大手企業の支持を受けて、急速に普及しています。
TypeScriptを学習し、より安全で保守性の高いコードを記述し、開発効率を向上させていきましょう。

CodeVilageでは無料カウンセリングを実施しております!

まずはお気軽に無料カウンセリングへご参加ください!
「興味はあるけど、自分にできるか不安...」
「どんなキャリアを描けばいいのか分からない...」
そんなあなたのために!!
何でも相談できる無料カウンセリングを実施しています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です