命名規則 ① ケース規約と変数・定数
本テーマは 3 部構成です
命名規則は 3 つの記事に分かれています。本記事 (第 1 部) ではケース規約と変数・真偽値・定数の命名を扱い、第 2 部: 関数とクラス、第 3 部: 命名の質を高めると続きます。
なぜ変数名が大切なのか
良い変数名はコードそのものがドキュメントになることを可能にします。
❌ Bad: 意図が伝わらない
❌ Bad: 意図が伝わらない
const a = 300 / 60;
問題点:
aが何を表すのか不明300と60の意味が不明- コメントなしでは理解不可能
✅ Good: 意図が明確
✅ Good: 意図が明確
const minutes = 300;
const hours = minutes / 60;
改善点:
- 変数名から「分を時間に変換」という意図が明確
- 数値の単位が理解できる
- コメント不要で自己説明的
命名が変わるとコードの意味が変わる
識別子とケース
識別子(変数名、関数名、クラス名など)の命名規則には主に4つのパターンがあります。
命名規則の種類
| 種類 | 例 |
|---|---|
| ケバブケース | kebab-case, user-name |
| スネークケース | snake_case, user_name |
| パスカルケース | PascalCase, UserData |
| キャメルケース | camelCase, userName |
1. ケバブケース(kebab-case)
説明: 単語と単語の間をハイフン(-)でつなぐ。
✅ Good: 使用場面: HTML属性、URL、CSSクラス名
// ✅ 使用場面: HTML属性、URL、CSSクラス名
<!-- HTML属性 -->
<input name="user-name" />
<section class="content-width">...</section>
<!-- URL -->
https://example.com/sales-profit
https://example.com/user-profile
TypeScript変数では使用しない (ハイフンが減算演算子と解釈される)
❌ Bad: エラー!
// ❌ エラー!
const user-name = "Taro"; // SyntaxError
2. スネークケース(snake_case)
説明: 単語と単語の間をアンダースコア(_)でつなぐ。
✅ Good: 使用場面(TypeScriptでは限定的)
// ✅ 使用場面(TypeScriptでは限定的)
TypeScriptでは一般的にキャメルケースが推奨されますが、以下の場合に使用されることがあります:
// データベースのカラム名に合わせる場合
interface UserRecord {
user_id: number;
first_name: string;
last_name: string;
created_at: Date;
}
// 外部APIのレスポンスに合わせる場合
type ApiResponse = {
access_token: string;
refresh_token: string;
expires_in: number;
};
アッパースネークケース(UPPER_SNAKE_CASE)
説明: 全て大文字でアンダースコアでつなぐ。
✅ Good: 使用場面: 定数(変更されない値)
// ✅ 使用場面: 定数(変更されない値)
const MAX_USER_COUNT = 100;
const API_BASE_URL = "https://api.example.com";
const DEFAULT_TIMEOUT_MS = 5000;
// ✅ 列挙型の値
const ORDER_TYPE = {
NEW_ENTRY: 0,
UPDATE_PLAN: 10,
CANCEL_CONTRACT: 30,
} as const;
3. パスカルケース(PascalCase)
説明: 全ての単語の先頭を大文字にする(アッパーキャメルケースとも言う)
✅ Good: 使用場面: クラス、インターフェース、型エイリアス、列挙型
// ✅ 使用場面: クラス、インターフェース、型エイリアス、列挙型
// クラス
class UserAccount {
private userName: string;
constructor(userName: string) {
this.userName = userName;
}
}
// インターフェース
interface UserProfile {
id: number;
name: string;
email: string;
}
// 型エイリアス
type ApiResult<T> = {
data: T;
status: number;
};
// 列挙型(Enum)
enum OrderStatus {
Pending,
Processing,
Completed,
Cancelled,
}
// React コンポーネント(関数コンポーネント)
function UserProfileCard({ user }: { user: UserProfile }) {
return <div>{user.name}</div>;
}
4. キャメルケース(camelCase)
説明: 先頭の単語は小文字、後に続く単語の先頭を大文字にする。
✅ Good: 使用場面: 変数、関数、メソッド、プロパティ
// ✅ 使用場面: 変数、関数、メソッド、プロパティ
// 変数
const userName = "Taro";
const totalAmount = 1000;
const isAuthenticated = true;
// 関数
function calculateTotalPrice(price: number, quantity: number): number {
return price * quantity;
}
// メソッド
class ShoppingCart {
private items: Item[] = [];
addItem(item: Item): void {
this.items.push(item);
}
getTotalPrice(): number {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}
// オブジェクトのプロパティ
const userSettings = {
displayName: "Taro Yamada",
emailAddress: "taro@example.com",
notificationEnabled: true,
};
TypeScriptにおける命名規則のまとめ
// ────────────────────────────────────────────
// 📋 TypeScript 命名規則チートシート
// ────────────────────────────────────────────
// 1️⃣ 変数・定数
const userName = "Taro"; // ✅ キャメルケース(通常の変数)
const MAX_RETRY_COUNT = 3; // ✅ アッパースネークケース(定数)
// 2️⃣ 関数
function getUserById(id: number) {} // ✅ キャメルケース
// 3️⃣ クラス
class UserAccount {} // ✅ パスカルケース
// 4️⃣ インターフェース
interface UserProfile {} // ✅ パスカルケース
// インターフェースに "I" プレフィックスは付けない(非推奨)
interface IUserProfile {} // ❌ 古い慣習
// 5️⃣ 型エイリアス
type UserId = string; // ✅ パスカルケース
type UserData = { id: number }; // ✅ パスカルケース
// 6️⃣ Enum(列挙型)
enum UserRole { // ✅ パスカルケース(型名)
Admin, // ✅ パスカルケース(メンバー)
User,
Guest,
}
// 7️⃣ ジェネリック型パラメータ
function identity<T>(value: T): T { return value; } // ✅ 1文字の大文字(T, U, V など)
class Container<TItem> {} // ✅ または T + 説明的な名前
// 8️⃣ プライベートフィールド
class User {
private userName = ""; // ✅ キャメルケース
#password = ""; // ✅ # プレフィックス(ECMAScript private)
}
練習問題 1: 命名規則の適用
以下のコードを正しい命名規則で書き直してみましょう。
❌ Bad: 修正前
// ❌ 修正前
class user_data {
constructor(public user_name: string) {}
}
interface product_info {
product_id: number;
product_name: string;
}
const TAX_RATE = 0.1;
function CALCULATE_PRICE(price: number): number {
return price * (1 + TAX_RATE);
}
enum order_status {
pending = 'PENDING',
completed = 'COMPLETED',
}
📝 解答を見る
✅ Good: 修正後
// ✅ 修正後
// クラスはパスカルケース
class UserData {
constructor(public userName: string) {}
}
// インターフェースはパスカルケース、プロパティはキャメルケース
interface ProductInfo {
productId: number;
productName: string;
}
// 定数はアッパースネークケース
const TAX_RATE = 0.1;
// 関数はキャメルケース
function calculatePrice(price: number): number {
return price * (1 + TAX_RATE);
}
// Enumはパスカルケース
enum OrderStatus {
Pending = 'PENDING',
Completed = 'COMPLETED',
}
※ この問題はケース(大文字・小文字と区切り方)の変換のみを扱っています。UserData という名前自体の良し悪しは、第 3 部の「意味のない単語を含めない」の節を参照してください。
変数の命名規則
原則: 変数は「何を格納しているか」を明確に表す
❌ Bad: 抽象的すぎる
// ❌ Bad: 抽象的すぎる
let number = 20;
let str = "red";
let data = { id: 1 };
// ✅ Good: 具体的で意味が明確
let age = 20;
let themeColor = "red";
let userData = { id: 1 };
型情報を変数名に含めない
TypeScriptでは型システムがあるため、型情報を変数名に含める必要はありません。
❌ Bad: 型情報を名前に含める(ハンガリアン記法)
// ❌ Bad: 型情報を名前に含める(ハンガリアン記法)
const strUserName = "Taro";
const numAge = 25;
const arrItems: number[] = [1, 2, 3];
const objUser = { id: 1 };
// ✅ Good: 型は型アノテーションで表現
const userName: string = "Taro";
const age: number = 25;
const items: number[] = [1, 2, 3];
const user: User = { id: 1 };
// ✅ Better: 型推論を活用(冗長な型アノテーションを避ける)
const userName = "Taro"; // 型推論で string
const age = 25; // 型推論で number
const items = [1, 2, 3]; // 型推論で number[]
const user: User = { id: 1 }; // 型が明示的に必要な場合のみ
真偽値(boolean)の命名規則
真偽値を格納する変数は、その値が true か false かを表す命名にします。
接頭辞のパターン
真偽値の命名パターン
| パターン | 例 |
|---|---|
| is + 名詞 / 形容詞 | isVisible, isValid |
| has + 名詞 | hasError, hasChildren |
| can + 動詞 | canEdit, canDelete |
| should + 動詞 | shouldUpdate, shouldRetry |
| 過去分詞 | completed, finished |
具体例
✅ Good: is + 形容詞/名詞
// ✅ is + 形容詞/名詞
const isVisible = true;
const isAuthenticated = false;
const isValid = checkValidity();
const isLoading = true;
const isEmpty = array.length === 0;
// ✅ has + 名詞
const hasError = errors.length > 0;
const hasChildren = node.children.length > 0;
const hasPermission = user.role === 'admin';
// ✅ can + 動詞
const canEdit = user.permissions.includes('edit');
const canDelete = user.role === 'admin';
const canSubmit = isValid && !isLoading;
// ✅ should + 動詞
const shouldUpdate = newVersion > currentVersion;
const shouldRetry = attemptCount < MAX_RETRIES;
const shouldShowWarning = diskUsage > 0.9;
// ✅ 過去分詞形
const completed = tasks.every(task => task.status === 'done');
const enabled = settings.featureFlags.newUI;
❌ 避けるべきパターン
❌ Bad: 避けるべきパターン
// ❌ Bad: 否定形は避ける(二重否定で混乱)
const notComplete = false;
if (!notComplete) { // 読みにくい
// ...
}
// ✅ Good: 肯定形を使う
const isComplete = true;
if (isComplete) { // 読みやすい
// ...
}
// ❌ Bad: 動詞だけで真偽値を表すのは避ける
const display = true; // displayは動詞なので関数と混同しやすい
// ✅ Good: is + 過去分詞
const isDisplayed = true;
// ❌ Bad: 型名を使う
const boolean = true;
const string = typeof value === 'string';
// ✅ Good: 具体的な状態を表す
const isEnabled = true;
const isString = typeof value === 'string';
練習問題 2: 真偽値の命名
// 以下の変数名を適切な命名に修正してください
// 1. ユーザーが成人かどうか
const xxx = age >= 18;
// 2. 配列が空かどうか
const xxx = array.length === 0;
// 3. 編集権限があるかどうか
const xxx = user.role === 'admin' || user.role === 'editor';
// 4. ファイルが存在するかどうか
const xxx = fs.existsSync(filePath);
// 5. 全てのタスクが完了したかどうか
const xxx = tasks.every(task => task.done);
📝 解答を見る
✅ Good: 解答
// ✅ 解答
// 1. ユーザーが成人かどうか
const isAdult = age >= 18;
// または
const isOfAge = age >= 18;
// 2. 配列が空かどうか
const isEmpty = array.length === 0;
// 3. 編集権限があるかどうか
const canEdit = user.role === 'admin' || user.role === 'editor';
// または
const hasEditPermission = user.role === 'admin' || user.role === 'editor';
// 4. ファイルが存在するかどうか
const fileExists = fs.existsSync(filePath);
// または
const hasFile = fs.existsSync(filePath);
// 5. 全てのタスクが完了したかどうか
const allCompleted = tasks.every(task => task.done);
// または
const isAllTasksCompleted = tasks.every(task => task.done);
定数の命名規則
定数とは
TypeScriptにおける定数には2つの意味があります:
- 再代入できない変数(
constで宣言) - アプリケーション全体で不変の値(設定値、マジックナンバーの代替など)
// ────────────────────────────────────────────
// const の2つの意味を理解する
// ────────────────────────────────────────────
// 1️⃣ 再代入できない変数(通常のconst)
const user = { name: "Taro" };
user.name = "Hanako"; // ✅ プロパティの変更は可能
// user = {}; // ❌ 再代入は不可
// 2️⃣ 完全に不変の値(アプリケーション定数)
const MAX_RETRY_COUNT = 3; // ✅ アッパースネークケース
const API_BASE_URL = "https://api.example.com";
命名規則の使い分け
✅ Good: 環境変数、設定値
// ────────────────────────────────────────────
// アッパースネークケース(UPPER_SNAKE_CASE)
// ────────────────────────────────────────────
// 用途: アプリケーション全体で変更されない値
// ✅ 環境変数、設定値
const API_ENDPOINT = "https://api.example.com";
const DEFAULT_LOCALE = "ja-JP";
const MAX_FILE_SIZE_MB = 10;
// ✅ マジックナンバーの代替
const TAX_RATE = 0.1;
const SECONDS_PER_MINUTE = 60;
const MILLISECONDS_PER_SECOND = 1000;
// ✅ ループの上限値
const MAX_RETRY_ATTEMPTS = 3;
const PAGE_SIZE = 20;
// ✅ 定数オブジェクト(as const を使用)
const HTTP_STATUS = {
OK: 200,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
NOT_FOUND: 404,
} as const;
const ORDER_TYPE = {
NEW_ENTRY: 0,
UPDATE_PLAN: 10,
CANCEL_CONTRACT: 30,
} as const;
// ────────────────────────────────────────────
// キャメルケース(camelCase)
// ────────────────────────────────────────────
// 用途: 通常の変数(オブジェクトや配列など)
// ✅ オブジェクトインスタンス
const userSettings = {
theme: "dark",
language: "ja",
};
// ✅ 配列
const itemList = [1, 2, 3];
// ✅ クラスインスタンス
const httpClient = new HttpClient();
// ✅ 関数の結果
const calculatedValue = calculateTotal();
as const による型の厳密化
as const を使用することで、値を完全に不変にし、型をリテラル型として扱えます。
❌ Bad: as const なし
// ────────────────────────────────────────────
// as const の効果
// ────────────────────────────────────────────
// ❌ as const なし
const ORDER_TYPE_1 = {
NEW: 0,
UPDATE: 10,
};
// 型: { NEW: number; UPDATE: number }
// ORDER_TYPE_1.NEW の型は number(広すぎる)
// ✅ as const あり
const ORDER_TYPE_2 = {
NEW: 0,
UPDATE: 10,
} as const;
// 型: { readonly NEW: 0; readonly UPDATE: 10 }
// ORDER_TYPE_2.NEW の型は 0(リテラル型で厳密)
// ✅ 実用例: 型安全な定数オブジェクト
const USER_ROLE = {
ADMIN: 'admin',
USER: 'user',
GUEST: 'guest',
} as const;
// 型を抽出
type UserRole = typeof USER_ROLE[keyof typeof USER_ROLE];
// 型: "admin" | "user" | "guest"
function checkPermission(role: UserRole) {
if (role === USER_ROLE.ADMIN) {
// ...
}
}
checkPermission(USER_ROLE.ADMIN); // ✅ OK
checkPermission('admin'); // ✅ OK
// checkPermission('superuser'); // ❌ エラー
練習問題 3: 定数の命名
// 以下の定数を適切に命名してください
// 1. 消費税率(10%)
const xxx = 0.1;
// 2. 最大ログイン試行回数
const xxx = 5;
// 3. ユーザー情報(オブジェクト)
const xxx = {
id: 1,
name: "Taro"
};
// 4. エラーコード一覧
const xxx = {
notFound: 404,
serverError: 500,
};
// 5. 曜日の配列
const xxx = ["日", "月", "火", "水", "木", "金", "土"];
📝 解答を見る
✅ Good: 解答
// ✅ 解答
// 1. 消費税率(10%) - 変更されない値なのでアッパースネークケース
const TAX_RATE = 0.1;
// 2. 最大ログイン試行回数 - 設定値なのでアッパースネークケース
const MAX_LOGIN_ATTEMPTS = 5;
// 3. ユーザー情報(オブジェクト) - インスタンスなのでキャメルケース
const currentUser = {
id: 1,
name: "Taro"
};
// 4. エラーコード一覧 - 定数オブジェクトなのでアッパースネークケース + as const
const ERROR_CODE = {
NOT_FOUND: 404,
SERVER_ERROR: 500,
} as const;
// 5. 曜日の配列 - 変更されないリストなので両方あり得る
const DAYS_OF_WEEK = ["日", "月", "火", "水", "木", "金", "土"] as const;
// または用途に応じて
const daysOfWeek = ["日", "月", "火", "水", "木", "金", "土"];
次に読む
- 命名規則 ② 関数とクラス — 関数・クラス・メソッドの命名規則に進む