命名規則 ③ 命名の質を高める
本記事は命名規則 3 部構成の第 3 部 (最終部) です。第 1 部: ケース規約と変数・定数・第 2 部: 関数とクラスで扱った基本を踏まえて、命名の質を高める原則・総合練習問題・全体のまとめを扱います。
発音可能で意味のある名前を使う
❌ Bad: 省略形、発音不可能
// ❌ Bad: 省略形、発音不可能
const genYmdhms = (): string => {
const now = new Date();
const pad = (n: number) => String(n).padStart(2, "0");
return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`;
};
const dfColor = "#fff";
const usrCnt = 10;
// ✅ Good: 発音可能で意味が明確
const generateTimestamp = (): string => {
const now = new Date();
const pad = (n: number) => String(n).padStart(2, "0");
return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`;
};
const defaultColor = "#fff";
const userCount = 10;
理由:
- チームメンバーとの口頭でのコミュニケーションが容易
- コードレビューで説明しやすい
- 新しいメンバーが理解しやすい
配列・リストには複数形をつける
配列やリストを表す変数は、複数形にすることで一目で配列だと分かります。
❌ Bad: 単数形
// ❌ Bad: 単数形
const user = [{ id: 1 }, { id: 2 }];
const item = ["apple", "banana", "orange"];
user.forEach(u => console.log(u)); // user が配列なのか分かりにくい
// ✅ Good: 複数形
const users = [{ id: 1 }, { id: 2 }];
const items = ["apple", "banana", "orange"];
users.forEach(user => console.log(user)); // users が配列で user が要素だと明確
// ✅ TypeScriptの型定義でも複数形を使う
type User = {
id: number;
name: string;
};
type Users = User[];
不規則な複数形
✅ Good: 英語の不規則な複数形
// ✅ 英語の不規則な複数形
const children = [child1, child2]; // child → children
const people = [person1, person2]; // person → people
const mice = [mouse1, mouse2]; // mouse → mice
// ✅ 単複同形
const sheep = [sheep1, sheep2]; // sheep → sheep
const fish = [fish1, fish2]; // fish → fish
同じ意味の単語は統一する
プロジェクト内で同じ概念を表す単語は統一します。
❌ Bad: 同じ概念に異なる単語を使用
// ❌ Bad: 同じ概念に異なる単語を使用
class UserController {
getUser(id: string): User { }
}
class ProductController {
fetchProduct(id: string): Product { } // ❌ get と fetch が混在
}
class OrderController {
retrieveOrder(id: string): Order { } // ❌ retrieve も混在
}
// ✅ Good: 統一
class UserController {
getUser(id: string): User { }
}
class ProductController {
getProduct(id: string): Product { }
}
class OrderController {
getOrder(id: string): Order { }
}
// ────────────────────────────────────────────
// その他の統一例
// ────────────────────────────────────────────
// ❌ Bad: 削除に複数の単語
function removeUser(id: string) { }
function deleteProduct(id: string) { }
function eraseOrder(id: string) { }
// ✅ Good: delete で統一
function deleteUser(id: string) { }
function deleteProduct(id: string) { }
function deleteOrder(id: string) { }
よくある類似語
統一すべき類似語の例
| 意味 | 候補 |
|---|---|
| 取得 | get / fetch / retrieve |
| 削除 | delete / remove / erase |
| 作成 | create / make / build |
| 更新 | update / modify / edit |
| 送信 | send / submit / post |
| 表示 | show / display / render |
推奨アプローチ: プロジェクトで**用語集(Glossary)**を作成し、チーム全体で共有しましょう。
✅ Good: プロジェクトの用語統一例(glossary.ts)
// ✅ プロジェクトの用語統一例(glossary.ts)
/**
* プロジェクト用語集
*
* - データ取得: get(非同期の場合は fetch)
* - データ作成: create
* - データ更新: update
* - データ削除: delete
* - 表示: show
*/
対比語を使う
反対の意味を持つ値には、対比のある名前をつけます。
✅ Good: 対比語の例
// ✅ 対比語の例
// 開始 ⇔ 終了
const startTime = new Date();
const endTime = new Date();
function startTimer() { }
function stopTimer() { } // ✅ start ⇔ stop
// 最小 ⇔ 最大
const minValue = 0;
const maxValue = 100;
// 前 ⇔ 次
const previousPage = 1;
const nextPage = 3;
// 最初 ⇔ 最後
const firstItem = items[0];
const lastItem = items[items.length - 1];
// 開く ⇔ 閉じる
function openModal() { }
function closeModal() { } // ✅ open ⇔ close
// 表示 ⇔ 非表示
function showElement() { }
function hideElement() { } // ✅ show ⇔ hide
// 有効 ⇔ 無効
function enableFeature() { }
function disableFeature() { } // ✅ enable ⇔ disable
// ❌ Bad: 対比が不明確
function startProcess() { }
function endProcess() { } // ❌ 動作を表す関数で start と end を混ぜない
// ✅ Good
function startProcess() { }
function stopProcess() { } // ✅ start ⇔ stop
時点と動作で対を使い分ける: 時点を表す変数は startTime ⇔ endTime(start ⇔ end)が自然な対です。一方、動作を表す関数は start ⇔ stop または begin ⇔ end で揃えます。startProcess の対は stopProcess です。
よくある対比語
対比語の一覧
| 開始 / 動作 | 反対 |
|---|---|
start | stop(終了) |
begin | end(終わり) |
open | close(閉じる) |
show | hide(隠す) |
enable | disable(無効化) |
activate | deactivate(非活性) |
lock | unlock(解除) |
first | last(最後) |
min | max(最大) |
previous | next(次) |
increment | decrement(減少) |
add | remove(削除) |
insert | delete(削除) |
push | pop(取り出し) |
acquire | release(解放) |
意味のない単語を含めない
Data, Info, Manager などの汎用的な単語は、それ単体では具体的な情報を提供しません。避けるべきは DataManager のように汎用語だけを重ねた名前です。SessionManager や FileMetadata のように、管理・記述する対象が明確な場合は問題ありません。
❌ Bad: 意味のない単語
// ❌ Bad: Manager は抽象的すぎる(何のデータを管理するのか不明)
class DataManager {
processData() { }
}
// ✅ Good: 具体的な責務を示す
class UserRepository {
findById(id: string): User | null { }
save(user: User): void { }
}
// ────────────────────────────────────────────
// ❌ Bad: Object, Thing など抽象的
const userObject = { name: "Taro" };
const dataThing = [1, 2, 3];
// ✅ Good
const user = { name: "Taro" };
const numbers = [1, 2, 3];
ただし例外もある
一部の単語は、特定の文脈で意味を持つ場合があります。
✅ Good: 許容される例
// ✅ 許容される例
// Metadata: 「データに関するデータ」という特定の意味
interface FileMetadata {
size: number;
createdAt: Date;
mimeType: string;
}
// Config/Settings: 設定を表す慣習的な名前
interface AppConfig {
apiUrl: string;
timeout: number;
}
// Context: React/Angularなどのフレームワークの慣習
const UserContext = React.createContext<User | null>(null);
変数名の省略
省略は一般的に認知されている場合のみ使用します。
✅ Good: 一般的に認知されている省略形
// ────────────────────────────────────────────
// ✅ 一般的に認知されている省略形
// ────────────────────────────────────────────
// ID(identifier)
const userId = "12345";
const productId = 100;
// URL(Uniform Resource Locator)
const apiUrl = "https://api.example.com";
// HTTP(HyperText Transfer Protocol)
const httpClient = new HttpClient();
// API(Application Programming Interface)
const apiResponse = await fetchData();
// DB(Database)
const dbConnection = createConnection();
// Auth(Authentication)
const authToken = "abc123";
// Config(Configuration)
const appConfig = loadConfig();
// Temp(Temporary)
const tempValue = calculateTemp();
// Max/Min(Maximum/Minimum)
const maxRetries = 3;
const minValue = 0;
// Prev/Next(Previous/Next)
const prevPage = 1;
const nextPage = 3;
// ────────────────────────────────────────────
// ❌ 避けるべき省略形
// ────────────────────────────────────────────
// ❌ 独自の省略
const usrNm = "Taro"; // ✅ userName
const prdLst = []; // ✅ productList
const calcTtl = () => {}; // ✅ calculateTotal
// ❌ 母音を削除しただけ
const btn = document.querySelector('button'); // ✅ button
const msg = "Hello"; // ✅ message
const err = new Error(); // ✅ error (errは許容される場合も)
// ❌ 文脈なしでは分からない省略
const d = new Date(); // ✅ date または currentDate
const i = 0; // ✅ index または count(ループ以外では)
const tmp = getValue(); // ✅ temporary または具体的な名前
ループ変数の省略は許容される
✅ Good: ループでは慣習的な省略が許容される
// ✅ ループでは慣習的な省略が許容される
for (let i = 0; i < 10; i++) {
console.log(i);
}
// ✅ ネストしたループ
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
matrix[i][j] = 0;
}
}
// ✅ より意味のある名前が望ましい場合
for (let userIndex = 0; userIndex < users.length; userIndex++) {
const user = users[userIndex];
// ...
}
// ✅ forEach/map では完全な名前を使う
users.forEach(user => { // ✅ user (u ではない)
console.log(user.name);
});
練習問題 5: 命名規則の総合問題
以下のコードをクリーンコードの命名規則に従って修正してください。
❌ Bad: 修正前
// ❌ 修正前
const d = new Date();
const usrCnt = 100;
interface prdData {
id: number;
nm: string;
prc: number;
}
class usrMgr {
getUsrInf(id: number) {
// ...
}
delUsr(id: number) {
// ...
}
}
function calcTtl(items: any[]) {
let t = 0;
for (let i = 0; i < items.length; i++) {
t += items[i].prc;
}
return t;
}
const isNotComplete = false;
if (!isNotComplete) {
// ...
}
📝 解答を見る
✅ Good: 修正後
// ✅ 修正後
const currentDate = new Date();
const userCount = 100;
interface ProductData {
id: number;
name: string;
price: number;
}
class UserManager {
getUser(id: number) {
// ...
}
deleteUser(id: number): void {
// ...
}
}
function calculateTotal(items: ProductData[]): number {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
return total;
}
// 否定形を避ける
const isComplete = true;
if (isComplete) {
// ...
}
calculateTotal は reduce を使った別解もあります。
✅ Good: 別解(reduce を使用)
function calculateTotal(items: ProductData[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
修正のポイント:
d→currentDate: 意味を明確にusrCnt→userCount: 省略を避けるprdData→ProductData: パスカルケースnm→name,prc→price: 完全な単語usrMgr→UserManager: パスカルケースgetUsrInf→getUser: 完全な単語にした上で、冗長な「Info」を削除delUsr→deleteUser: 完全な単語 + 動詞で統一calcTtl→calculateTotal: 完全な単語t→total: 意味のある名前isNotComplete→isComplete: 否定形を避ける
命名規則のまとめ
命名規則クイックリファレンス
| 対象 | ルール | 例 |
|---|---|---|
| 変数 | キャメルケース | userName, itemCount |
| 定数 | アッパースネークケース | MAX_COUNT |
| 関数 | キャメルケース | getUserById |
| クラス | パスカルケース | UserService |
| インターフェース | パスカルケース | UserProfile |
| 型エイリアス | パスカルケース | UserId |
| Enum | パスカルケース | UserRole |
| 真偽値 | is / has / can / should + 状態・能力 | isValid, canEdit |
| 配列 | 複数形 | users, items |
命名の原則
- 意図が明確な名前を使う
- 検索可能な名前を使う
- 一貫性を保つ
- 読み手の認知負荷を下げる