跳到主要内容

[Easy] TypeScript vs JavaScript

1. What is TypeScript?

什么是 TypeScript?

TypeScript 是由 Microsoft 开发的开源编程语言,它是 JavaScript 的超集(Superset),意味着所有有效的 JavaScript 代码都是有效的 TypeScript 代码。

核心特点

  • 在 JavaScript 基础上加入静态类型系统
  • 编译时进行类型检查
  • 编译后转换为纯 JavaScript
  • 提供更好的开发体验和工具支持

2. What are the differences between TypeScript and JavaScript?

TypeScript 与 JavaScript 的差异是什么?

主要差异

特性JavaScriptTypeScript
类型系统动态类型(运行时检查)静态类型(编译时检查)
编译不需要编译需要编译为 JavaScript
类型注解不支持支持类型注解
错误检查运行时发现错误编译时发现错误
IDE 支持基本支持强大的自动完成和重构
学习曲线较低较高

类型系统差异

JavaScript(动态类型)

// JavaScript:运行时才检查类型
let value = 10;
value = 'hello'; // 可以改变类型
value = true; // 可以改变类型

function add(a, b) {
return a + b;
}

add(1, 2); // 3
add('1', '2'); // '12'(字符串连接)
add(1, '2'); // '12'(类型转换)

TypeScript(静态类型)

// TypeScript:编译时检查类型
let value: number = 10;
value = 'hello'; // ❌ 编译错误:Type 'string' is not assignable to type 'number'

function add(a: number, b: number): number {
return a + b;
}

add(1, 2); // ✅ 3
add('1', '2'); // ❌ 编译错误:Argument of type 'string' is not assignable to parameter of type 'number'
add(1, '2'); // ❌ 编译错误

编译过程

JavaScript

// 直接执行,不需要编译
console.log('Hello World');

TypeScript

// TypeScript 源代码
let message: string = 'Hello World';
console.log(message);

// ↓ 编译后转换为 JavaScript
let message = 'Hello World';
console.log(message);

3. Why use TypeScript?

为什么要使用 TypeScript?

优点

  1. 早期发现错误

    // 编译时就能发现错误,不需要等到运行时
    function calculateArea(width: number, height: number): number {
    return width * height;
    }

    calculateArea('10', 20); // ❌ 编译错误:立即发现问题
  2. 更好的 IDE 支持

    interface User {
    name: string;
    age: number;
    email: string;
    }

    const user: User = {
    name: 'John',
    age: 30,
    // IDE 会自动提示缺少 email 属性
    };
  3. 代码可读性

    // 类型注解让函数意图更清楚
    function processUser(user: User, callback: (result: string) => void): void {
    // ...
    }
  4. 重构更安全

    // 修改接口时,TypeScript 会找出所有需要更新的地方
    interface User {
    name: string;
    age: number;
    // 新增 email 属性时,所有使用 User 的地方都会报错
    }

缺点

  1. 需要编译步骤:增加开发流程复杂度
  2. 学习曲线:需要学习类型系统
  3. 文件大小:类型信息会增加源代码大小(但编译后不会影响)
  4. 配置复杂:需要配置 tsconfig.json

4. Common Interview Questions

常见面试题目

题目 1:类型检查时机

请说明以下代码在 JavaScript 和 TypeScript 中的行为差异。

// JavaScript
function add(a, b) {
return a + b;
}

console.log(add(1, 2)); // ?
console.log(add('1', '2')); // ?
console.log(add(1, '2')); // ?
// TypeScript
function add(a: number, b: number): number {
return a + b;
}

console.log(add(1, 2)); // ?
console.log(add('1', '2')); // ?
console.log(add(1, '2')); // ?
点击查看答案

JavaScript 输出

console.log(add(1, 2)); // 3
console.log(add('1', '2')); // '12'(字符串连接)
console.log(add(1, '2')); // '12'(类型转换)

TypeScript 行为

console.log(add(1, 2)); // ✅ 3(编译通过)
console.log(add('1', '2')); // ❌ 编译错误:Argument of type 'string' is not assignable to parameter of type 'number'
console.log(add(1, '2')); // ❌ 编译错误:Argument of type 'string' is not assignable to parameter of type 'number'

解释

  • JavaScript 在运行时进行类型转换,可能产生非预期结果
  • TypeScript 在编译时检查类型,提前发现错误

题目 2:类型推断

请说明以下代码中 TypeScript 如何推断类型。

let value1 = 10;
let value2 = 'hello';
let value3 = true;

value1 = 'world'; // ?
value2 = 20; // ?
value3 = 'yes'; // ?
点击查看答案
let value1 = 10; // TypeScript 推断为 number
let value2 = 'hello'; // TypeScript 推断为 string
let value3 = true; // TypeScript 推断为 boolean

value1 = 'world'; // ❌ 编译错误:Type 'string' is not assignable to type 'number'
value2 = 20; // ❌ 编译错误:Type 'number' is not assignable to type 'string'
value3 = 'yes'; // ❌ 编译错误:Type 'string' is not assignable to type 'boolean'

解释

  • TypeScript 会根据初始值自动推断类型
  • 推断后无法改变类型(除非明确声明为 anyunion 类型)

明确指定类型

let value1: number = 10;
let value2: string = 'hello';
let value3: boolean = true;

题目 3:运行时行为

请说明 TypeScript 编译后的 JavaScript 代码与原始 TypeScript 的差异。

// TypeScript
interface User {
name: string;
age: number;
}

function greet(user: User): string {
return `Hello, ${user.name}!`;
}

const user: User = { name: 'John', age: 30 };
console.log(greet(user));
点击查看答案

编译后的 JavaScript

// 所有类型信息都被移除
function greet(user) {
return `Hello, ${user.name}!`;
}

const user = { name: 'John', age: 30 };
console.log(greet(user));

关键点

  • TypeScript 的类型注解在编译后完全消失
  • 编译后的 JavaScript 与纯 JavaScript 完全相同
  • TypeScript 只在开发阶段提供类型检查,不影响运行时性能
  • 这就是为什么 TypeScript 是"编译时类型系统"而非"运行时类型系统"

题目 4:类型错误 vs 运行时错误

请比较以下两种错误的差异。

// 情况 1:TypeScript 编译时错误
function calculate(a: number, b: number): number {
return a + b;
}

calculate('1', '2'); // ❌ 编译错误

// 情况 2:JavaScript 运行时错误
function process(data) {
return data.value.toUpperCase();
}

process(null); // ❌ 运行时错误:Cannot read property 'toUpperCase' of null
点击查看答案

情况 1:TypeScript 编译时错误

  • 发现时机:编译时(开发阶段)
  • 影响:无法编译成功,必须修正才能执行
  • 优点:提前发现问题,避免部署错误代码

情况 2:JavaScript 运行时错误

  • 发现时机:运行时(用户使用时)
  • 影响:程序崩溃,影响用户体验
  • 缺点:需要实际执行才能发现问题

TypeScript 的解决方案

function process(data: { value: string } | null) {
if (data === null) {
return '';
}
return data.value.toUpperCase();
}

process(null); // ✅ 编译通过,运行时安全

5. Best Practices

最佳实践

推荐做法

// 1. 明确指定函数返回类型
function add(a: number, b: number): number {
return a + b;
}

// 2. 使用接口定义复杂对象结构
interface User {
name: string;
age: number;
email?: string; // 可选属性
}

// 3. 避免使用 any,优先使用 unknown
function processValue(value: unknown): void {
if (typeof value === 'string') {
console.log(value.toUpperCase());
}
}

// 4. 使用类型别名提高可读性
type UserID = string;
type UserName = string;

function getUser(id: UserID): User {
// ...
}

避免的做法

// 1. 不要过度使用 any
function process(data: any) {
// ❌ 失去类型检查的意义
return data.value;
}

// 2. 不要忽略类型错误
function add(a: number, b: number): number {
return a + b; // ❌ 如果这里有错误,不要用 @ts-ignore 忽略
}

// 3. 不要混合类型注解和推断
let value: number = 10; // ✅ 明确指定
let value = 10; // ✅ 让 TypeScript 推断
let value: number = 10; // ⚠️ 两者都有时,确保一致

6. Interview Summary

面试总结

快速记忆

TypeScript 核心概念

  • JavaScript 的超集,加入静态类型系统
  • 编译时检查类型,运行时与 JavaScript 相同
  • 提供更好的开发体验和错误预防

主要差异

  • 类型系统:静态(TypeScript)vs 动态(JavaScript)
  • 错误发现:编译时(TypeScript)vs 运行时(JavaScript)
  • 开发工具:强大的 IDE 支持(TypeScript)vs 基本支持(JavaScript)

面试回答范例

Q: TypeScript 和 JavaScript 的主要差异是什么?

"TypeScript 是 JavaScript 的超集,主要差异在于 TypeScript 加入了静态类型系统。JavaScript 是动态类型语言,类型检查在运行时进行;而 TypeScript 是静态类型语言,类型检查在编译时进行。这让开发者能够在开发阶段就发现类型相关的错误,而不是等到运行时才发现。TypeScript 编译后会转换为纯 JavaScript,所以运行时的行为与 JavaScript 完全相同。"

Q: 为什么要使用 TypeScript?

"TypeScript 的主要优点包括:1) 早期发现错误,在编译时就能发现类型错误;2) 更好的 IDE 支持,提供自动完成和重构功能;3) 提高代码可读性,类型注解让函数意图更清楚;4) 重构更安全,修改类型时会自动找出所有需要更新的地方。不过也需要考虑学习曲线和编译步骤的额外成本。"

Reference