TypeScript 和 JavaScript 是密切相关的编程语言,但它们在设计目标、语法特性和使用场景上有明显区别。以下是它们的核心区别及具体示例:
核心区别
特性 | TypeScript | JavaScript |
---|---|---|
类型系统 | 静态类型(编译时类型检查) | 动态类型(运行时类型推断) |
兼容性 | JavaScript 的超集(最终编译为 JS) | 原生脚本语言 |
错误检查时机 | 编译时发现类型错误 | 运行时可能暴露类型错误 |
开发工具支持 | 强大的代码提示、重构和文档生成 | 有限的类型相关工具支持 |
学习曲线 | 需要掌握类型语法 | 更简单直接 |
具体区别与示例
1. 类型注解(Type Annotations)
TypeScript 允许为变量、函数参数和返回值定义明确的类型:
// TypeScript
function add(a: number, b: number): number {
return a + b;
}
add(2, 3); // 正确
add("2", 3); // 编译时报错:Argument of type 'string' is not assignable to 'number'
JavaScript 只能在运行时发现类型问题:
// JavaScript
function add(a, b) {
return a + b;
}
add(2, 3); // 5
add("2", 3); // "23"(可能非预期行为,但不会报错)
2. 接口与类型定义(Interfaces)
TypeScript 支持通过接口定义对象结构:
// TypeScript
interface User {
id: number;
name: string;
}
function printUser(user: User) {
console.log(user.name);
}
// 调用时需符合接口定义
printUser({ id: 1, name: "Alice" }); // 正确
printUser({ age: 25 }); // 编译错误:缺少 'id' 和 'name'
JavaScript 无法约束对象结构:
// JavaScript
function printUser(user) {
console.log(user.name); // 若 user 无 name 属性,运行时可能报错
}
printUser({ age: 25 }); // 输出 undefined(可能引发后续错误)
3. 可选属性和默认值
TypeScript 支持更严格的参数控制:
// TypeScript
function greet(name: string, age?: number) {
return age ? `${name} is ${age} years old` : `Hello ${name}!`;
}
greet("Bob"); // 正确
greet("Bob", 30); // 正确
greet(123); // 编译错误:类型不匹配
JavaScript 依赖人工检查参数:
// JavaScript
function greet(name, age) {
if (typeof name !== 'string') throw new Error("Invalid name");
// 需要手动验证类型
}
4. 类与访问修饰符
TypeScript 支持 public
/private
/protected
修饰符:
// TypeScript
class Animal {
private name: string;
constructor(name: string) {
this.name = name;
}
}
const cat = new Animal("Cat");
console.log(cat.name); // 编译错误:Property 'name' is private
JavaScript 通过约定(如 _name
)模拟私有属性:
// JavaScript
class Animal {
constructor(name) {
this._name = name; // 实际仍可访问
}
}
const cat = new Animal("Cat");
console.log(cat._name); // 正常运行(无强制私有化)
5. 泛型(Generics)
TypeScript 支持泛型提升代码复用性:
// TypeScript
function identity<T>(arg: T): T {
return arg;
}
identity<number>(42); // 显式类型
identity("Hello"); // 自动推断为 string
JavaScript 无法直接实现类型安全的泛型:
// JavaScript
function identity(arg) {
return arg; // 无类型约束
}
总结使用场景
- TypeScript:大型项目、团队协作、需要高可维护性和可预测性时。
- JavaScript:小型脚本、快速原型开发、无需复杂类型系统时。
TypeScript 通过静态类型系统显著提升了代码的健壮性,而 JavaScript 更适合轻量级场景。两者最终都运行在 JavaScript 引擎中,TypeScript 需要通过编译器(如 tsc
)转换为 JavaScript 代码。