1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypeScriptで迷わない `type` と `interface` の使い分け

Posted at

TypeScriptを書いていると「型定義ってtypeinterfaceどっち使えばいいの?」ってなることありませんか?今回は初学者でもなるべく簡単に選べるシンプルルールをまとめました。2025年8月現在最新版(TS 5.9)に対応しています。

結論から(シンプルルール)

  • オブジェクトの“形”を決めたいinterface
    (クラスやオブジェクトの設計図。拡張もしやすい)

  • 型を“組み合わせたり計算”したいtype
    (Union・タプル・条件付き・Mappedなどの型操作向け)

  • 両方で書けるならチームや現場ルールに合わせる

typeについての詳しい拡張方法についてはこちらにまとめたので気になる方はぜひ。
https://qiita.com/kinopy513/items/73b72304a41f21851cef

そもそも何が違うの?

  • interface は「オブジェクトの形」を表すのが本職。宣言マージ(同名での拡張)ができるので、公開APIやライブラリ拡張と相性抜群。

  • type は「型に別名をつける」だけにとどまらず、Union/タプル/条件付き/Mappedなど、型を“いじる”のが得意。

どちらもオブジェクトは書けるけれど、得意分野が違います。

基本の書き方

interface:オブジェクトの設計図

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

const userData: User = { 
	id: 1,
	name: "Lily" 
}

type:別名+型操作いろいろ

type User = { 
	id: number
	name: string 
}

// Union  
type Status = "active" | "inactive" | "deleted"

// タプル  
type Point = [number, number] 

// 条件付き・Mappedの土台にも
type WithTimestamp<T> = T & { 
	createdAt: Date
	updatedAt: Date 
}

できる/できない 早見表(TS 5.9時点)

目的 interface type
オブジェクトの形を定義
クラスに implements させる
(※Union等は不可)
Union(A | B ×
タプル([A, B] ×
条件付き・Mappedなどの型操作
同名での宣言マージ(後から足す) ×

ポイント

  • クラスはオブジェクト型なら type でも implements 可能。ただしUnion型は不可。

  • ライブラリ型を拡張したいなら interface 一択(宣言マージが効く)。

場面別使用例

1) API/DTO など公開する場合は interface

export interface UserDTO { 
	id: number; 
	name: string;
	email?: string;
}

後からプロパティを足す余地がある場合は interface が安全。

2) 状態の分岐は type のUnion

interface Loading { 
	type: "loading" 
} 

interface Success { 
	type: "success" 
	data: string 
} 

interface Failure { 
	type: "failure"
	error: Error 
} 

type FetchState = Loading | Success | Failure;

列挙的な分岐はtypeのUnionで表現。

3) Props/設定の“合成”は type が書きやすい

type WithTimestamp<T> = T & {
	createdAt: Date
	updatedAt: Date 
}

interface Base { 
	id: string 
} 

type Entity = WithTimestamp<Base>;

4) 既存ライブラリの型を後から拡張(module augmentation)

// d.ts で宣言マージ(interface だけが可能)  
declare module "express-serve-static-core" { 
	interface Request {
	    userId?: string;
	}
}

5) 設定オブジェクトの“型だけ満たす”チェック(satisfies

type RGB = readonly [number, number, number] 
type Palette = Record<"red" | "green" | "blue", string | RGB> 

const palette = { 
	red: [255, 0, 0], 
	green: "#00ff00", 
	bleu: [0, 0, 255], // スペルミス"bleu"を検出
} satisfies Palette

satisfies値の型を変えず「その型を満たしているか」を検証できるので安全な設計が可能です。

よくあるつまずき

1) 交差型(&)の衝突に気づきにくい

// id は両立できず実質使えない型に
type A = { id: string } & { id: number } 

“型を合成”したいだけなら interfaceextends のほうが衝突に気づきやすいです。

2) type は“同名で足していく”ができない

type User = { id: number }
type User = { name: string } // 再宣言エラー

後から増える見込みがあるなら最初から interface の方がシンプルに実装できる。

3) クラスは Union(A | B)を implements できない

implements は「持つべき型を確定」させる必要があるため、“どちらか”の Union は不可
クラスの型は interface(またはオブジェクト型の typeその交差(A & B で指定します。

type S = { x: number } | { y: number }  // ❌ class C implements S

interface X { x: number } 
interface Y { y: number }
class P implements X, Y { x = 0; y = 0 } // ⭕️ A & B

const v: X | Y = new P(); // 使う側の Union はOK

チームで迷わないための最小ルール

  1. 原則

    • オブジェクトの型 → interface

    • Union/タプル/条件付き/Mapped → type

  2. 例外

    • 内部の一時的な合成・変形が中心なら type を使ってもよい
  3. Lintで固定

{  
	"rules":  {  
		"@typescript-eslint/consistent-type-definitions":  [
			"error",  
			"interface"
		]  
	}  
}

「オブジェクトは interface」を機械的に守れます。
※ただし対象は素のオブジェクト型だけ。
Union/Intersection/条件型/Mapped型はinterface制限の対象外です

チーム方針として「公開されるオブジェクト形は interface、型演算は type」で割り切るなら、このLint固定はおすすめです。

補足

TypeScript 5.9では import defer などが話題ですが、typeinterface の基本的な性質や使い分けが変わったわけではないので、今まで通り使えます。

まとめ

  • 公開する設計図(API/DTO/外部と接する型)interface

  • 後から足す可能性がある型interface(宣言マージ)

  • 状態分岐・選択肢の列挙type(Union)

  • 固定長配列・位置に意味があるtype(タプル)

  • 型の合成・変形type(交差・条件付き・Mapped)

  • クラスの型interface(またはオブジェクト型の type。Union不可)

採用情報

アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドエンジニアを募集しています!
少しでも興味のある方は、カジュアル面談からでもお気軽にお話ししましょう!

お問い合わせはこちらから↓
https://official.assisteng.co.jp/contact/

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?