メインコンテンツまでスキップ

命名規則 ③ 命名の質を高める

本記事は命名規則 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

時点と動作で対を使い分ける: 時点を表す変数は startTimeendTime(start ⇔ end)が自然な対です。一方、動作を表す関数は startstop または beginend で揃えます。startProcess の対は stopProcess です。

よくある対比語

対比語の一覧

開始 / 動作反対
startstop(終了)
beginend(終わり)
openclose(閉じる)
showhide(隠す)
enabledisable(無効化)
activatedeactivate(非活性)
lockunlock(解除)
firstlast(最後)
minmax(最大)
previousnext(次)
incrementdecrement(減少)
addremove(削除)
insertdelete(削除)
pushpop(取り出し)
acquirerelease(解放)

意味のない単語を含めない

Data, Info, Manager などの汎用的な単語は、それ単体では具体的な情報を提供しません。避けるべきは DataManager のように汎用語だけを重ねた名前です。SessionManagerFileMetadata のように、管理・記述する対象が明確な場合は問題ありません。

❌ 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) {
// ...
}

calculateTotalreduce を使った別解もあります。

✅ Good: 別解(reduce を使用)
function calculateTotal(items: ProductData[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}

修正のポイント:

  1. dcurrentDate: 意味を明確に
  2. usrCntuserCount: 省略を避ける
  3. prdDataProductData: パスカルケース
  4. nmname, prcprice: 完全な単語
  5. usrMgrUserManager: パスカルケース
  6. getUsrInfgetUser: 完全な単語にした上で、冗長な「Info」を削除
  7. delUsrdeleteUser: 完全な単語 + 動詞で統一
  8. calcTtlcalculateTotal: 完全な単語
  9. ttotal: 意味のある名前
  10. isNotCompleteisComplete: 否定形を避ける

命名規則のまとめ

命名規則クイックリファレンス

対象ルール
変数キャメルケースuserName, itemCount
定数アッパースネークケースMAX_COUNT
関数キャメルケースgetUserById
クラスパスカルケースUserService
インターフェースパスカルケースUserProfile
型エイリアスパスカルケースUserId
EnumパスカルケースUserRole
真偽値is / has / can / should + 状態・能力isValid, canEdit
配列複数形users, items
命名の原則
  • 意図が明確な名前を使う
  • 検索可能な名前を使う
  • 一貫性を保つ
  • 読み手の認知負荷を下げる

次に読む

  • コメント — コードで表現できないことだけをコメントに残す考え方
  • 変数 — 命名と並んで読みやすさを支える変数の扱い方