TypeScript | 基礎文法:オブジェクト基礎 – interface の基本

TypeScript
スポンサーリンク

interface は「オブジェクトの設計図」

interface は、オブジェクトの「形(どんなプロパティを持つか)」を表す設計図です。
「このオブジェクトは、こういうプロパティを持っていて、その型はこうでなければならない」という“契約”を決めるものだと思ってください。

interface User {
  id: number;
  name: string;
  email: string;
}

const userA: User = {
  id: 1,
  name: "Taro Yamada",
  email: "taro@example.com",
};
TypeScript

ここで User は、「id: number, name: string, email: string を必ず持つオブジェクト」というルールです。
このルールから外れるオブジェクトを代入しようとすると、TypeScript がコンパイル時に止めてくれます。


interface の基本構文と使い方

オブジェクトの形を定義する

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

function greet(person: Person) {
  console.log(`Hello, ${person.name} (${person.age})`);
}

greet({ name: "Taro", age: 20 });
TypeScript

interface Person { ... } で「Person という名前の“形”」を定義し、
person: Person で「この引数はその形を満たすオブジェクトでなければならない」と宣言しています。

ここで重要なのは、interface 自体は「中身の処理」ではなく「形だけ」を定義するという点です。
「どんなプロパティ名があって、その型は何か」だけを決めます。


プロパティの必須・任意・readonly

必須プロパティ

何も印を付けなければ、そのプロパティは「必須」です。

interface User {
  id: number;
  name: string;
}

const u1: User = { id: 1, name: "Taro" }; // OK

const u2: User = { id: 1 }; // エラー(name が足りない)
TypeScript

「このプロパティは絶対に必要」という仕様を、型として表現できます。

オプションプロパティ(?)

? を付けると「なくてもよい」プロパティになります。

interface User {
  id: number;
  name: string;
  age?: number;
}

const u1: User = { id: 1, name: "Taro" };          // OK
const u2: User = { id: 1, name: "Hanako", age: 18 }; // OK
TypeScript

age? は「age は number かもしれないし、そもそも存在しないかもしれない」という意味です。
使う側では「ないかもしれない」ことを意識してコードを書く必要があります。

readonly プロパティ

readonly を付けると、「一度値を入れたら書き換え禁止」のプロパティになります。

interface Config {
  readonly env: string;
  readonly debug: boolean;
}

const config: Config = {
  env: "dev",
  debug: true,
};

// config.env = "prod"; // エラー:読み取り専用
TypeScript

「設定値のように、あとから変えてほしくないもの」を表現するときにとても役立ちます。


interface を使うとコードがどう良くなるか

「形」を名前で共有できる

interface User {
  id: number;
  name: string;
}

function printUser(user: User) { ... }
function saveUser(user: User) { ... }
function deleteUser(user: User) { ... }
TypeScript

同じ { id: number; name: string } という形を、User という名前で共有できます。
もしあとから「namefullName に変えたい」となっても、interface User を1か所直せば、
それを使っている関数すべてに変更が反映されます。

「このオブジェクトはこういうものだ」という意図が伝わる

interface LoginRequest {
  email: string;
  password: string;
}

function login(req: LoginRequest) { ... }
TypeScript

ただ { email: string; password: string } と書くよりも、
LoginRequest という名前が付くだけで、「これはログイン用のリクエストだ」と一目で分かります。
「意味のある名前をつけた設計図」として interface を使うイメージです。


type と interface の関係をざっくりだけ

どちらも「オブジェクトの形」を表現できる

TypeScript では、オブジェクトの型は interface でも type でも書けます。

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

type Person2 = {
  name: string;
  age: number;
};
TypeScript

この2つは、基本的には同じ意味です。
初心者のうちは、「オブジェクトの形に名前をつけるなら、とりあえず interface でも type でもいい」くらいの理解で十分です。

より細かい違い(拡張の仕方、宣言マージなど)は、
interface に慣れてきてから、必要になったときに覚えればOKです。


初心者がまず掴んでおきたい interface の感覚

interface の本質は、たったひとつです。

「このオブジェクトは、こういうプロパティを持っていて、その型はこうであるべきだ」という契約を、コードの外ではなく“型”として書き下すもの

だからこそ、

  • ユーザー情報
  • 商品情報
  • APIレスポンス
  • 設定オブジェクト

のような「意味のあるまとまり」を見つけたら、
一度 interface 名前 { ... } で形を定義してみるといいです。

「バラバラのオブジェクト」から「設計図に基づいたオブジェクト」に変わった瞬間、
コードの読みやすさと安全性が、かなりはっきり変わってきます。

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