TypeScript 入门(00):从 JS 到 TS 的第一个类型程序
更新时间:2026-08-31。本文是
languages/typescript/beginner/入门层第 0 篇。目标很单纯:用 TypeScript 写第一个带类型的程序并跑通,搞清楚它和 JavaScript 的关系。后续衔接 类型系统基础 与 工程配置与构建。
一、先搞清楚:TypeScript 是什么、为什么本站讲它
TypeScript(简称 TS) 是微软 2012 年开源的 JavaScript 超集——所有合法 JS 代码都是合法 TS 代码,TS 在 JS 之上加了类型系统,然后编译回干净的 JS。一句话概括它的定位:给 JavaScript 补上编译期类型检查。
本站主线是性能与底层原理,TypeScript 出现在这里的原因很直白:前端/全栈工程(Vite、Next.js、Node 生态)早已全面 TS 化,而 TS 的"编译期约束 + 工程化配置"恰恰是"把工程严谨性带到动态语言世界"的最佳案例——它和本站 Rust 所有权系统(编译期把内存错误锁死)在精神上是同源的:能在编译期抓到的错,绝不留到运行期。
如果你写过 Python 或 JS,会觉得 TS 很"啰嗦"——每个变量都要想类型。但项目一超过几千行,这些"啰嗦"就变成了免费的文档和重构的安全网。
二、安装 tsc 并验证
tsc(TypeScript Compiler,TypeScript 编译器) 把 .ts 文件编译成 .js。用 npm 安装(需要 Node.js 环境):
npm install -g typescript
tsc --version验证输出示例
$ tsc --version
Version 5.6.2看到版本号即安装成功。tsc 只是编译器,不是运行时——TS 没有自己的运行时,编译出的 JS 最终在 Node 或浏览器里跑。这是理解 TS 工具链的第一原则。
三、第一个带类型的程序
写一个最简单的类型标注示例,文件 hello.ts:
// 类型标注:变量名后面加 : 类型
let name: string = "codebuddy";
let count: number = 42;
let active: boolean = true;
function greet(user: string): string {
return `Hello, ${user}!`;
}
console.log(greet(name));
console.log(count, active);编译运行:
tsc hello.ts # 产出 hello.js(类型标注被擦除)
node hello.js # 运行编译产物输出说明
$ node hello.js
Hello, codebuddy!
42 true注意 tsc 干了两件事:检查类型(有错就报)和擦除类型(把 : string 这类标注删掉,生成纯 JS)。类型信息在编译期就消费完了,运行时根本没有类型这回事——这正是 TS "编译期安全、零运行时开销"的设计。
四、编译期抓错:类型系统的价值
TS 最有说服力的时刻是报错。看这个例子,把 greet 传错类型:
function greet(user: string): string {
return `Hello, ${user}!`;
}
greet(42); // TS2345: 类型 number 的参数不能赋给类型 string 的参数编译直接失败:
$ tsc hello.ts
hello.ts:6:7 - error TS2345: Argument of type 'number' is not assignable
to parameter of type 'string'.
Found 1 error.同样的代码在纯 JS 里,greet(42) 会顺利跑出 Hello, 42!——错误在运行时才暴露,甚至静默产生错误结果。TS 把这类低级错误提前到编译期,这是它存在的全部理由。
五、基础类型速览
TS 在 JS 类型之上加了一批自己的类型,先记这六个就够用:
| 类型 | 含义 | 示例 |
|---|---|---|
string | 字符串 | let s: string = "hi" |
number | 数字(整数浮点不分家) | let n: number = 3.14 |
boolean | 布尔 | let b: boolean = true |
string[] / number[] | 数组 | let arr: number[] = [1, 2, 3] |
null / undefined | 空值 | let x: null = null |
any | 放弃检查(慎用) | let a: any = "随便啥" |
any 是双刃剑:它关掉类型检查,等于把 TS 变回 JS。入门阶段看到 any 要警惕,它是"这里没想清楚"的标记。类型收窄、联合类型这些进阶玩法在 类型系统基础 展开。
六、接口:给对象定形状
JS 对象是自由散漫的键值对,TS 用接口(interface) 给对象定形状——声明"这个对象必须有这些字段、这些类型":
interface User {
name: string;
age: number;
email?: string; // ?: 可选字段,可有可无
}
function printUser(user: User): void {
console.log(`${user.name} (${user.age})`);
if (user.email) {
console.log(`邮箱: ${user.email}`);
}
}
printUser({ name: "ada", age: 30 }); // 合法:email 可选
printUser({ name: "bob", age: 25, email: "b@x.com" }); // 合法:带了 email运行输出
$ node user.js
ada (30)
bob (25)
邮箱: b@x.com接口把"对象长什么样"写成了可检查的契约:传对象时字段多、少、类型不对,编译期立刻报错。这个"用类型描述数据结构"的思路,是后面泛型、类型体操(泛型与类型体操入门)的地基。
七、常见坑与排查
| 报错/现象 | 原因 | 解法 |
|---|---|---|
error TS2304: Cannot find name 'console' | 缺少 Node 类型声明 | 装 @types/node 或 npm i -D @types/node |
| 编译产物路径混乱 | 没配 tsconfig.json | 见 工程配置与构建 |
看到大量 any | 从 JS 迁移的老代码 | 逐步把 any 换成具体类型,可用 tsc --noImplicitAny 强制 |
tsc 命令不存在 | 全局安装失败 | 重装:npm install -g typescript |
一句话:TypeScript = JavaScript + 编译期类型检查——tsc 负责查错并擦除类型,接口和基础类型标注把"对象长什么样"变成可编译期验证的契约,这就是它在大型工程里站稳脚跟的根本原因。