식별자는 변수, 함수, 클래스, 인터페이스, 타입, 속성 등의 이름을 나타낸다.
식별자에서 허용되는 문자:
영문 대소문자 (A-Z, a-z): 일반적인 알파벳 문자.
숫자 (0-9): 알파벳과 함께 사용 가능. 단, 숫자로 시작할 수는 없다.
특정 상황에서만 밑줄 사용:
상수: ALL_CAPS 스타일의 상수 이름에 밑줄을 사용.
예: MAX_LENGTH
, DEFAULT_VALUE
.
구조화된 테스트 메서드 이름: 테스트 메서드에서 논리적 구조를 나타내기 위해 밑줄 사용 가능.
예: test_addition_of_two_numbers
달러 기호($):
JavaScript 및 TypeScript에서 $
는 변수 이름에 허용되지만, 일반적으로 특별한 목적으로만 사용한다.
예: AngularJS에서 $scope
, jQuery에서 $
같은 경우.
허용되지 않는 문자:
비ASCII 문자(예: 한글, 특수 기호 등)는 식별자로 사용하지 않는다.
예: 이름
, #value
, @count
등은 허용되지 않음.
opt_
접두사를 사용하지 않기Observable
변수 구분을 위한 $
접미사의 사용 여부는 팀의 판단에 따름Before
interface ITodoItem {
title: string;
completed: boolean;
}
interface TodoItemInterface {
title: string;
completed: boolean;
}
I
나 Interface
와 같은 특별한 표시는 코드에 의미를 더하지 않는다.After
interface TodoItemStorage {
title: string;
completed: boolean;
}
이름은 설명적이고 명확해야 한다. 모호하거나 익숙하지 않은 약어를 사용하지 말고, 단어 내에서 문자를 삭제하여 약어의 사용을 지양하자.
예외: 10줄 이하 범위에 속하는 변수, 즉 내보내는 API에 속하지 않는 인수는 짧은(예: 문자 하나) 변수 이름을 사용할 수 있다.
명확하고 서술적인 이름 사용:
변수나 식별자는 코드만 봐도 무슨 역할을 하는지 쉽게 이해할 수 있는 이름을 사용해야 한다.
외부인이나 새로운 독자가 봐도 직관적으로 의미를 알 수 있도록 이름을 정해야 한다.
모호하거나 생소한 약어 지양:
특정 프로젝트 내부에서만 통용되는 약어나 생소한 약어는 사용하지 말 것.
약어를 쓸 때는 일반적으로 알려진 약어만 사용한다.
예: URL
, DNS
, Id
등.
단어 내 글자를 생략하지 말 것:
단어의 중간 글자를 삭제하거나 축약하여 의미를 모호하게 만들지 말 것.
예: cstmrId
→ customerId
로 작성.
짧은 범위에서는 간결한 이름 허용:
범위가 10줄 이하인 코드(로컬 변수, 함수 인자 등)에서는 단일 문자 또는 간결한 이름이 허용된다.
예: i
, n
, x
등.
헝가리안 표기법 지양:
변수 이름에 타입 정보를 접두사로 붙이는 헝가리안 표기법은 사용하지 않는다.
예: kSecondsPerDay
(잘못된 헝가리안 표기법).
올바른 CamelCase:
CamelCase 표기법을 사용할 때, 약어는 일관되게 소문자로 처리.
예: customerId
(올바름), customerID
(잘못된 CamelCase).
Before
const n = 5; // 의미 불명확
const nErr = 0; // 애매한 약어
const cstmrId = "12345"; // 축약으로 가독성 저하
const wgcConnections = []; // 팀 내부에만 알려진 약어
const customerID = "12345"; // 잘못된 CamelCase
After
const itemCount = 5; // 명확한 이름
const errorCount = 0; // 가독성이 좋은 이름
const customerId = "12345"; // 축약하지 않은 명확한 이름
const connections = []; // 약어를 제거하여 직관적으로 수정
약어는 단어처럼 취급:
약어(Acronym)가 포함된 식별자 이름은 단어처럼 혼합 대소문자로 작성해야 한다.
BAD: loadHTTPURL
(약자를 전체 대문자로 작성하면 읽기 어렵다.)
GOOD: loadHttpUrl
(Http는 단어처럼 취급되어 첫 글자만 대문자로 표기)
플랫폼 이름이 특별한 경우는 예외:
특정 플랫폼이나 API 이름이 약자를 대문자로 사용하는 경우, 해당 관례를 따라야 한다.
(XMLHttpRequest
는 JavaScript의 API 이름에서 사용되는 표준.)
$
는 일반적인 경우 식별자 이름에 사용하지 않는 것이 좋다.
다만, 서드파티 프레임워크의 명명 규칙에 따라 사용하거나, Observable
값을 구분하기 위해 명확한 목적으로 사용할 수 있다.
$
를 사용할 경우, 프로젝트 내에서 일관성을 유지하는 것이 중요하다.
식별자의 종류에 따라 일관된 네이밍 스타일을 사용해야 한다:
스타일 | 대상 카테고리 | 설명 |
---|---|---|
PascalCase | 클래스, 인터페이스, 타입, 열거형(enum), 데코레이터, 타입 매개변수, TSX/JSX 요소 타입 매개변수 | 첫 단어와 이후 모든 단어의 첫 글자가 대문자. 주로 구조적이고 정의적인 객체에 사용됨. |
camelCase | 변수, 매개변수, 함수, 메서드, 속성, 모듈 별칭 | 첫 단어는 소문자, 이후 단어는 첫 글자만 대문자. 일반적으로 작은 스코프의 요소 또는 동작과 관련된 것들에 사용됨. |
CONSTANT_CASE | 전역 상수 값, 열거형(enum) 값 | 모든 문자가 대문자이며, 단어는 밑줄(_ )로 구분. 불변 값을 명확히 구분하기 위해 사용됨. |
#ident | private 식별자 | TypeScript에서는 지원하지 않음. # 접두사는 JavaScript의 private class 필드에 사용되며 TypeScript에서는 일반적으로 private 키워드를 사용. |
타입 매개변수는 제네릭(generic)을 사용할 때 선언되며, 함수, 클래스, 인터페이스, 타입 별칭 등에 유연한 타입 지정을 제공한다. 단일 대문자 또는 PascalCase를 사용할 수 있다.
function getKey<K, V>(key: K, value: V): K {
return key;
}
class ApiResponse<DataType> {
constructor(public data: DataType, public success: boolean) {}
}
const userResponse = new ApiResponse<{ id: number; name: string }>({
id: 1,
name: "Alice",
}, true);
테스트의 목적과 동작을 명확하게 나타내고, 테스트가 어떤 상황에서 어떤 결과를 예상하는지를 쉽게 이해할 수 있도록 _ (밑줄) 구분자를 사용하여 테스트 메서드를 설명적이고 읽기 쉽게 작성한다.
testX_whenY_doesZ()
형태를 따른다.X
: 테스트하려는 기능 또는 행동.Y
: 조건이나 상황.Z
: 예상되는 결과 또는 행동function testLogin_whenCredentialsAreValid_doesRedirectToDashboard() {
// 로그인 기능 테스트
}
testLogin
: 로그인 기능을 테스트.whenCredentialsAreValid
: 사용자 자격 증명이 유효한 경우에 대해 테스트.doesRedirectToDashboard
: 유효한 자격 증명으로 로그인할 때 대시보드로 리디렉션되는지 확인.function testCalculateTotalPrice_whenItemIsAdded_doesIncreaseTotalPrice() {
// 상품 추가 시 총 가격이 증가하는지 테스트
}
testCalculateTotalPrice
: 총 가격 계산 기능을 테스트.whenItemIsAdded
: 아이템이 장바구니에 추가될 때.doesIncreaseTotalPrice
: 아이템을 추가하면 총 가격이 증가하는지 확인.구체적이고 설명적이어야 한다. 지나치게 짧거나 모호한 이름을 피하고, 테스트가 무엇을, 언제, 어떻게 확인하는지 명확하게 나타내야 한다.
너무 긴 이름은 가독성을 떨어뜨릴 수 있으므로 적당히 사용한다.
밑줄을 접두사나 접미사로 사용하지 않기:
식별자는 가능하면 의미가 명확해야 하며, 밑줄을 접두사나 접미사로 사용할 경우 어떤 의미가 있는지 또는 그 식별자가 특별한 목적을 가지고 있는지 명확히 전달되지 않는다.
단독으로 밑줄 사용 금지:
식별자가 의미를 가지지 않게 된다. 변수나 매개변수는 그 목적이 분명해야 한다.
(파이썬에서는 매개변수가 사용되지 않음을 나타내는 경우 단독으로 밑줄을 사용함)
구조 분해 할당을 사용할 때, 배열이나 튜플에서 불필요한 요소를 무시하려면 단순히 중간에 ,를 삽입하여 해당 요소를 무시할 수 있다.
const [a, , b] = [1, 5, 10]; // a <- 1, b <- 10, 중간 요소 5는 무시
모듈 네임스페이스 (camelCase):
모듈을 네임스페이스로 가져올 때는 camelCase를 사용한다.
import * as fooBar from './foo_bar'; // 올바른 네임스페이스 네이밍
파일 이름 (snake_case):
파일 이름은 snake_case를 사용해야 하며, 이는 소문자와 밑줄(_)로 단어를 구분하는 스타일이다. 예를 들어 foo_bar.ts와 같이 작성된다.
(작성자 첨언) 그러나 모듈과 파일 이름은 camelCase나 kebab-case를 사용하기도 한다.
CONSTANT_CASE의 사용:
상수(Constant) 값에 CONSTANT_CASE를 사용하여 변하지 않아야 하는 값들을 명확하게 표시하고, 이를 통해 코드에서 해당 값을 수정하지 않도록 유도한다.
static readonly와 CONSTANT_CASE:
클래스에서 static readonly
속성도 상수로 다루어질 수 있다. readonly
키워드를 사용하면 해당 속성의 값을 변경할 수 없다는 점에서 불변성을 보장할 수 있다.
class Foo {
private static readonly MY_SPECIAL_NUMBER = 5;
bar() {
return 2 * Foo.MY_SPECIAL_NUMBER;
}
}
Global Scope와 CONSTANT_CASE:
CONSTANT_CASE는 모듈 수준에서만 사용된다. 모듈의 최상위에서 정의된 상수값에 대해서만 CONSTANT_CASE를 사용하는 것이 권장된다. 지역 변수나 함수 내부에서 선언된 값은 camelCase를 사용해야 한다.
로컬 별칭은 기존 심볼의 네이밍 규칙과 형식을 따르며, 그 목적에 맞는 적절한 선언 방법을 사용해야 한다.
기존 심볼의 네이밍 규칙을 따르기:
로컬에서 기존의 변수를 별칭으로 사용할 때, 별칭의 이름은 기존 심볼의 형식과 규칙을 따라야 한다. 예를 들어, 상수는 대문자 및 밑줄을 사용한 CONSTANT_CASE 형식을 따르고, 변수나 객체는 camelCase 형식을 사용해야 한다. 이렇게 하면 일관된 네이밍 규칙을 유지할 수 있다.
const { BrewStateEnum } = SomeType; // 기존 심볼
const CAPACITY = 5; // 기존 상수
BrewStateEnum
은 SomeType
에서 추출된 객체의 속성이다. 이 값을 사용할 때 로컬에서 새로운 이름을 지정할 수 있다.CAPACITY
는 값 5를 나타내는 상수이다. 이 값을 사용하려면 로컬에서 CAPACITY
라는 이름을 그대로 사용해야 한다.로컬 별칭 생성 방법:
로컬에서 별칭을 생성할 때, 변수와 클래스 필드에 대해 서로 다른 방식으로 선언해야 한다.
const
를 사용하여 선언해야 한다.readonly
속성을 사용하여 선언해야 한다.class Teapot {
readonly BrewStateEnum = BrewStateEnum; // 클래스 필드에서 BrewStateEnum을 읽기 전용으로 설정
readonly CAPACITY = CAPACITY; // 클래스 필드에서 CAPACITY를 읽기 전용으로 설정
}
BrewStateEnum
과 CAPACITY
는 각각 기존 값의 별칭이다. 클래스 필드에 대해 readonly
를 사용하면 불변 값임을 명확하게 나타낼 수 있다.템플릿에서의 별칭:
프레임워크나 템플릿을 사용할 때, 별칭을 생성하여 템플릿에 노출하려는 경우에도 이 규칙이 적용된다. 별칭을 만들 때 접근 제어자(예: public
, private
)를 올바르게 지정하는 것이 중요하다. 프레임워크에서는 특정 데이터나 속성을 템플릿에서 직접 사용할 수 있도록 노출해야 할 때가 많은데, 이때도 접근 제어자를 적절히 설정하여 외부에서 접근할 수 있는지, 또는 내부에서만 접근할 수 있는지를 정의해야 한다.
class Teapot {
public readonly BrewStateEnum = BrewStateEnum; // 템플릿에서 사용될 수 있도록 공개
private readonly CAPACITY = CAPACITY; // 내부에서만 사용될 수 있도록 제한
}
public
접근 제어자는 템플릿에서 이 값을 사용할 수 있도록 함.private
접근 제어자는 템플릿에서 사용되지 않도록 하여, 외부 접근을 제한.GitHub - google/gts: ☂️ TypeScript style guide, formatter, and linter.
Typescript Google Code Style Part 1
Typescript Google Code Style Part 2
Typescript Google Code Style Part 3