mcpField
T
typescript-naming

typescript-naming

github.com/mkosir开发78541 次安装8 周前更新
代码仓库

关于 typescript-naming

用于在当前任务中应用 TypeScript 命名规范的技能。它帮助开发者优先遵循仓库现有规则,并避免引入无关改动。

主要功能

  1. 01优先检查仓库规范
  2. 02变量与类型命名指导
  3. 03React 命名建议
  4. 04注释与 TSDoc 指导

适用场景

  1. 01审查现有 TypeScript 代码命名
  2. 02为新函数和类型选择名称
  3. 03使用 TSDoc 编写可复用 API 文档

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mkosir/typescript-style-guide --skill typescript-naming

安装后在 Claude Code 中输入/typescript-naming确认已加载。

详细介绍

命名

在当前任务的上下文中,遵循 TypeScript 风格指南的命名约定。

工作流

  1. 检查所使用仓库的约定和配置。
  2. 明确的仓库约定优先于本指南中的特定建议。
  3. 仅应用、审查或说明与任务相关的指南。
  4. 当合适的名称或文档取决于上下文或判断时,说明重要的权衡。

边界

  • 由 ESLint 和其他工具负责自动检查可强制执行的规则。
  • 不要仅仅因为启用了此技能,就引入无关的 TypeScript 风格指南约定。

相关指南

使用 Satisfies 实现类型安全的常量

如需了解如何针对现有类型验证常量的详细指南,请在可用时使用 typescript-types。

命名

努力保持命名约定一致且易于阅读,并提供重要的上下文,因为你编写的代码将由他人维护。

命名导出

<Rule prefix="Named exports must be used to ensure that all imports follow a uniform pattern" href="https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-default-export.md"

{export default [ { rules: { 'import/no-default-export': 'error' }, }, // In case of exceptions disable the rule { files: ['src/pages/**/*'], rules: { 'import/no-default-export': 'off' }, }, ]; }

这样可以确保整个代码库中的变量和函数名称保持一致。命名导出的优点是,当导入语句尝试导入未声明的内容时会报错。

命名约定

虽然通常很难找到最佳名称,但应遵循以下约定,以提升代码的一致性,并方便未来的读者:

变量 {#variables-1}
  • 局部变量
    驼峰命名法
    products、productsFiltered

  • 布尔值
    前缀使用 is、has 等
    isDisabled、hasProduct

    {`'@typescript-eslint/naming-convention': [ 'error', { selector: 'variable', types: ['boolean'], format: ['PascalCase'], prefix: ['is', 'are', 'should', 'has', 'can', 'did', 'will'], } ] `}
  • 常量
    首字母大写

    const FEATURED_PRODUCT_ID = '8f47d2a1-b13e-4d5a-a7d8-6ef1234';
    
  • 对象和数组常量

    使用单数形式、首字母大写,并带有 const 断言。

    const IDLE_ORDER = {
      pending: 'idle',
      fulfilled: true,
      error: 'Shipping Error',
    } as const;
    
    const DASHBOARD_ACCESS_ROLES = ['admin', 'editor', 'moderator'] as const;
    

    如果存在类型,请使用使用 Satisfies 实现类型安全的常量。

    // Type OrderStatus is predefined (e.g. generated from database schema, API)
    type OrderStatus = {
      pending: 'pending' | 'idle';
      fulfilled: boolean;
      error: string;
    };
    
    const IDLE_ORDER = {
      pending: 'idle',
      fulfilled: true,
      error: 'Shipping Error',
    } as const satisfies OrderStatus;
    
    // Type UserRole is predefined
    type UserRole = 'admin' | 'editor' | 'moderator' | 'viewer' | 'guest';
    
    const DASHBOARD_ACCESS_ROLES = ['admin', 'editor', 'moderator'] as const satisfies ReadonlyArray<UserRole>;
    
函数 {#functions-1}

驼峰命名法
filterProductsByType、formatCurrency

类型 {#types-1}

帕斯卡命名法
OrderStatus、ProductItem

{` '@typescript-eslint/naming-convention': [ 'error', { selector: 'typeAlias', format: ['PascalCase'], }, ]`}
泛型

泛型类型参数必须以大写字母 T 开头,后接描述性名称,例如 TRequest、TFooBar。

主要原因和优点:

  • 复杂类型通常会涉及泛型,清晰的命名有助于提高可读性和可维护性。
  • 不允许使用 T、K 和 U 这类单字母泛型。引入的参数越多,就越容易混淆。
  • 使用 T 作为前缀,可以立即看出这是泛型类型参数,而不是普通类型。
  • 一种常见情况是泛型参数与现有类型同名,导致名称遮蔽,例如 <Request extends Request>。
{`'@typescript-eslint/naming-convention': [ 'error', { // Generic type parameter must start with letter T, followed by any uppercase letter. selector: 'typeParameter', format: ['PascalCase'], custom: { regex: '^T[A-Z]', match: true }, } ]`}
// ❌ Avoid naming generic parameters with one letter
const createPair = <T, K extends string>(first: T, second: K): [T, K] => {
  return [first, second];
};
const pair = createPair(1, 'a');

// ✅ Use descriptive names starting with capital T
const createPair = <TFirst, TSecond extends string>(first: TFirst, second: TSecond): [TFirst, TSecond] => {
  return [first, second];
};
const pair = createPair(1, 'a');

// ❌ Avoid naming generic parameters without a prefix - which 'Request' is which?
const handle = <Request extends Request>(req: Request): void => {...

// ✅ Prefix generic parameter with capital T
const handle = <TRequest extends Request>(req: TRequest): void => {...
缩写与首字母缩略词

将首字母缩略词视为完整单词,仅首字母大写。

// ❌ Avoid
const FAQList = ['qa-1', 'qa-2'];
const generateUserURL(params) => {...}

// ✅ Use
const FaqList = ['qa-1', 'qa-2'];
const generateUserUrl(params) => {...}

为提高可读性,应尽量避免使用缩写,除非它们广为接受且确有必要。

// ❌ Avoid
const GetWin(params) => {...}

// ✅ Use
const GetWindow(params) => {...}
React 组件

帕斯卡命名法
ProductItem、ProductsPage

属性类型

React 组件名称后加上 “Props” 后缀
[ComponentName]Props - ProductItemProps、ProductsPageProps

回调属性

事件处理程序(回调)属性以 on* 为前缀,例如 onClick。
事件处理程序实现函数以 handle* 为前缀,例如 handleClick。

{'react/jsx-handler-names': [ 'error', { eventHandlerPrefix: 'handle', eventHandlerPropPrefix: 'on', }, ]}

// ❌ Avoid inconsistent callback prop naming
<Button click={actionClick} />
<MyComponent userSelectedOccurred={triggerUser} />

// ✅ Use prop prefix 'on*' and handler prefix 'handle*'
<Button onClick={handleClick} />
<MyComponent onUserSelected={handleUserSelected} />
React Hooks

<Rule prefix="驼峰命名法,前缀为 'use'" href="https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks"

{'react-hooks/rules-of-hooks': 'error'} <Rule prefix="对称命名约定:[value, setValue] = useState()" href="https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/hook-use-state.md#rule-details" {'react/hook-use-state': 'error'}

// ❌ Avoid inconsistent useState hook naming
const [userName, setUser] = useState();
const [color, updateColor] = useState();
const [isActive, setActive] = useState();

// ✅ Use
const [name, setName] = useState();
const [color, setColor] = useState();
const [isActive, setIsActive] = useState();

自定义 Hook 必须始终返回一个对象。

// ❌ Avoid
const [products, errors] = useGetProducts();
const [fontSizes] = useTheme();

// ✅ Use
const { products, errors } = useGetProducts();
const { fontSizes } = useTheme();
注释

注释很容易过时,带来的可能是困惑,而非清晰。

应通过使用有意义的名称和清晰的逻辑,优先编写表达清楚的代码,而不是添加注释。注释应主要解释“为什么”,而非“是什么”或“怎么做”。

在以下情况下使用注释:

  • 仅凭代码无法明显看出背景或原因时(例如配置文件、变通方案)
  • 引用相关问题、PR 或计划中的改进时
// ❌ Avoid
// convert to minutes
const m = s * 60;
// avg users per minute
const myAvg = u / m;

// ✅ Use - Prefer expressive code by naming things what they are
const SECONDS_IN_MINUTE = 60;
const minutes = seconds * SECONDS_IN_MINUTE;
const averageUsersPerMinute = noOfUsers / minutes;

// ✅ Use - Reference planned improvements
// TODO: Move filtering to the backend once API v2 is released.
// Issue/PR - https://github.com/foo/repo/pulls/55124
const filteredUsers = frontendFiltering(selectedUsers);

// ✅ Use - Add context to explain why
// Use Fourier transformation to minimize information loss - https://github.com/dntj/jsfft#usage
const frequencies = signal.FFT();
TSDoc 注释

TSDoc 统一了 TypeScript 文档注释的标准,让编辑器和文档工具能够以一致的方式解析注释。这能改善开发者体验,并支持生成 API 文档。

为 API、库、配置或可复用代码编写文档时,请使用 TSDoc 注释。

/**
 * Configuration options for the Web3 SDK.
 */
export type Web3Config = {
  /** Ethereum network chain ID. */
  chainId: number;

  /**
   * Gas price strategy for transactions:
   * - `fast`: Higher fees, faster confirmation
   * - `standard`: Balanced
   * - `slow`: Lower fees, slower confirmation
   */
  gasPriceStrategy: 'fast' | 'standard' | 'slow';

  /** Maximum gas limit per transaction. */
  maxGasLimit?: number;

  /** Enables event listening for smart contract interactions. */
  enableEventListener?: boolean;
};

评论

支持 Markdown