本示例约定三块:① TS 源码面板展示带类型标注的代码;② tsc 类型检查面板是「写死的、真实的」编译器报错样本;③ 等价 JS 面板去掉类型后可点着真跑。类型检查一栏并非现场运行 tsc,是预先写好的输出。
let count = 0 // 推断为 number
const title = 'TS' // 推断为字面量类型 'TS'(const 窄化)
function add(a: number, b: number) {
return a + b // 返回值被推断为 number
}
let bad: number = 'oops' // ✗ 类型错误:字符串赋给 number 标注
: number 是硬约束,初值 'oops' 是 string,编译器要求二者对得上——这条错误拦住了「把字符串当数字用」的隐患。擦除类型后,这就是真正被执行的代码。注意 bad 在 JS 里照样能赋值,只是运行时它是字符串。
JSON.parse 的 any 泄漏function parse1(input: string) {
return JSON.parse(input) // 返回值被推断成 any —— 不确定性从这里开始
}
function parse2(input: string): User {
return JSON.parse(input) // 补一个返回注解,把 any 挡在函数边界内
}
const u = parse1('{"name":"阿蓝"}')
u.name.foo.bar // 一路不报错——any 顺着返回值传染了出去
return 反推,JSON.parse 的返回是 any,于是整条链都失去检查。给 parse2 显式标注返回 User,是把不确定挡在边界——这也是公共函数建议写返回类型的原因。