三块面板:TS 源码 / 写死的 tsc 报错样本(非现场运行)/ 可点跑的等价 JS。这些坑几乎都源于第一章两件事:类型会被擦除、检查与转译互不干涉。
const data = JSON.parse(text) // JSON.parse 返回 any
data.user.profile.name // 一路都不报错,但每个点都可能运行时崩
type UserID = string
type OrderID = string
function getUser(u: UserID) {}
getUser(orderId) // ✓ 编译通过——两个都是 string,TS 不区分语义
catch (err) {
const msg = (err as MyError).message // 用 as 把 unknown 一步“吃”成想要的类型
} // 若抛的不是 MyError,运行时 msg 是 undefined
export { SomeType } from './types' // ✗ isolatedModules 下:SomeType 只是类型
export type { SomeType } from './types' // ✓ 纯类型重导出必须用 export type
// esbuild/SWC 一个文件一个文件独立转译,拿不到全局类型图,
// 因此“本地能跑”≠“类型没问题”:完整检查得靠 CI 里的 tsc --noEmit
export type,否则单文件转译时无法判断它到底是值还是类型——这正是「类型擦除」与「独立转译」之间的必然要求。