| name | code-style-core |
| description | 通用 TypeScript 代码规范(命名·类型·注释·格式),适用于任何 TS/TSX 项目。编写、审查或重构 .ts/.tsx 文件时使用,尤其涉及文件命名(kebab-case + 角色后缀 / PascalCase.tsx)、标识符命名(I 前缀/_ 前缀/$ 后缀/SCREAMING_SNAKE/is-has-should-can)、interface vs type 选择、Nullable<T>、enum vs 联合类型、class 成员顺序、注释语言与密度、缩进引号分号等格式硬约束时。这是所有 code-style-* 系列 skill 的基础层。 |
通用代码规范 — 核心层 (命名 / 类型 / 注释 / 格式)
概述
通用 TypeScript 编码规范,不绑定任何框架或架构。配套进阶 skill(按需安装):
code-style-architecture — DI / 服务化 / 插件化 / 命令模式 / RxJS
code-style-react — React 组件规范
code-style-monorepo — monorepo 拆包与跨端工程化
必背命名速查 (违反必改)
| 类别 | 规则 | 示例 |
|---|
| 普通 TS 文件 | kebab-case + 角色后缀 | session.service.ts, create-session.command.ts |
| React 组件文件 | PascalCase.tsx | SessionList.tsx |
| Hook 文件 | use-<name>.ts(x) | use-host-tree.ts |
| 目录 | kebab-case(组件所在目录也是) | terminal-tabs/, views/hooks/ |
| 测试文件 | __tests__/<name>.spec.ts | __tests__/session.service.spec.ts |
| 接口 | I 前缀 | ISessionConfig, ICommandService |
| 私有成员 | _ 前缀(含 protected) | private readonly _sessionMap |
| Observable 属性 | $ 后缀 | sessions$, _currentTheme$ |
| 常量 | SCREAMING_SNAKE | DEFAULT_TERM_TYPES, XXX_PLUGIN_NAME |
| 布尔值 | is/has/should/can 前缀 | isConnected, hasPendingWrites |
| 本地事件处理函数 | handleXxx | handleContextMenu |
| Props 回调 | onXxx | onSelect, onClose |
| 泛型参数 | T 主类型;U/V 次要;K key;P params;R return | Map<K, V> |
| 枚举 | PascalCase 名 + PascalCase 成员 | enum LogLevel { Silent, Error } |
Service 后缀是硬性的(个人偏好,全项目一致):任何注册进 DI 的服务,接口、实现类、文件名三者都以 Service 结尾,即使职责是 router / bus / manager / registry。
❌ IDeepLinkRouter / DeepLinkRouter / deep-link.router.ts
✅ IDeepLinkRouterService / DeepLinkRouterService / deep-link-router.service.ts
例外:*Controller 与 *Plugin 保留各自后缀;纯协议门面可留 Client 中缀但仍以 Service 结尾(IRPCClientService)。
类型硬规则
- 对象结构用
interface,联合/函数签名/派生用 type
- 联合类型优先于 enum:
type Status = 'idle' | 'connecting';需要反查或数值语义才用 enum
- 可空统一
Nullable<T>(项目工具类型),禁止散写 T | null | undefined
- DI 注入参数与 Observable 字段一律
readonly
any 默认避免(lint 至少 warn);与底层库互操作的目录可局部豁免,但豁免范围要在 lint 配置显式声明
- 异步函数不加命名前缀,靠
async + Promise<T> 返回类型表达
格式硬约束 (lint 卡)
- 缩进 2 空格、单引号、必须分号
- 箭头函数参数始终带括号:
(x) => x
if 必须用大括号,禁止 if (!v) return; 单行写法(lint 只卡 multi-line,本条按个人偏好从严)
- 多行结构带尾逗号,函数参数列表不带
- 文件末尾保留一个换行;连续空行最多 1 行
- import 排序交给 lint(perfectionist),不手动维护
注释规范
- 代码内注释一律英文,只解释 why 不解释 what,禁止 emoji / 装饰边框 / 多段落
- 密度低:好代码大部分行不需要注释;出现注释说明这里有非直觉的约束
- TODO 格式:
// TODO: <说明> 或 // TODO(@author): <说明>
- JSDoc 只用于对外公开 API(facade / 包入口导出),带
@param / @returns / @example;内部实现不写 JSDoc
- 若项目要求 License 头,用 lint(
header/header)强制到所有 .ts/.tsx,不靠人工
章节索引 — 按需打开
| # | 主题 | 文件 | 何时查阅 |
|---|
| 1 | 命名细则 | references/01-naming.md | 命名拿不准、新建文件/目录时 |
| 2 | TypeScript 类型与 class 结构 | references/02-typescript.md | 类型选择、class 成员排序、abstract 使用时 |
| 3 | 注释·格式·lint 基线 | references/03-comments-style.md | 配 lint、写注释、争论格式时 |