TypeScript 是 JavaScript 的超集,两者既有联系又有区别。理解它们的差异有助于更好地使用 TypeScript。
// JavaScript
var name = "张三"
let age = 25
const PI = 3.14
// TypeScript
var name: string = "张三"
let age: number = 25
const PI: number = 3.14
// 类型可以省略,自动推断
let city = "北京" // 自动推断为 string
// JavaScript
function add(a, b) {
return a + b
}
add(1, 2) // 3
add("1", "2") // "12" - 可能不是预期结果
// TypeScript
function add(a: number, b: number): number {
return a + b
}
add(1, 2) // 3
add("1", "2") // 编译错误
// JavaScript
const user = {
name: "张三",
age: 25
}
user.email = "test@example.com" // 运行时添加属性
// TypeScript
interface User {
name: string
age: number
email?: string
}
const user: User = {
name: "张三",
age: 25
}
user.email = "test@example.com" // 正确,email 是可选属性
user.phone = "123456" // 错误,属性不存在
| 特性 | JavaScript | TypeScript |
|---|---|---|
| 类型系统 | 动态类型 | 静态类型 |
| 类型检查 | 运行时 | 编译时 |
| 编译 | 不需要 | 需要编译 |
| 接口 | 不支持 | 支持 |
| 泛型 | 不支持 | 支持 |
| 枚举 | 不支持 | 支持 |
| 装饰器 | 不支持(ES7提案) | 支持 |
| 类型推断 | 无 | 有 |
let value = "hello"
value = 123 // 运行时可以改变类型
value = { a: 1 } // 任何类型都可以
console.log(value.toUpperCase()) // 运行时错误
let value: string = "hello"
value = 123 // 编译错误
value = { a: 1 } // 编译错误
console.log(value.toUpperCase()) // 编译器知道这是字符串方法
function greet(user) {
return "Hello, " + user.nmae // 拼写错误,运行时才发现
}
greet({ name: "张三" }) // "Hello, undefined"
interface User {
name: string
}
function greet(user: User): string {
return "Hello, " + user.nmae // 编译错误:属性 nmae 不存在
}
greet({ name: "张三" })
TypeScript 完全兼容 JavaScript:
// 这段 JavaScript 代码在 TypeScript 中完全合法
function calculate(a, b) {
return a * b
}
const result = calculate(3, 4)
可以逐步添加类型:
function calculate(a: number, b: number): number {
return a * b
}
const result: number = calculate(3, 4)
编写代码 → 运行 → 发现错误 → 修复 → 运行
编写代码 → 编译检查 → 修复错误 → 运行
TypeScript 把错误发现前置到编译阶段。
从 JavaScript 迁移到 TypeScript:
// tsconfig.json - 渐进式迁移配置
{
"compilerOptions": {
"strict": false,
"noImplicitAny": false,
"allowJs": true
}
}