文章目录
📈「作者简介」:不知名十八线技术博主【ai_todo】
📚「推荐主页」:前端小姐姐【阿珊和她的猫】
🎁「推荐专栏」:《从0到0.01入门React》
🕐「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️⭐️)
1. TypeScript是什么?它与JavaScript有什么区别?
- TypeScript是一个开源的编程语言,它是
JavaScript
的超集,通过为JavaScript添加静态类型检查和其他功能来增强JavaScript的开发体验。 - TypeScript相对于JavaScript的优势包括:静态类型检查、
更好的代码组织与可维护性
、更好的工具支持和代码智能提示
、更好的面向对象编程支持等。
2. TypeScript中的类型注解是什么?如何使用它们?
- 类型注解是在
TypeScript
中声明变量、函数参数、函数返回值等时指定类型的方式。可以使用冒号(:)后紧跟类型来进行类型注解。 - 例如:
let num: number = 10; function greet(name: string): string { return `Hello, ${name}!`; }
3. TypeScript的泛型是什么?为什么要使用它们?
- 泛型是一种在编程中使用类型参数化的方式。它允许我们编写适用于多种类型的可重用代码。
- 通过使用泛型,我们可以编写更灵活、更通用的函数和类,同时提高代码的类型安全性和可读性。
当涉及到TypeScript的泛型时,下面是几个代码案例,以帮助你更好地理解它们的使用方法:
1. 简单的泛型函数
function identity<T>(arg: T): T {
return arg;
}
let result = identity<string>("Hello, TypeScript!");
console.log(result); // 输出: Hello, TypeScript!
2. 泛型接口
interface Pair<K, V> {
key: K;
value: V;
}
let pair1: Pair<number, string> = { key: 1, value: "One" };
let pair2: Pair<string, number> = { key: "Two", value: 2 };
3. 泛型类
class Stack<T> {
private elements: T[] = [];
push(element: T) {
this.elements.push(element);
}
pop(): T {
return this.elements.pop();
}
}
let stack = new Stack<number>();
stack.push(1);
stack.push(2);
console.log(stack.pop()); // 输出: 2
4. 泛型约束
interface Comparable {
compareTo(other: this): number;
}
function max<T extends Comparable>(a: T, b: T): T {
return a.compareTo(b) > 0 ? a : b;
}
class Person implements Comparable {
constructor(public name: string, public age: number) {}
compareTo(other: Person): number {
return this.age - other.age;
}
}
let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);
let olderPerson = max(alice, bob);
console.log(olderPerson); // 输出: Person { name: "Alice", age: 30 }
这些案例展示了TypeScript中泛型的常见用法。泛型能够增加代码的灵活性和可重用性,让我们可以编写更通用的函数和类。通过使用泛型约束,可以进一步限制泛型的类型范围,提高代码的类型安全性。请根据你自己的需要,在项目中灵活运用泛型特性。
4. TypeScript中的接口和类型别名有什么区别?
- 接口和类型别名都用于定义自定义类型,但有一些区别。
- 接口(interface)可以用于描述对象、类、函数的形状和契约,而类型别名(type alias)则可以为任何类型创建别名。
- 接口可以被实现和继承,而类型别名不可以。
- 接口只能定义对象类型,而类型别名可以定义其他类型,如联合类型、交叉类型、原始类型等。
下面是一个对比TypeScript中接口和类型别名的表格,以帮助你更好地理解它们之间的区别和用法:
接口(Interface) | 类型别名(Type Alias) | |
---|---|---|
定义形式 | 使用interface 关键字定义 | 使用type 关键字定义 |
定义对象形状 | 是 | 是 |
定义函数形状 | 是 | 是 |
可被类实现和继承 | 是 | 否 |
可使用extends 扩展 | 是 | 是 |
可定义交叉类型 | 是 | 是 |
可定义联合类型 | 是 | 是 |
可定义原始类型别名 | 否 | 是 |
具名化 | 可以给接口命名,便于重复使用 | 不可以给类型别名命名,只能使用匿名类型别名 |
可定义索引签名 | 是 | 是 |
可定义函数重载 | 是 | 否 |
可定义可选属性 | 是 | 是 |
可定义只读属性 | 是 | 是 |
接口和类型别名都可以用于定义自定义类型,但有一些区别。接口适用于描述对象、类、函数的形状和契约,而类型别名则可以为任何类型创建别名。接口可以被类实现和继承,而类型别名不可以。另外,接口可以定义函数重载,而类型别名不行。
根据具体的需求,可以选择使用接口或类型别名。通常情况下,当需要描述对象或类的结构时,使用接口更合适;当需要为其他类型(联合类型、交叉类型等)创建别名时,使用类型别名更合适。
5. TypeScript中的装饰器是什么?如何使用它们?
- 装饰器是一种特殊类型的声明,可以附加到类、方法、属性或参数上来修改其行为。
- 装饰器使用
@
符号,后跟一个表达式来应用于某个目标。 - 例如:
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { // 修改函数行为 const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { console.log(`Calling ${propertyKey} with arguments: ${args}`); return originalMethod.apply(this, args); }; } class MyClass { @log doSomething() { console.log("Doing something..."); } }
6. TypeScript编译成JavaScript的方式是什么?可以配置哪些编译选项?
TypeScript
可以通过使用tsc
命令行编译器将TypeScript
代码转换为JavaScript
代码。- 编译选项包括但不限于:
目标版本(target)、模块系统(module)、输出目录(outDir)、严格模式(strict)、源映射(sourceMap)
等。 - 通过
tsconfig.json
文件可以配置编译选项,也可以通过命令行参数来进行配置。
当准备面试时,了解这些关键的TypeScript概念和用法,能够帮助你在面试中更好地回答与TypeScript相关的问题。记住,在回答问题时尽量清晰、简洁地表达你的观点,并结合实际的代码例子来支持你的回答。