柳嘉希

硕士研究生毕业生

软件工程师 | 可扩展的API · 网络爬虫 · 数据集成 · Vibe代码清理专家

TypeScript 基础:为什么需要类型、编译与变量声明

TypeScript 的核心价值是把一部分错误提前到代码运行之前发现。JavaScript 很灵活,但也容易在运行时才暴露问题,例如变量类型变化、对象属性不存在、函数参数不符合预期。TypeScript 通过静态类型检查减少这类运行时异常。

编译与类型检查

TypeScript 代码通常不会直接在浏览器或 Node.js 中运行,而是先经过编译,转换成 JavaScript。这个过程中,编译器会检查类型是否合理。

需要注意的是,类型检查主要发生在开发和构建阶段;运行时执行的仍然是 JavaScript。

变量声明

现代 TypeScript/JavaScript 中优先使用 letconst

let count: number = 10;
count = 20;
 
const siteName: string = "Portfolio";

var 是函数作用域,容易出现变量提升和作用域污染,所以通常不建议使用。

if (true) {
  var message = "hello";
}
 
console.log(message); // 仍然可访问

letconst 是块级作用域,更符合现代开发习惯。

if (true) {
  let message = "hello";
}
 
// console.log(message); // 编译报错

类型推断

TypeScript 不要求每个变量都显式写类型。很多时候它可以根据初始值自动推断。

let name = "Alice"; // string
let age = 30; // number

一般原则是:简单变量可以依赖类型推断,函数参数、返回值、复杂对象结构更适合显式标注类型。

const 的细节

const 表示变量绑定不能重新赋值,但如果它指向对象,对象内部属性仍然可以修改。

const person = { name: "Alice", age: 25 };
person.age = 26;
 
// person = {}; // 不允许

理解这一点有助于区分“引用不可变”和“内容不可变”。

延伸理解

复习这篇时,不要只记住名词,要把重点放在 TypeScript 编译、类型检查、变量声明、类型推断和 const 的真实含义。这类知识如果只停留在定义层面,很容易在面试或项目中答得很散。更好的理解方式是把它放进一个具体场景:谁在调用它,输入从哪里来,失败后谁负责恢复,数据或状态会不会被重复处理。

  • TypeScript 的价值是把运行时不确定性尽量前移到开发阶段,但它不能替代运行时校验。
  • 类型设计应优先描述业务约束,而不是为了炫技使用复杂泛型。
  • 遇到第三方输入、JSON、表单和 API 响应时,要结合类型收窄或 schema 校验。

在真实项目中,可以把它当成一个判断框架:先确认输入、约束、失败场景和可观测性,再决定具体工具或写法。 如果一个方案看起来很简单,要继续追问它在规模扩大、权限变化、异常恢复和团队协作下是否仍然成立。

实践检查清单

  • 明确这个知识点在系统中的位置:是开发时约束、运行时能力、基础设施能力,还是协作流程。
  • 写出一个最小可运行例子,并补一个失败例子;只会写 happy path 说明理解还不够稳。
  • 记录常见误用:例如边界条件、权限假设、性能假设、同步/异步差异或环境差异。
  • 把概念和项目经历关联起来:如果面试被追问,可以用自己的项目说明为什么这样选。
  • 最后用一句话总结取舍:它牺牲了什么,换来了什么。

自测问题

  1. 这个主题解决的核心问题是什么?
  2. 如果不用当前方案,还有哪些替代方案?代价是什么?
  3. 最容易出错的边界条件在哪里?
  4. 如何在代码、测试或监控中验证它真的可靠?

项目化应用场景

可以把这类知识放到一个前后端共享类型的项目里理解:API 返回 JSON,前端先用 schema 做运行时校验,再把校验后的数据交给 TypeScript 类型系统。类型可以帮助编辑器提示和编译期检查,但不能保证网络返回一定正确。好的类型设计应该表达业务约束,例如角色、状态、权限、请求参数和响应结构,而不是所有地方都写成 string 或 any。

常见误区:

  • 把 TypeScript 类型当成运行时校验。
  • 为了省事使用 any,导致错误延后到线上。
  • 泛型过度复杂,让调用者难以理解。