PR

TypeScript超入門:本当に最初の第一歩から

TypeScript

この記事では、プログラミング言語「TypeScript」の基本的な文法を、プログラミング自体が初めての方や、まだ慣れていない方にもわかるように、本当に基本的なところから順を追って解説します。

深堀りしていくと、深い話も尽きないのがどのプログラミング言語にも共通する特徴ですが、まずはその土台としての解説ページです!是非最後までご覧ください。

スポンサーリンク

プログラミングの超基本:「文」と「セミコロン」

どんなプログラミング言語にも共通しますが、プログラムはコンピューターに対する指示の集まりでできています。この1つ1つの指示のことを文 (Statement) と呼びます。

// これは「変数 message を宣言し、"Hello" という文字列を代入する」という一つの文
let message: string = "Hello";

// これも「変数 year を宣言し、2025 という数値を代入する」という別の一つの文
let year: number = 2025;

// これも「コンソールに message 変数の内容を表示する」という文
console.log(message);

プログラムは、これらの文が上から順に実行されることで動きます。

セミコロン ; の役割

多くのプログラミング言語では、文の終わりを明確にするためにセミコロン (;) を付けます。TypeScript(および元になったJavaScript)でも、文の終わりにはセミコロンを付けるのが基本的なルールです。

let greeting: string = "Good morning"; // 文の終わりにセミコロン
let count: number = 10;             // 文の終わりにセミコロン
console.log(greeting);             // 文の終わりにセミコロン

セミコロンは省略できる?

実は、TypeScript (JavaScript) では、多くの場合、行の終わりが文の終わりであると自動的に判断してくれるため、セミコロンを省略しても動くことがあります。

let city: string = "Tokyo" // セミコロンなしでもOK
let population: number = 14000000 // セミコロンなしでもOK
console.log(city)           // セミコロンなしでもOK

しかし、以下のような理由から、基本的にはセミコロンを付けることが推奨されています。

  1. 意図しない動作を防ぐ
    特定の状況では、セミコロンがないとコードが予期せぬ形で結合され、エラーやバグの原因になることがあります。
  2. コードの明確性
    文の終わりが明確になり、コードが読みやすくなります。
  3. チーム開発での一貫性
    複数人で開発する場合、セミコロンを付けるか付けないかのルールを統一しておくと、コードのスタイルが揃います。

この入門記事では、原則として文の終わりにはセミコロンを付けるようにします。

TypeScriptとは?

さて、本題のTypeScriptです。
TypeScriptは、Microsoftによって開発された、JavaScriptを拡張して作られたプログラミング言語です。一番大きな特徴は静的型付けができることです。

  • JavaScriptのスーパーセット
    TypeScriptはJavaScriptの機能をすべて含んでいます。つまり、JavaScriptを知っていれば、TypeScriptは比較的スムーズに学べます!
  • 静的型付け
    プログラムを実行する前に、データ(後述する「値」や「変数」)に「型」(種類)を指定することで、型の間違いを早期に発見できます。これがコードの品質を高め、開発を助けてくれます。

なぜ型が必要なの?

コンピューターは、「数値」と「文字列(文字の並び)」を区別します。
例えば、100 は数値、"100" は文字列です。JavaScriptでは、実行時に型が決まるため、意図せず数値と文字列を足し合わせてしまうようなミスが起こりえます(例: 1 + "0""10" になる)。TypeScriptでは、あらかじめ「これは数値だよ」「これは文字列だよ」と宣言することで、そのようなミスを防ぎます。

参考 「データ型」とは?

基本的な「値」と「型」

プログラムが扱うデータの基本的な単位を値 (Value) と呼びます。値には様々な種類があり、その種類のことを型 (Type) と言います。

TypeScriptでよく使う基本的な型を見ていきましょう。

  • string (文字列型)
    文字や文章を表す値の型です。ダブルクォーテーション " またはシングルクォーテーション ' で囲みます。
    • 値の例: "こんにちは", 'TypeScript', "123" (これは数値ではなく文字列)
  • number (数値型)
    整数や小数を表す値の型です。
    • 値の例: 100, 0, -5, 3.14
  • boolean (真偽値型)
    「正しい (true)」か「間違っている (false)」かの二択を表す値の型です。
    • 値の例: true, false
  • Array (配列型)
    同じ型の値を複数まとめて順番に格納する型です。角括弧 [] を使います。
    • 値の例: [1, 2, 3] (数値の配列), ["apple", "banana"] (文字列の配列)
  • null
    「何もない」ことを意図的に示す特殊な値。
  • undefined
    値が「未定義」であることを示す特殊な値。変数を宣言しただけで、まだ値を入れていない状態など。
  • any (任意型)
    どんな型の値でも入る特殊な型。便利ですが、TypeScriptの型チェックの恩恵を受けられなくなるため、使用は慎重に

値を覚えておく:「変数」

プログラミング 変数とは
図1:変数とは?

プログラムの中で、値を一時的に保存しておくための「名前付きの箱」のようなものが変数 (Variable) です。変数を使うことで、値に名前を付けて何度も利用したり、値を変更したりできます。

参考 プログラミングの変数とは?1分でわかりやすく

変数を使うには、まず宣言 (Declaration) が必要です。TypeScriptでは let または const を使って変数を宣言します。

  • let: 値を後から変更可能な変数を宣言します。
  • const: 値を後から変更不可能な(定数 Constant)変数を宣言します。基本的には const を使い、値の変更が必要な場合のみ let を使うのが良い習慣です。

宣言の際には、変数名の後に : (コロン) と型名を付けて、その変数にどんな型の値を入れるかを指定します(型注釈 Type Annotation)。そして = の後に、その変数に入れる最初の値(初期値)を書きます。

// string 型の変数 message を宣言し、初期値として "Hello, TypeScript!" を入れる
let message: string = "Hello, TypeScript!";

// number 型の定数 year を宣言し、初期値として 2025 を入れる
const year: number = 2025;

// boolean 型の変数 isActive を宣言し、初期値として true を入れる
let isActive: boolean = true;

// number 型の配列 scores を宣言
const scores: number[] = [80, 95, 72];

// message 変数の中身を "Hi!" に変更する (let なので変更可能)
message = "Hi!";

// year 変数の中身を変更しようとするとエラーになる (const なので変更不可)
// year = 2026; // エラー!

// 型が違う値を入れようとするとエラーになる
// message = 100; // エラー! message は string 型

型推論 (Type Inference)

多くの場合、TypeScriptは初期値から変数の型を自動的に推測してくれます。これを型推論と呼びます。型推論が可能な場合は、型注釈を省略できます。

let user = "Alice"; // 初期値が文字列なので string 型と推論される
const pi = 3.14;    // 初期値が数値なので number 型と推論される

// user = 123; // エラー! user は string 型と推論されている

値を作り出す:「式」

プログラムの中で、計算や処理を実行して最終的に一つの値になるもの式 (Expression) と呼びます。

  • 1 + 2 は、計算されて 3 という値になるので式です。
  • year (上で宣言した変数)は、その中に入っている 2025 という値になるので式です。
  • message は、その中に入っている "Hi!" という値になるので式です。
  • scores[0] は、配列 scores の最初の要素である 80 という値になるので式です。
  • isActive === true は、比較の結果 true または false という値になるので式です。

文と式の違い

  • 文 (Statement)
    コンピューターへの指示。何かを実行させる。
    例: let x = 10;, console.log("OK");
  • 式 (Expression)
    評価されると1つの値になるもの。
    例: 10, x, 10 + 5, x > 5

文の中に式が含まれていることがよくあります。例えば、let x = 10 + 5; という文には、10 + 5 という式が含まれています。この式が評価されて 15 という値になり、その値が変数 x に代入されます。

処理をまとめる:「関数」

一連の処理をまとめて名前を付け、繰り返し呼び出せるようにしたものが関数 (Function) です。関数を使うことで、同じようなコードを何度も書く手間が省け、プログラムが整理されます。

参考 プログラミングの「関数」とは?

関数を定義するには function キーワードを使います。関数には引数 (Argument/Parameter) を渡すことができ、処理の結果として戻り値 (Return Value) を返すことができます。

TypeScriptでは、関数の引数と戻り値にも型注釈を付けます。

// 関数宣言の基本形
// function 関数名(引数1: 型, 引数2: 型, ...): 戻り値の型 {
//   // 関数の処理
//   return 戻り値; // 戻り値がある場合
// }

// 二つの数値を受け取り、合計を返す関数
function add(a: number, b: number): number {
  const result: number = a + b; // a + b は式
  return result;             // result を戻り値として返す文
}

// 戻り値がない (何かを表示するだけなど) 関数の戻り値の型は `void`
function printMessage(message: string): void {
  console.log(message); // message を表示する文
  // return 文がない、または return; だけ
}

// 関数を呼び出す (実行する)
const sum: number = add(5, 3); // add関数を呼び出し、戻り値 (8) を変数 sum に代入する文
console.log(sum); // 出力: 8

printMessage("関数のテスト"); // printMessage関数を呼び出す文 (出力: 関数のテスト)

アロー関数

JavaScriptでお馴染みの、より簡潔に関数を書く方法であるアロー関数も使えます。

// アロー関数の基本形
// const 関数名 = (引数1: 型, 引数2: 型, ...): 戻り値の型 => {
//   // 関数の処理
//   return 戻り値;
// };

const multiply = (x: number, y: number): number => {
  return x * y;
};

const difference = (a: number, b: number): number => a - b; // 処理が1行で終わる場合は {} と return を省略可

const resultMultiply: number = multiply(4, 6); // 24
const resultDifference: number = difference(10, 7); // 3

console.log(resultMultiply);
console.log(resultDifference);

オブジェクトの形を決める:「インターフェース」

複数の値をまとめて、1つの意味のあるデータとして扱いたい場合があります。例えば、「ユーザー」を表すデータとして、ID、名前、メールアドレスなどをまとめたい、といった場合です。このようなデータのまとまりをオブジェクト (Object) と呼びます。

参考 Typescriptのオブジェクトとは?

インターフェース (Interface) は、オブジェクトがどのようなプロパティ(オブジェクト内の個々のデータのこと)を持つべきか、その「形」や「構造」を定義するための設計図のようなものです。

// User というインターフェース (設計図) を定義
interface User {
  id: number;     // id という名前のプロパティがあり、その型は number
  name: string;    // name という名前のプロパティがあり、その型は string
  isAdmin: boolean; // isAdmin という名前のプロパティがあり、その型は boolean
  email?: string; // ? を付けると、あってもなくても良いプロパティ (オプショナル)
}

// User インターフェースに従ったオブジェクトを作成
// このオブジェクトは User の設計図通りに作られている
let user1: User = {
  id: 1,
  name: "David",
  isAdmin: true,
  email: "david@example.com"
};

// email プロパティがなくても User インターフェースを満たす
let user2: User = {
  id: 2,
  name: "Eve",
  isAdmin: false
};

// インターフェースで定義されていないプロパティを持っていたり、
// 必須のプロパティがなかったりするとエラーになる
// let user3: User = { id: 3, username: "Frank" }; // エラー: nameがない、username は未定義

// 関数が User 型のオブジェクトを受け取ることを明示できる
function displayUserName(user: User): void {
  console.log(user.name);
}

displayUserName(user1); // 出力: David
displayUserName(user2); // 出力: Eve

インターフェースを使うことで、「このオブジェクトには必ず idnamenumber 型と string 型で存在する」といったルールを明確にでき、コードの安全性が高まります。

オブジェクトの設計図と機能:「クラス」

インターフェースがオブジェクトの「形」だけを定義するのに対し、クラス (Class) はオブジェクトの「形」(プロパティ)に加えて、そのオブジェクトが持つ「機能」(メソッド Method と呼ばれる関数)も一緒に定義できる、より高機能な設計図です。オブジェクト指向プログラミングの中心的な概念です。

class Product {
  // プロパティ (クラスが持つデータ)
  name: string;
  price: number;
  readonly id: number; // readonly: 一度設定したら変更できない

  // コンストラクタ: クラスからオブジェクトを生成するときに自動的に呼ばれる特殊なメソッド
  // プロパティの初期化などを行う
  constructor(id: number, name: string, price: number) {
    this.id = id; // this は生成されるオブジェクト自身を指す
    this.name = name;
    this.price = price;
    console.log(`商品「${this.name}」が生成されました。`);
  }

  // メソッド (クラスが持つ機能・関数)
  getPriceWithTax(taxRate: number): number {
    // 税込み価格を計算して返す
    return this.price * (1 + taxRate);
  }
}

// クラス (設計図) から実際のオブジェクト (インスタンス) を生成する
const productA = new Product(101, "高機能マウス", 5000); // コンストラクタが呼ばれる
const productB = new Product(102, "キーボード", 8000);

// オブジェクトのプロパティにアクセス
console.log(productA.name); // 出力: 高機能マウス
console.log(productB.price); // 出力: 8000

// オブジェクトのメソッドを呼び出す
const priceAWithTax = productA.getPriceWithTax(0.1); // 税率10%
console.log(`商品Aの税込価格: ${priceAWithTax}円`); // 出力: 商品Aの税込価格: 5500円

// readonly なプロパティは変更できない
// productA.id = 200; // エラー!

クラスを使うと、関連するデータ(プロパティ)と処理(メソッド)をひとまとめにして管理できるため、複雑なプログラムを構造化しやすくなります。

型に別名を付ける:「型エイリアス」

複雑な型や、何度も使う型に、分かりやすい別名を付けることができるのが型エイリアス (Type Alias) です。type キーワードを使って定義します。

// 文字列リテラルの組み合わせに 'Status' という別名を付ける
type Status = "pending" | "processing" | "completed" | "failed";
// Status 型の変数は、上記4つの文字列のどれかしか受け付けない

let orderStatus: Status = "processing";
console.log(orderStatus);

orderStatus = "completed";
// orderStatus = "shipped"; // エラー! Status 型には 'shipped' は含まれない

// オブジェクトの型にも別名を付けられる (インターフェースと似ている)
type Point = {
  x: number;
  y: number;
};

function distance(p1: Point, p2: Point): number {
  const dx = p1.x - p2.x;
  const dy = p1.y - p2.y;
  return Math.sqrt(dx * dx + dy * dy); // Math.sqrt は平方根を計算する組み込み関数
}

const point1: Point = { x: 0, y: 0 };
const point2: Point = { x: 3, y: 4 };
console.log(distance(point1, point2)); // 出力: 5

// 関数型に別名を付ける
type StringFormatter = (input: string) => string;

const toUpperCase: StringFormatter = (str) => str.toUpperCase();
const addGreeting: StringFormatter = (str) => `Hello, ${str}!`;

console.log(toUpperCase("test")); // 出力: TEST
console.log(addGreeting("World")); // 出力: Hello, World!

型エイリアスを使うと、コードが読みやすく、意図が伝わりやすくなります。

型を引数にする:「ジェネリクス」

ジェネリクス (Generics) は、関数やクラスを定義するときに、そこで使われる型を固定せず、後から指定できるようにする仕組みです。型をまるで関数の引数のように扱えます。これにより、様々な型に対応できる、再利用性の高いコードを書くことができます。

// この関数は、呼び出すときに指定された型 T の配列を受け取り、
// その型の要素を返す(もし配列が空なら undefined を返す)
function getFirstItem<T>(items: T[]): T | undefined {
  // T は型引数と呼ばれる。呼び出し時に具体的な型が決まる。
  return items.length > 0 ? items[0] : undefined;
}

// number 型を指定して呼び出す
const numbers: number[] = [10, 20, 30];
const firstNum: number | undefined = getFirstItem<number>(numbers);
console.log(firstNum); // 出力: 10

// string 型を指定して呼び出す
const colors: string[] = ["red", "green", "blue"];
const firstColor: string | undefined = getFirstItem<string>(colors);
console.log(firstColor); // 出力: red

// 型を省略すると、TypeScriptが推論してくれる場合もある
const flags = [true, false, true];
const firstFlag = getFirstItem(flags); // boolean 型だと推論される
console.log(firstFlag); // 出力: true

// 空の配列の場合
const emptyArray: any[] = [];
const firstEmpty = getFirstItem(emptyArray);
console.log(firstEmpty); // 出力: undefined

ジェネリクスは少し高度な概念ですが、ライブラリなどでは頻繁に使われているため、覚えておくと役立ちます。

コードの説明書き:「コメント」

コードの中に、プログラムの動作には影響しない説明文を書き残すことができます。これをコメントと呼びます。後で自分が見返したときや、他の人がコードを読むときに、処理内容を理解しやすくするために使います。

TypeScript (JavaScript) では、コメントの書き方は主に2種類あります。

  • 一行コメント: // から行末までがコメントになります。 TypeScript// これは一行コメントです let price: number = 100; // 税抜き価格
  • 複数行コメント: /**/ で囲まれた範囲がコメントになります。 TypeScript/* これは複数行コメントです。 複数行にわたって説明を記述できます。 関数やクラスの説明などによく使われます。 */ function calculateTotal(price: number, quantity: number): number { // 消費税率 (10%) const taxRate = 0.1; const subTotal = price * quantity; const tax = subTotal * taxRate; return subTotal + tax; // 合計金額を返す }

適切なコメントは、コードの可読性を大きく向上させます。

まとめ

今回は、プログラミングの本当に基本的な「文」や「値」から始まり、TypeScriptのコアとなる「型」「変数」「関数」「インターフェース」「クラス」などの概念を駆け足で見てきました。

  • プログラムはの集まり。文末にはセミコロン ; を付けるのが基本。
  • データにはがあり、その種類が
  • 値を保存するのが変数 (let, const)。型注釈と型推論がある。
  • 値を生成するのが
  • 処理をまとめるのが関数。引数と戻り値に型を付ける。
  • オブジェクトの形を定義するのがインターフェース
  • 形と機能を定義するのがクラス
  • 型に別名を付けるのが型エイリアス
  • 型を柔軟に扱うのがジェネリクス
  • コードの説明はコメントで。

TypeScriptは、JavaScriptに「型」という強力な武器を与えてくれます。最初は覚えることが多く感じるかもしれませんが、型があることでエラーが減り、コードが読みやすくなり、安心して開発を進められるようになります。

ぜひ、ご自身の環境でTypeScriptをセットアップして、実際にコードを書いて動かしてみてください。公式ドキュメントや様々なチュートリアルも素晴らしい学習リソースです。

タイトルとURLをコピーしました