第 93 章:第一个 TypeScript 程序
学习目标
- 编写第一个 TypeScript 函数
- 理解类型注解的基本语法
- 掌握从 JS 到 TS 的迁移方式
- 理解类型推断与类型注解的区别
一、Hello World 三种写法
1.1 JavaScript 写法(基线)
javascript
// hello.js
function greet(name) {
return 'Hello, ' + name + '!';
}
console.log(greet('Tom'));问题:name 可以传任何值(数字、对象、null),IDE 不报错。
1.2 TypeScript 写法(1.0 - 显式类型)
typescript
// hello.ts
function greet(name: string): string { // ① 参数类型 string ② 返回类型 string
return 'Hello, ' + name + '!';
}
console.log(greet('Tom'));
// console.log(greet(123)); // ❌ Argument of type 'number' is not assignable to parameter of type 'string'类型注解三要素:
typescript
function 函数名(参数: 参数类型): 返回类型 {
// 函数体
}1.3 TypeScript 写法(2.0 - 箭头函数)
typescript
// hello.ts
const greet = (name: string): string => `Hello, ${name}!`;
console.log(greet('Tom'));1.4 TypeScript 写法(3.0 - 类型推断)
typescript
// 编译器能自动推断 string,可以省略
const greet = (name: string) => `Hello, ${name}!`; // 推断返回 string最佳实践:参数必须显式标注,返回类型能推断就省略。
二、变量类型注解
2.1 基本语法
typescript
// 变量名: 类型 = 值
let username: string = 'Tom';
let age: number = 18;
let isActive: boolean = true;
let skills: string[] = ['Java', 'TypeScript', 'Vue'];2.2 常量也支持类型
typescript
const PI: number = 3.14159;
const APP_NAME: string = 'TaskFlow';2.3 类型推断 vs 显式注解
typescript
// ✅ 推荐:能推断就省略
let count = 10; // 推断为 number
let name = 'Tom'; // 推断为 string
let items = [1, 2, 3]; // 推断为 number[]
// ✅ 必要:参数、对象字面量、复杂类型
function add(a: number, b: number) { ... } // 参数必须标
// ❌ 反例:画蛇添足
let count: number = 10; // 重复,编译器已经能推断三、第一个完整示例
3.1 完整代码
typescript
// src/user.ts
interface User {
name: string;
age: number;
email: string;
}
function createUser(name: string, age: number, email: string): User {
return { name, age, email };
}
function describeUser(user: User): string {
return `${user.name} (${user.age}岁) 的邮箱是 ${user.email}`;
}
// 使用
const u = createUser('Tom', 18, 'tom@example.com');
console.log(describeUser(u));
// Tom (18岁) 的邮箱是 tom@example.com3.2 编译运行
bash
pnpm tsc
node dist/user.js四、逐步从 JS 迁移到 TS
实际项目很少"从零开始"用 TS,都是逐步迁移。
4.1 第一步:先改后缀
bash
# 把 .js 改成 .ts
mv user.js user.ts第一次改完,TS 可能会报一堆错误,先不必慌。
4.2 第二步:加 // @ts-check 注释
javascript
// user.js
// @ts-check ← 加上这一行,VS Code 就会做类型检查
function greet(name) {
return 'Hello, ' + name;
}好处:不用改文件后缀,先在 JS 文件里打开检查。
4.3 第三步:允许 JS 和 TS 混编
json
// tsconfig.json
{
"compilerOptions": {
"allowJs": true, // 允许编译 .js 文件
"checkJs": false, // 暂不检查 .js(第一阶段)
"outDir": "./dist"
},
"include": ["src/**/*"]
}这样 JS 和 TS 可以共存,逐步把 .js 改成 .ts。
4.4 第四步:迁移顺序
原则:从底层向顶层迁移(叶子 → 根),避免依赖混乱。
五、常见编译错误
5.1 类型不匹配
typescript
function print(message: string): void {
console.log(message);
}
print(123); // ❌ TS2345: Argument of type 'number' is not assignable to parameter of type 'string'修复:
typescript
print(String(123)); // ✅ 显式转换
print(`${123}`); // ✅ 模板字符串5.2 缺少返回类型
typescript
function add(a: number, b: number) {
return a + b; // 有的项目会要求显式返回类型
}修复:
typescript
function add(a: number, b: number): number {
return a + b;
}5.3 隐式 any
typescript
// 严格模式下报错
function process(data) { // ❌ Parameter 'data' implicitly has an 'any' type
return data;
}修复:
typescript
function process(data: unknown): unknown { // ✅ 显式标注
return data;
}六、tsc 命令详解
bash
# 编译指定文件
tsc hello.ts
# 编译整个项目(依赖 tsconfig.json)
tsc
# 只做类型检查,不输出文件
tsc --noEmit
# 监听模式
tsc --watch
# 编译时打印详细错误
tsc --pretty
# 指定配置文件
tsc --project tsconfig.build.json
# 增量编译(加快速度)
tsc --incremental七、调试技巧
7.1 开启 sourceMap
json
// tsconfig.json
{
"compilerOptions": {
"sourceMap": true
}
}配合 node --enable-source-maps dist/index.js,调试时能直接跳到 .ts 源码。
7.2 使用 VS Code 调试
.vscode/launch.json:
json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "调试 TS",
"program": "${workspaceFolder}/src/index.ts",
"preLaunchTask": "tsc: build",
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}按 F5 启动。
八、本章小结
| 要点 | 关键 |
|---|---|
| 类型注解语法 | 变量: 类型 = 值 / 函数(参数: 类型): 返回类型 |
| 类型推断 | 能推断就省略返回类型 |
| 渐进式迁移 | @ts-check → allowJs → 逐步改后缀 |
| 编译命令 | tsc / tsc --watch / tsc --noEmit |
| 严格模式 | 开启 strict: true 后所有隐式 any 都会报错 |
动手练习
- 基础练习:写一个
calculateCircleArea(r: number): number函数,参数是半径,返回面积 - 迁移练习:把之前的 JavaScript 工具函数加上类型注解
- 类型推断实验:故意写一个能推断的和一个不能推断的代码,对比有没有
: type的差异
推荐阅读
- 📖 TypeScript for JavaScript Programmers — 官方 5 分钟上手
- 🌐 TypeScript Playground — 在线编辑器,实时看编译结果
- 🌐 tsconfig 配置项详解 — 官方逐项说明
下一章:第 94 章:基本类型 →