mcpField
S
shared-tooling-typescript-config

shared-tooling-typescript-config

github.com/agents-inc开发2677 次安装2 天前更新
代码仓库

关于 shared-tooling-typescript-config

为 TypeScript 项目提供严格配置与共享 tsconfig 模式的实践指南,适用于新建或维护项目的开发者。内容涵盖现代模块选项、路径别名同步及不同项目类型的配置取舍。

主要功能

  1. 01严格类型检查选项
  2. 02单仓库共享配置模式
  3. 03现代模块解析设置
  4. 04跨配置同步路径别名
  5. 05TS 5.x 与 6.0 选项指导

适用场景

  1. 01为新项目启用严格模式
  2. 02统一单仓库各包的 tsconfig
  3. 03配置基于打包器的模块设置
  4. 04迁移弃用选项并评估新特性

安装

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

$npx skills add https://github.com/agents-inc/skills --skill shared-tooling-typescript-config

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

metadata.yaml
reference.md
examples/
core.md

详细介绍

TypeScript 配置模式

快速指南: 在 packages/typescript-config/ 中使用共享的 TypeScript 严格配置。启用 strict: true,以及 noUncheckedIndexedAccess、exactOptionalPropertyTypes、noImplicitOverride。使用现代模块设置:module: "preserve"、moduleResolution: "bundler"、verbatimModuleSyntax: true、moduleDetection: "force"。使用 ${configDir}(TS 5.5+)设置可移植路径。在 tsconfig 和构建工具之间同步路径别名。


<critical_requirements>

重要:使用此技能前

(你必须在所有 tsconfig.json 文件中启用 TypeScript 严格模式(strict: true),这是不可妥协的要求)

(你必须使用 verbatimModuleSyntax: true 来强制显式使用 import type,以取代已弃用的 importsNotUsedAsValues)

(在 monorepo 中,你必须使用共享配置模式(packages/typescript-config/),绝不能为每个包重复配置)

(你必须在 tsconfig.json 和构建工具之间同步路径别名,不匹配会导致导入解析失败)

(对于基于打包工具的项目,你必须使用现代模块设置:module: "preserve"、moduleResolution: "bundler")

</critical_requirements>


自动检测: TypeScript 配置、tsconfig.json、tsconfig、严格模式、noUncheckedIndexedAccess、exactOptionalPropertyTypes、verbatimModuleSyntax、moduleDetection force、module preserve、moduleResolution bundler、configDir、路径别名、typescript-config、共享配置、noImplicitOverride、isolatedDeclarations、erasableSyntaxOnly、import defer

适用场景:

  • 在新项目或现有项目中设置 TypeScript 严格模式
  • 创建共享 tsconfig 模式,确保 monorepo 配置一致
  • 配置 TS 5.x+ 现代模块设置(preserve、bundler、verbatimModuleSyntax)
  • 在 tsconfig 和构建工具之间同步路径别名
  • 创建专用配置(React、Node.js、库发布)
  • 从已弃用的 TypeScript 选项迁移
  • 评估新的 TS 特性(isolatedDeclarations、erasableSyntaxOnly、configDir、import defer)

不适用场景:

  • TypeScript 运行时代码模式(请参阅语言/框架相关技能)
  • Linter 配置(请使用单独的技能)
  • 构建工具配置(请使用单独的技能)——但此处仍应保留路径别名同步指南
  • 命名和导入等日常编码规范(请参阅 CLAUDE.md)

涵盖的核心模式:

  • 用于 monorepo 扩展模式的共享严格配置基准
  • 现代模块设置(TS 5.x+:preserve、bundler、verbatimModuleSyntax、moduleDetection)
  • 用于可移植共享配置的 ${configDir} 模板变量(TS 5.5+)
  • tsconfig 与构建工具之间的路径别名同步
  • 专用配置(react.json、node.json、library.json)
  • 用于支持并行构建的 isolatedDeclarations(TS 5.5+)
  • 用于 Node.js 直接执行的 erasableSyntaxOnly(TS 5.8+)
  • 用于延迟模块求值的 import defer(TS 5.9+)
  • TypeScript 6.0 的新默认值和弃用项

详细资源:


理念

TypeScript 配置应当默认严格、在各个包之间共享,并能面向未来。每个项目都从最严格的设置开始。共享配置可避免偏移。现代模块设置与基于打包工具的工作流保持一致。

核心原则:

  1. 默认严格 - strict: true,以及 noUncheckedIndexedAccess、exactOptionalPropertyTypes、noImplicitOverride
  2. 共享而非重复 - Monorepo 配置扩展共享基准;独立项目使用相同的严格选项
  3. 现代模块模式 - 对于打包工具项目,使用 module: "preserve" + moduleResolution: "bundler";对于 Node.js,使用 "node18"/"node20"
  4. 路径别名一致 - 别名必须同时存在于 tsconfig 和构建工具中

核心模式

模式 1:共享严格配置基底

所有应用和包都扩展共享的严格基底。基底配置位于 packages/typescript-config/(单仓库)中,或内联在独立项目中。

// packages/typescript-config/base.json (abbreviated)
{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "module": "preserve",
    "moduleResolution": "bundler",
    "verbatimModuleSyntax": true
  }
}

使用方配置扩展共享基底,并且只添加有差异的内容(例如 paths)。

优点: 严格设置只有一个事实来源,所有包都能获得相同的安全保障,使用方只需添加有差异的内容

完整的基底配置、使用方配置和专用配置(react.json、node.json、library.json)请参见 examples/core.md。


模式 2:现代模块设置(TS 5.x+)
verbatimModuleSyntax(TS 5.0+)

强制对仅用于类型的导入显式使用 import type。替代已弃用的 importsNotUsedAsValues 和 preserveValueImports。

// With verbatimModuleSyntax: true

// Good - explicit type import
import type { User } from "./types";
import { createUser } from "./api";

// Bad - type imported as value (errors with verbatimModuleSyntax)
import { User, createUser } from "./api";
module: "preserve"(TS 5.4+)

原样保留导入/导出语法。TypeScript 只进行类型检查;模块输出由打包工具处理。

适用场景: 基于打包工具的项目,其中 TypeScript 不会生成 JavaScript(noEmit: true)

不适用场景: 直接生成 CJS/ESM 的 Node.js 包——改用 module: "node18" 或 "node20"

moduleDetection: "force"(TS 5.0+)

强制将所有文件视为模块,即使没有 import/export。防止意外污染全局作用域。


模式 3:${configDir} 模板变量(TS 5.5+)

使共享配置具有可移植性。${configDir} 会解析为叶级配置(即扩展其他配置的配置文件)所在目录,而非基底配置所在目录。

// packages/typescript-config/base.json
{
  "compilerOptions": {
    "outDir": "${configDir}/dist",
    "rootDir": "${configDir}/src"
  },
  "include": ["${configDir}/src"]
}

优点: 使用方无需覆盖 outDir、rootDir 或 include——路径会相对于其自身目录解析

注意事项: 如果不使用 ${configDir},像 "./dist" 这样的相对路径会从基底配置所在位置(packages/typescript-config/)解析,而非从使用该配置的包解析。


模式 4:路径别名同步

路径别名必须同时配置在 tsconfig.json 和构建工具中。不匹配会导致 TypeScript 错误或构建时导入解析失败。

// tsconfig.json -- paths here for TypeScript type checking
{ "compilerOptions": { "paths": { "@/*": ["./src/*"] } } }

// Build tool config -- SAME aliases for bundler resolution
// resolve: { alias: { "@": path.resolve(__dirname, "./src") } }

注意事项: 忘记同步会导致“找不到模块”错误。TypeScript 可以正常解析,但打包工具会失败(反之亦然)。添加新别名时,务必同时更新两个文件。

完整的 tsconfig 和构建工具配置示例请参见 examples/core.md。


模式 5:isolatedDeclarations(TS 5.5+)

要求为所有导出显式添加类型注解。支持外部工具(oxc、swc)并行生成 .d.ts。

// With isolatedDeclarations: true

// Good - explicit return type on export
export function getUser(id: string): User {
  return { id, name: "John" };
}

// Bad - inferred return type (will error)
export function getUser(id: string) {
  return { id, name: "John" };
}

适用场景: 发布库包的大型单仓库项目,在这些项目中,并行生成 .d.ts 可加快构建速度

不适用场景: 永远不会作为库使用的应用代码(只会增加冗长程度,没有实际收益)


模式 6:erasableSyntaxOnly(TS 5.8+)

禁止具有运行时行为的 TypeScript 专属构造(枚举、命名空间、参数属性)。确保兼容 Node.js --experimental-strip-types,以便直接执行 TS。

禁止的构造: enum、const enum、运行时 namespace、参数属性(constructor(public name: string))

允许的构造: type、interface、仅用于类型的导入——任何可擦除且不会改变运行时行为的内容

适用场景: 使用 Node.js 直接执行 TS 的项目,或采用仅类型理念的项目

不适用场景: 严重依赖枚举、命名空间或参数属性的项目

完整的正反例代码请参见 examples/core.md。


模式 7:import defer(TS 5.9+)

延迟模块求值——模块会加载,但只有在访问某个导出时才会执行。仅在 --module preserve 或 esnext 下与命名空间导入搭配使用。

import * as analytics from "./heavy-analytics.js";

// Module is loaded but NOT executed yet
if (needsAnalytics) {
  analytics.track("event"); // Module executes here on first access
}

适用场景: 提升有条件加载的重型模块的启动性能

限制: import defer 不支持命名导入和默认导入——只能使用命名空间语法(import defer * as ...)


模式 8:TypeScript 6.0 新默认值

TS 6.0(2026 年 2 月)调整了多个默认值。如果你的配置已遵循上述模式,大多数改动都不会产生影响。

选项旧默认值TS 6.0 默认值
strictfalsetrue
modulecommonjsesnext
targetes3es2025
rootDir推断.(当前目录)
types自动发现 @types/*[](仅显式指定)
noUncheckedSideEffectImportsfalsetrue
libReplacementtruefalse

需要采取的操作: 升级到 TS 6.0 后,显式设置 "types": ["node"](或相关包)——自动发现 @types/* 的功能已移除。

TS 6.0 中已弃用(将在 TS 7.0 中移除):

  • target: "es5"、moduleResolution: "node"(node10)、module: "amd"|"umd"|"systemjs"|"none"
  • esModuleInterop: false、将 --baseUrl 用作模块解析根目录、--outFile

迁移期间使用 "ignoreDeprecations": "6.0" 可抑制警告。

完整的 TS 6.0 默认值表及弃用详情,请参阅 examples/core.md。


模式 9:NoInfer 工具类型(TS 5.4+)

防止 TypeScript 在泛型函数的特定位置推断类型。

// Good - NoInfer ensures initial must be from states array
declare function createFSM<TState extends string>(config: {
  initial: NoInfer<TState>;
  states: TState[];
}): void;

createFSM({
  initial: "invalid", // Error: "invalid" not in states
  states: ["open", "closed"],
});

优点: TypeScript 只会从 states 推断 TState;initial 必须匹配,但不会扩大联合类型

适用场景: 一个参数应约束另一个参数,而不是扩大推断类型的泛型函数


<decision_framework>

决策框架

模块设置选择
What module/moduleResolution to use?
├─ Bundler-based project (TypeScript does NOT emit JS)?
│   └─ YES -> module: "preserve", moduleResolution: "bundler"
├─ Node.js package (direct execution)?
│   ├─ Node 20+? -> module: "node20" (TS 5.9+, stable)
│   └─ Node 18+? -> module: "node18" (TS 5.8+)
└─ Library consumed by both bundlers and Node?
    └─ module: "nodenext" (most compatible)
Target 选择
What target to use?
├─ Bundler-based project? -> target: "ES2022" (stable, well-supported)
├─ Node.js 18+? -> target: "ES2022"
├─ Node.js 20+? -> target: "ES2023"
└─ TS 6.0+ project? -> target: "es2025" (new default)
新功能采用
isolatedDeclarations?
├─ Publishing library packages in large monorepo? -> Enable
├─ Application code only? -> Skip (adds verbosity for no benefit)
└─ Using oxc or swc for builds? -> Enable (these tools benefit most)

erasableSyntaxOnly?
├─ Using Node.js --experimental-strip-types? -> Enable (required)
├─ Project uses enums extensively? -> Skip (migration cost too high)
└─ Standard bundler project? -> Optional (nice-to-have)

其他决策框架(共享配置与本地配置、TS 6.0 迁移)请参阅 reference.md。

</decision_framework>


<red_flags>

危险信号

高优先级问题:

  • 禁用 TypeScript 严格模式(strict: false)——会导致整个项目中出现隐式 any 和 null 相关错误
  • 缺少 verbatimModuleSyntax: true——类型导入是否会被移除取决于转译器
  • 在 monorepo 中未使用共享配置——配置会逐渐偏离,导致各个包的安全级别不一致
  • 使用已弃用的 importsNotUsedAsValues 或 preserveValueImports——自 TS 5.0 起已由 verbatimModuleSyntax 取代

中优先级问题:

  • 在 tsconfig 中配置了路径别名,却未在构建工具中配置(或反之)——会导致导入解析失败
  • 使用已弃用的 moduleResolution: "node"(node10),而非 "bundler" 或 "node18"——在 TS 6.0 中已弃用
  • 使用已弃用的 target: "ES3" 或 "ES5"——在 TS 6.0 中已弃用,并将在 TS 7.0 中移除
  • 每个包都重复配置,而非继承共享基础配置

注意事项与边缘情况:

  • ${configDir} 解析为叶级配置(即使用 extends 的配置)所在目录,而非基础配置所在目录
  • verbatimModuleSyntax 要求所有仅用于类型的导入都使用 import type——如果 Type 仅用于类型,混合导入(如 import { Type, value })会报错。请使用内联语法:import { type Type, value }
  • exactOptionalPropertyTypes 表示 { key?: string } 不接受 { key: undefined }——只能省略该属性或使用 string
  • noUncheckedIndexedAccess 会为所有索引签名(包括数组)添加 | undefined——请使用 for...of 或通过 if 进行保护
  • module: "preserve" 仅适用于 noEmit: true 或 emitDeclarationOnly: true
  • TS 6.0 会将 types 的默认值改为 []——升级后必须显式列出 @types/node、@types/react 等
  • import defer 仅支持命名空间语法(import defer * as ...),不支持命名导入或默认导入

</red_flags>


<critical_reminders>

重要提醒

(必须在所有 tsconfig.json 文件中启用 TypeScript 严格模式(strict: true),此项不可妥协)

(必须使用 verbatimModuleSyntax: true 强制显式使用 import type,它已取代弃用的 importsNotUsedAsValues)

(在 monorepo 中必须使用共享配置模式(packages/typescript-config/),绝不可为每个包重复配置)

(必须确保 tsconfig.json 与构建工具中的路径别名保持一致——不一致会导致导入解析失败)

(必须使用现代模块设置:基于打包器的项目应使用 module: "preserve"、moduleResolution: "bundler")

不遵守这些规则会导致类型安全漏洞、配置不一致以及导入解析失败。

</critical_reminders>

评论

支持 Markdown