clean-typescript-names

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Clean Names

清晰命名

N1: Choose Descriptive Names

N1:选择具有描述性的名称

Names should reveal intent. If a name requires a comment, it doesn't reveal its intent.
ts
// Bad - what is d?
const d = 86400;

// Good - obvious meaning
const SECONDS_PER_DAY = 86400;

// Bad - what does this function do?
function proc(values: number[]) {
  return values.filter((value) => value > 0);
}

// Good - intent is clear
function filterPositiveNumbers(numbers: number[]) {
  return numbers.filter((number) => number > 0);
}
名称应能体现其用途。如果一个名称需要注释来解释,说明它未能清晰表达用途。
ts
// 不佳——d代表什么?
const d = 86400;

// 优良——含义一目了然
const SECONDS_PER_DAY = 86400;

// 不佳——这个函数的作用是什么?
function proc(values: number[]) {
  return values.filter((value) => value > 0);
}

// 优良——用途清晰明确
function filterPositiveNumbers(numbers: number[]) {
  return numbers.filter((number) => number > 0);
}

N2: Choose Names at the Appropriate Level of Abstraction

N2:选择符合抽象层级的名称

Don't pick names that communicate implementation; choose names that reflect the level of abstraction of the class or function.
ts
// Bad - too implementation-specific
function getMapOfUserIdsToNames() {
  // ...
}

// Good - abstracts the data structure
function getUserDirectory() {
  // ...
}
不要选择体现实现细节的名称;应选择能反映类或函数抽象层级的名称。
ts
// 不佳——过于关注实现细节
function getMapOfUserIdsToNames() {
  // ...
}

// 优良——对数据结构进行了抽象
function getUserDirectory() {
  // ...
}

N3: Use Standard Nomenclature Where Possible

N3:尽可能使用标准命名法

Use terms from the domain, design patterns, or well-known conventions.
ts
// Good - uses pattern name
class UserFactory {
  create(data: unknown) {
    // ...
  }
}

// Good - uses domain term
function calculateAmortization(principal: number, rate: number, term: number) {
  // ...
}
使用领域术语、设计模式或公认的约定术语。
ts
// 优良——使用了模式名称
class UserFactory {
  create(data: unknown) {
    // ...
  }
}

// 优良——使用了领域术语
function calculateAmortization(principal: number, rate: number, term: number) {
  // ...
}

N4: Unambiguous Names

N4:使用含义明确的名称

Choose names that make the workings of a function or variable unambiguous.
ts
// Bad - ambiguous
function rename(source: string, target: string) {
  // ...
}

// Good - clear what's being renamed
function renameFile(oldPath: string, newPath: string) {
  // ...
}
选择能让函数或变量的作用毫无歧义的名称。
ts
// 不佳——含义模糊
function rename(source: string, target: string) {
  // ...
}

// 优良——明确说明要重命名的对象
function renameFile(oldPath: string, newPath: string) {
  // ...
}

N5: Use Longer Names for Longer Scopes

N5:作用域越长,名称应越详细

Short names are fine for tiny scopes. Longer scopes need longer, more descriptive names.
ts
// Good - short name for tiny scope
const total = numbers.reduce((sum, n) => sum + n, 0);

// Good - longer name for module-level constant
const MAX_RETRY_ATTEMPTS_BEFORE_FAILURE = 5;

// Bad - short name at module level
const MAX = 5;
短名称适用于极小的作用域。较长的作用域需要更长、更具描述性的名称。
ts
// 优良——极小作用域使用短名称
const total = numbers.reduce((sum, n) => sum + n, 0);

// 优良——模块级常量使用较长名称
const MAX_RETRY_ATTEMPTS_BEFORE_FAILURE = 5;

// 不佳——模块级使用短名称
const MAX = 5;

N6: Avoid Encodings

N6:避免编码式命名

Don't encode type or scope information into names. Modern editors make this unnecessary.
ts
// Bad - Hungarian notation
const strName = "Alice";
const arrUsers: string[] = [];
const nCount = 0;

// Good - clean names
const name = "Alice";
const users: string[] = [];
const count = 0;

// Bad - interface prefix
interface IUserRepository {
  findById(id: string): Promise<unknown>;
}

// Good - just name it
interface UserRepository {
  findById(id: string): Promise<unknown>;
}
不要在名称中编码类型或作用域信息。现代编辑器已让这种做法不再必要。
ts
// 不佳——使用Hungarian notation
const strName = "Alice";
const arrUsers: string[] = [];
const nCount = 0;

// 优良——简洁名称
const name = "Alice";
const users: string[] = [];
const count = 0;

// 不佳——接口使用前缀
interface IUserRepository {
  findById(id: string): Promise<unknown>;
}

// 优良——直接命名
interface UserRepository {
  findById(id: string): Promise<unknown>;
}

N7: Names Should Describe Side Effects

N7:名称应描述副作用

If a function does something beyond what its name suggests, the name is misleading.
ts
const configStore = new Map<string, string>();

// Bad - name doesn't mention file creation
function getConfig(configPath: string) {
  if (!configStore.has(configPath)) {
    configStore.set(configPath, "{}"); // Hidden side effect!
  }
  return JSON.parse(configStore.get(configPath) ?? "{}");
}

// Good - name reveals behavior
function getOrCreateConfig(configPath: string) {
  if (!configStore.has(configPath)) {
    configStore.set(configPath, "{}");
  }
  return JSON.parse(configStore.get(configPath) ?? "{}");
}
如果函数的行为超出其名称所暗示的范围,这个名称就具有误导性。
ts
const configStore = new Map<string, string>();

// 不佳——名称未提及文件创建操作
function getConfig(configPath: string) {
  if (!configStore.has(configPath)) {
    configStore.set(configPath, "{}"); // 隐藏的副作用!
  }
  return JSON.parse(configStore.get(configPath) ?? "{}");
}

// 优良——名称揭示了实际行为
function getOrCreateConfig(configPath: string) {
  if (!configStore.has(configPath)) {
    configStore.set(configPath, "{}");
  }
  return JSON.parse(configStore.get(configPath) ?? "{}");
}