とある会社の、とあるプロジェクトにマネージャ―兼CTO補佐として参加した時に、TypeScriptのコーディング規約について作成するように言われてしまいました。
その時に作成したコーディング等の規則をもとに、私的コーディングガイドラインをまとめておこうと思います。
自分でも忘れがちなので、自分に対する備忘録でもあります。
目次
命名規則
形式 (ケース) について
キャメルケース (ローワーキャメルケース)、パスカルケース (アッパーキャメルケース)、コンスタントケースのみ使用する。
スネークケース、チェインケース (ケバブケース) は使用しない。
変数名、引数名、関数名、プロパティ名、メソッド名には、キャメルケース (camelCase) を使用する。
クラス名、インターフェース名、ネームスペース名、列挙型名には、パスカルケース (PascalCase) を使用する。
定数名、列挙型のメンバ名には、パスカルケースまたはコンスタントケース (CONSTANT_CASE) を使用する。パスカルケースとコンスタントケースの使い分けについては、プロジェクトごとの規則に従う場合や、目的、用途によって適用する。
形式一覧表
対象 | 形式 | 例 |
---|---|---|
変数 | キャメルケース | variableName |
引数 | キャメルケース | parameterName |
関数 | キャメルケース | functionName |
プロパティ | キャメルケース | propertyName |
メソッド | キャメルケース | methodName |
クラス | パスカルケース | ClassName |
インターフェース | パスカルケース | InterfaceName |
ネームスペース | パスカルケース | Namespace.Name |
定数 | パスカルケースまたは コンスタントケース |
ConstantName CONSTANT_Name |
列挙型 | パスカルケース | EnumName |
列挙型のメンバー | パスカルケースまたはコンスタントケース | MemberName MEMBER_NAME |
避ける名前・記法・文字
TypeScript、JavaScript の予約語は、大文字小文字の区別に関係なく使用しない。
ハンガリアン記法は使用しない。
定数、列挙型のメンバー (コンスタントケース) 以外にアンダースコア「 _ 」は使用しない。
関数名・メソッド名
原則として動詞で始める。
機能を明確に表すものにする。
(例)
search
updateUser
loadList
引数名
わかりやすく簡潔であり、引数の内容が判断できるものにする。
クラス名・インターフェース名・プロパティ名
名詞または名詞句を使用する。
省略形は多用しない。 (どうしても必要な場合のみ省略形は使用する。)
boolean 型の変数、引数、関数など
boolean 型の変数、引数、boolean 型の値を返す関数は、「is + 形容詞」「can + 動詞」「has + 過去分詞」「三単現動詞」「三単現動詞+ 名詞」の形式で命名する。
(例)
isEmpty
canWrite
hasChanged
exists
existsPerson
書式
インデント
スペース2つまたはスペース4つに統一する。
改行コード
CRLFに統一する。
1行の文字数
150文字以内にする。
文字列の引用符
シングルクォート「’」を使用する。
文末のセミコロン
文末のセミコロン「;」は原則として省略しない。
制御構文
制御構文
if, for, do, while 等の制御構文の本体は、中括弧「{}」で囲む。
制御構文後の括弧「(」との間にはスペースを入れる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// × if (!canUpdate) return; // または if (canUpdate) return; // または if(canUpdate) { return; } // ○ if (canUpdate) { return; } |
中括弧の位置
制御構文、関数、クラスなどの文の開始中括弧「{」は、文の宣言と同じ行に記述し、文の宣言と中括弧の間にはスペースを入れる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// × if (canRead) { this.readCustomer(); } else{ this.clearForm(); } // ○ if (canRead) { this.readCustomer(); } else { this.clearForm(); } // または if (canRead) { this.readCustomer(); } else { this.clearForm(); } |
変数の宣言
1行に宣言する変数の個数
1行に宣言する変数は1つにする。 (カンマ区切りで複数宣言しない。)
1 2 3 4 5 6 |
// × const foo: string = '', bar: string = ''; // ○ const foo: string = ''; const bar: string = ''; |
const, let, var
変数の宣言時には原則として const を使用する。再代入を行う必要がある場合のみ let を使用する。(var は使用しない。)
1 2 3 4 5 6 7 |
// × var id: number = user.id; var isEmpty: boolean = false; // ○ const id: number = user.id; let isEmpty: boolean = false; |
変数のスコープ
変数は使用する直前に宣言し、スコープができる限り狭くなるようにする。
型アノテーション (Type Annotation)
型アノテーション (型注釈) は一目見てデータ型が推測できる場合のみ省略可能とする。
1 2 3 4 5 6 7 8 9 |
// × const value = null; const user = this.getData(); // ○ let counter = 0; const defaultName = 'Default Name'; const user: UserRead = this.getData(); const newUser = new User(id, name); |
関数の引数、戻り値の型アノテーションは省略しない。
1 2 3 4 5 6 7 8 9 |
// × function isNullOrEmpty(str) { return !str; } // ○ function isNullOrEmpty(str: number): boolean { return !str; } |
型アサーション (Type Assertion)
型アサーション (キャスト) は、原則として value as Type 形式を使用する。(<Type> value 形式は使用しない。)
1 2 3 4 5 |
// × const foo = <Bar> bar; // ○ const foo = bar as Bar; |
配列 (Array<T>) の初期化
配列の初期化には、原則として new Array<T>() 形式を使用する。(<<Array<T>>[] 形式は使用しない。)
1 2 3 4 5 |
// × const foos = <<Array<Foo>>[]; // ○ const foos = new Array<Foo>(); |
any 型
any 型は原則として使用しない。コンパイルエラーの回避など、やむを得ない場合のみ使用可能とする。
比較演算子
原則として厳密等価演算子「===」、厳密不等価演算子「!==」を使用する。
等価演算子「==」と不等価演算子「!=」は必要な場合のみ使用可能とする。
文字列合成
文字列の合成には原則としてテンプレートリテラルを使用する。ただしソースコードの可読性を考慮する場合はこの限りではない。
1 |
const ymd = `${yyyy}/${mm}/${dd}`; |
データ型の変換
暗黙の型変換は行わない。
数値に変換する場合は、Number(foo)、parseInt(foo)、parseFloat(foo)を使用する。(+foo、foo – 0 等の変換は行わない。)
文字列に変換する場合は、String(foo)、foo.toString()を使用する。(” + foo、foo + ” 等の変換は行わない。)
真偽値の判定
以下の挙動を理解した上で使用する。
- 数値は、0(+0, -0), NaNの場合にfalse。
- 文字列は、””(空文字列)の場合にfalse。
- undefined, nullの場合はfalse。
ファイル
パスカルケースで命名し、エンコーディングはUTF-8とする。