Agent Skills
› lobehub/lobehub
› typescript
typescript
GitHub提供 TypeScript 编码规范,涵盖类型安全、异步 IO 最佳实践、导入管理及代码结构,旨在提升代码质量与可维护性。
Trigger Scenarios
编写或修改 TypeScript/TSX 代码
进行 TypeScript 代码审查
Install
npx skills add lobehub/lobehub --skill typescript -g -y
SKILL.md
Frontmatter
{
"name": "typescript",
"description": "Use for TypeScript style and type safety when editing TS\/TSX\/MTS, including imports, async code and error suppression.",
"user-invocable": false
}
TypeScript Code Style Guide
Types and Type Safety
- Avoid explicit type annotations when TypeScript can infer
- Avoid implicitly
any; explicitly type when necessary - Use accurate types: prefer
Record<PropertyKey, unknown>overobjectorany - Prefer
interfacefor object shapes (e.g., React props); usetypefor unions/intersections - Prefer
as const satisfies XyzInterfaceover plainas const - Prefer
@ts-expect-errorover@ts-ignoreoveras any - Avoid meaningless null/undefined parameters; design strict function contracts
- Prefer ES module augmentation (
declare module '...') overnamespace; do not introducenamespace-based extension patterns - When a type needs extensibility, expose a small mergeable interface at the source type and let each feature/plugin augment it locally instead of centralizing all extension fields in one registry file
- For package-local extensibility patterns like
PipelineContext.metadata, define the metadata fields next to the processor/provider/plugin that reads or writes them
Async Patterns
- Async-first for IO: new IO code (fs, child_process, etc.) must use async APIs at its boundaries — use promise-based variants like
import { readFile } from 'fs/promises', never*Syncby default. Function coloring is asymmetric: async→sync migration is never needed, while sync→async (when IO gets slower, gains concurrency, or grows a subprocess/network call) forces rewriting every caller up the chain — sync-first debt that compounds. Micro-costs of async (thread-pool dispatch, cache races) are not valid reasons: races are solved by caching the promise instead of the result *Syncis acceptable in exactly one place: call sites locked inside a synchronous contract you don't control — an existing sync signature chain (don't virally refactor a legacy sync chain in a bugfix, but new standalone modules must not extend such chains), or sync-only callbacks likeprocess.on('exit'). Module-load-time and CLI startup init are NOT exceptions — use top-levelawait(ESM) there
Imports
- Let lint enforce
simple-import-sort/importsandconsistent-type-importswith separateimport typestatements (fixStyle: 'separate-type-imports').
Code Structure
- Prefer named exports over
export default— keeps refactor renames and IDE auto-import in sync, and avoids thedefaultre-naming drift you get withimport Foo from './foo'. Reserveexport defaultfor files where the framework requires it (Next.js page/route/layout, React.lazy targets, config files likevitest.config.ts). The codebase still has manyexport defaultoccurrences — that's historical debt, not a pattern to copy; do not model new code on existingexport defaultusage outside the framework-required cases above
Reusability
- Before adding guards, parsing, normalization, timing, or JSON-safe helpers, search
packages/utilsand installed packages. Reuse@lobechat/utilsor its relevant subpath instead of duplicating helpers across features. - Do not hand-roll reusable record/object-map guards such as
typeof value === 'object' && value !== null; import helpers likeisRecord,isPlainRecord,isObjectLike,toRecord,pickString,UnknownRecord, etc. from@lobechat/utils/object. - Assign
Date.now()to a constant once and reuse for consistency
Logging
- Never log user private information (API keys, etc.)
- Don't use
import { log } from 'debug'directly (logs to console) - Use
console.errorin catch blocks instead of debug package - Always log the error in
.catch()callbacks — silent.catch(() => fallback)swallows failures and makes debugging impossible
Version History
- aace12f Current 2026-10-20 06:06
- 69012b8 2026-09-28 20:15
- e0d4b61 2026-09-23 09:53
- 29fe043 2026-08-20 18:34


