TypeScript 与 JavaScript 对比

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"            // 错误,属性不存在

核心差异

特性JavaScriptTypeScript
类型系统动态类型静态类型
类型检查运行时编译时
编译不需要需要编译
接口不支持支持
泛型不支持支持
枚举不支持支持
装饰器不支持(ES7提案)支持
类型推断

类型系统对比

JavaScript 动态类型

let value = "hello"
value = 123        // 运行时可以改变类型
value = { a: 1 }   // 任何类型都可以

console.log(value.toUpperCase())  // 运行时错误

TypeScript 静态类型

let value: string = "hello"
value = 123        // 编译错误
value = { a: 1 }   // 编译错误

console.log(value.toUpperCase())  // 编译器知道这是字符串方法

错误发现时机

JavaScript

function greet(user) {
  return "Hello, " + user.nmae  // 拼写错误,运行时才发现
}

greet({ name: "张三" })  // "Hello, undefined"

TypeScript

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)

开发体验对比

JavaScript 开发流程

编写代码 → 运行 → 发现错误 → 修复 → 运行

TypeScript 开发流程

编写代码 → 编译检查 → 修复错误 → 运行

TypeScript 把错误发现前置到编译阶段。

何时选择 TypeScript

适合 TypeScript 的场景

  • 大型项目,多人协作
  • 长期维护的项目
  • 需要高可靠性的应用
  • 团队成员经验丰富

适合 JavaScript 的场景

  • 小型项目或原型开发
  • 快速迭代的产品
  • 团队对 TypeScript 不熟悉
  • 学习成本需要控制

迁移成本

从 JavaScript 迁移到 TypeScript:

  1. :允许使用 any,逐步添加类型
  2. :配置宽松的编译选项
  3. :严格模式,完整类型定义
// tsconfig.json - 渐进式迁移配置
{
  "compilerOptions": {
    "strict": false,
    "noImplicitAny": false,
    "allowJs": true
  }
}