TypeScript code style and optimization guidelines. Use when writing TypeScript code (.ts, .tsx, .mts files), reviewing code quality, or implementing type-safe patterns...
any; explicitly type when necessaryRecord<PropertyKey, unknown> over object or anyinterface for object shapes (e.g., React props); use type for unions/intersectionsas const satisfies XyzInterface over plain as const@ts-expect-error over @ts-ignore over as anydeclare module '...') over namespace; do not introduce namespace-based extension patternsPipelineContext.metadata, define the metadata fields next to the processor/provider/plugin that reads or writes themasync/await over callbacks or .then() chains*Sync)import { readFile } from 'fs/promises'Promise.all, Promise.race for concurrent operations where safeThis project uses simple-import-sort/imports and consistent-type-imports (fixStyle: 'separate-type-imports')
Separate type imports: always use import type { ... } for type-only imports, NOT import { type ... } inline syntax
When a file already has import type { ... } from a package and you need to add a value import, keep them as two separate statements:
import type { ChatTopicBotContext } from '@lobechat/types';
import { RequestTrigger } from '@lobechat/types';
Within each import statement, specifiers are sorted alphabetically by name
export default — keeps refactor renames and IDE auto-import in sync, and avoids the default re-naming drift you get with import Foo from './foo'. Reserve export default for files where the framework requires it (Next.js page/route/layout, React.lazy targets, config files like vitest.config.ts). The codebase still has many export default occurrences — that's historical debt, not a pattern to copy; do not model new code on existing export default usage outside the framework-required cases abovepackages/utils first. If the helper already exists or clearly belongs there, import it from @lobechat/utils (or the relevant @lobechat/utils/* subpath) instead of duplicating tiny helpers across feature files.@lobehub/ui, Ant Design components instead of raw HTML tagsantd-style token system instead of hard-coded colorspackages/utils or installed npm packagestypeof value === 'object' && value !== null; import helpers like isRecord, isPlainRecord, isObjectLike, toRecord, pickString, UnknownRecord, etc. from @lobechat/utils/object.Date.now() to a constant once and reuse for consistencyimport { log } from 'debug' directly (logs to console)console.error in catch blocks instead of debug package.catch() callbacks — silent .catch(() => fallback) swallows failures and makes debugging impossible