在TypeScript面试中,面试官通常会考察你对TypeScript特性的理解、类型系统的掌握、以及在实际项目中的应用能力。以下是一些热点题目及其相应的代码示例,旨在帮助你准备TypeScript相关的面试。
1. 类型别名与接口的区别及使用场景
问题:请解释类型别名(Type Aliases)和接口(Interfaces)之间的主要区别,并给出使用场景。
答案:
- 类型别名:用于给类型起一个新名字,可以是基本类型、联合类型、交叉类型、数组类型等。它更灵活,但不能被extends或implements(仅当类型别名是对象或类类型时,可以用在extends或implements的右侧)。
- 接口:主要用于定义对象的形状,它可以包含方法(抽象或具体)、属性等。接口可以被extends和implements。
代码示例:
// 类型别名
type Name = string;
type UserInfo = { name: Name; age: number;
}; // 接口
interface IPerson { name: string; greet(phrase: string): void;
} class Person implements IPerson { name: string; constructor(name: string) { this.name = name; } greet(phrase: string) { console.log(`${phrase}, ${this.name}!`); }
} // 使用场景:当你需要一个简单的类型引用时,使用类型别名;当需要定义对象形状或继承时,使用接口。
2. 泛型(Generics)的使用
问题:请解释什么是泛型,并给出一个使用泛型的函数示例。
答案:泛型是一种在编译时定义类型但在运行时保持灵活性的方法。它允许你编写灵活、可重用的函数、类或接口。
代码示例:
// 泛型函数示例
function identity<T>(arg: T): T { return arg;
} let output = identity<string>("myString"); // 类型参数为string
let outputNum = identity(42); // 类型参数为number,TypeScript会自动推断 // 泛型接口示例
interface GenericIdentityFn<T> { (arg: T): T;
} let myIdentity: GenericIdentityFn<number> = identity;
3. 枚举(Enumerations)与常量(Constants)的区别
问题:请阐述枚举(Enumerations)与常量(Constants)之间的主要区别。
答案:
- 枚举:是一种特殊的类,它包含了一组命名的常量。枚举成员可以是数字、字符串甚至是计算值(只要成员之间有明确的差异)。枚举提供了一种描述一组命名常量的方法,使得代码更加清晰。
- 常量:通常使用
const
关键字定义,表示其值在初始化之后不可更改。它可以是任何类型。
代码示例:
enum Color {Red, Green, Blue};
let c: Color = Color.Green; const PI = 3.14;
// PI = 3.15; // 这会引发编译错误
4. TypeScript中类属性的初始化时机
问题:在TypeScript中,类属性的初始化时机是怎样的?
答案:
- 类属性可以在声明时直接初始化(称为实例属性初始化器)。
- 也可以在构造函数中初始化。
- 如果类属性是静态的,则它可以在类体内部直接初始化。
代码示例:
class Person { // 实例属性初始化器 name: string = "John"; age: number; // 静态属性 static staticProperty = "I am static"; constructor(age: number) { this.age = age; }
} console.log(new Person(30).name); // John
console.log(Person.staticProperty); // I am static
5.解释一下 TypeScript 中的 interface
和 type
有什么区别?
答案概述:
interface
通常用于定义对象的形状,可以被多次声明并合并,支持继承其他接口。type
更为灵活,支持联合类型、元组、字面量类型等复杂类型,但不能被多次声明(除非使用类型别名)。
示例代码:
// Interface 示例
interface User { name: string; age: number;
} interface UserWithEmail extends User { email: string;
} const user: UserWithEmail = { name: 'John Doe', age: 30, email: 'john@example.com'
}; // Type 示例
type Name = string;
type Age = number;
type UserType = { name: Name; age: Age; email?: string; // 可选属性
}; const anotherUser: UserType = { name: 'Jane Doe', age: 25
};
4. TypeScript 中如何声明一个模块?
答案概述:
在 TypeScript 中,模块是用来封装变量、函数、类、接口等对象的容器。
示例代码:
math.ts
export function add(a: number, b: number): number { return a + b;
} export function subtract(a: number, b: number): number { return a - b;
}
main.ts
import { add, subtract } from './math'; console.log(add(1, 2)); // 输出 3
console.log(subtract(5, 3)); // 输出 2