1. TypeScript 是什么?
解析:TypeScript 是一种由微软开发的开源编程语言,是 JavaScript 的超集,增加了静态类型和其他语言特性。TypeScript 可以编译成纯 JavaScript。
2. TypeScript 的主要特性有哪些?
解析:
- 静态类型:允许在编译时检查类型。
- 接口:定义对象的结构。
- 类:支持面向对象编程。
- 枚举:为一组相关的常量赋予名称。
- 装饰器:用于元编程的特性。
3. 在 TypeScript 中,如何定义一个接口?
示例:
interface Person {
name: string;
age: number;
}
4. TypeScript 中的类型推断是什么?
解析:类型推断是 TypeScript 自动推断变量类型的能力。编译器根据变量的初始值和上下文来推断类型。
5. TypeScript 中的联合类型是什么?
解析:联合类型允许一个变量可以是多种类型之一。
示例:
let value: string | number;
value = "Hello";
value = 42;
6. 如何在 TypeScript 中定义一个类?
示例:
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
7. TypeScript 中的类型别名是什么?
解析:类型别名用于给类型赋予一个新名称,可以用于基本类型、联合类型、元组等。
示例:
type StringOrNumber = string | number;
8. TypeScript 中的枚举类型是什么?
解析:枚举是一种特殊的类型,用于定义一组命名常量。
示例:
enum Color {
Red,
Green,
Blue,
}
9. TypeScript 中的泛型是什么?
解析:泛型允许创建可重用的组件,能够在保留类型信息的同时支持多种数据类型。
示例:
function identity<T>(arg: T): T {
return arg;
}
10. 如何在 TypeScript 中使用装饰器?
解析:装饰器是用于修改类及其成员的特殊类型的声明。
示例:
function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
return originalMethod.apply(this, args);
};
}
11. TypeScript 中的抽象类是什么?
解析:抽象类是不能被实例化的类,用于定义子类的结构。
示例:
abstract class Animal {
abstract makeSound(): void;
}
class Dog extends Animal {
makeSound() {
console.log("Woof!");
}
}
12. 如何在 TypeScript 中实现类型保护?
解析:类型保护用于在运行时检查变量的类型,以确保安全地访问其属性。
示例:
function printId(id: number | string) {
if (typeof id === "string") {
console.log(`String ID: ${id}`);
} else {
console.log(`Number ID: ${id}`);
}
}
13. TypeScript 中的交叉类型是什么?
解析:交叉类型允许将多个类型组合为一个类型,包含所有类型的属性。
示例:
type Person = { name: string };
type Employee = { employeeId: number };
type EmployeeDetails = Person & Employee;
14. TypeScript 中如何处理可选属性?
解析:可选属性在接口或类中使用问号(?)表示。
示例:
interface Person {
name: string;
age?: number; // 可选属性
}
15. 什么是 TypeScript 的声明文件(.d.ts)?
解析:声明文件用于为 JavaScript 代码提供类型信息,允许 TypeScript 检查类型并提供 IntelliSense。
16. TypeScript 中的 never 类型是什么?
解析:never 类型表示一个永远不会出现的值,通常用于表示抛出异常或无限循环的函数返回值。
示例:
function throwError(message: string): never {
throw new Error(message);
}
17. TypeScript 中的 any 类型是什么?
解析:any 类型表示可以是任何类型,关闭了类型检查,通常用于不确定类型的场景。
18. 如何在 TypeScript 中使用模块?
解析:可以使用 import 和 export 关键字来创建和使用模块。
示例:
// math.ts
export function add(x: number, y: number): number {
return x + y;
}
// app.ts
import { add } from './math';
console.log(add(2, 3));
19. TypeScript 中的函数重载是什么?
解析:函数重载允许为同一函数定义多个类型签名。
示例:
function overload(x: string): string;
function overload(x: number): number;
function overload(x: any): any {
return x;
}
20. 如何在 TypeScript 中处理 Promise?
解析:可以使用 Promise 类型进行异步操作,并使用 async/await 语法简化异步代码。
示例:
async function fetchData(): Promise<string> {
return "数据";
}
21. TypeScript 中如何处理异步编程?
解析:TypeScript 支持使用 Promise、async/await 来处理异步操作。
示例:
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
22. 如何在 TypeScript 中实现类型声明合并?
解析:TypeScript 允许多个同名接口进行合并,合并后的接口包含所有属性。
示例:
interface Person {
name: string;
}
interface Person {
age: number;
}
const john: Person = {
name: "John",
age: 25,
};
23. TypeScript 中的命名空间是什么?
解析:命名空间用于将相关的代码组织在一起,避免全局命名冲突。
示例:
namespace Animals {
export class Dog {
bark() {
console.log("Woof!");
}
}
}
24. 如何在 TypeScript 中使用类型守卫?
解析:类型守卫用于在运行时检查变量的类型,以确保安全地访问对象的属性。
示例:
function isString(value: any): value is string {
return typeof value === "string";
}
const value: any = "Hello";
if (isString(value)) {
console.log(value.toUpperCase());
}
25. TypeScript 中的接口与类型别名有什么区别?
解析:
- 接口用于定义对象的结构,可以被实现和扩展。
- 类型别名可以定义基本类型、联合类型和元组等,不能被扩展。
26. 如何在 TypeScript 中使用模块导入和导出?
解析:使用 export 导出模块中的变量或函数,使用 import 引入。
示例:
// math.ts
export const PI = 3.14;
export function add(a: number, b: number): number {
return a + b;
}
// app.ts
import { PI, add } from './math';
console.log(PI);
console.log(add(2, 3));
27. TypeScript 中的可选链操作符是什么?
解析:可选链操作符(?.)用于安全地访问嵌套对象的属性,如果中间的值为 null 或 undefined,则返回 undefined。
示例:
const obj = { a: { b: { c: 1 } } };
const value = obj.a?.b?.c; // 1
28. TypeScript 中的非空断言操作符是什么?
解析:非空断言操作符(!)用于告知 TypeScript 该值不会是 null 或 undefined。
示例:
let name: string | undefined;
name = "Alice";
console.log(name!); // 断言 name 不会是 undefined
29. 如何在 TypeScript 中实现接口的继承?
解析:接口可以通过 extends 关键字继承其他接口。
示例:
interface Animal {
name: string;
}
interface Dog extends Animal {
bark(): void;
}
30. 解释 TypeScript 中的映射类型。
解析:映射类型允许通过已有类型创建新的类型。
示例:
type Person = {
name: string;
age: number;
};
type ReadOnly<T> = {
readonly [K in keyof T]: T[K];
};
type ReadOnlyPerson = ReadOnly<Person>;
31. TypeScript 中的字面量类型是什么?
解析:字面量类型用于指定变量可以是特定的值。
示例:
let direction: "left" | "right";
direction = "left"; // 合法
// direction = "up"; // 不合法
32. 如何在 TypeScript 中实现函数重载?
解析:函数重载通过定义多个函数签名来实现。
示例:
function combine(a: string, b: string): string;
function combine(a: number, b: number): number;
function combine(a: any, b: any): any {
return a + b;
}
33. TypeScript 中如何使用 Promise 的泛型?
解析:可以在 Promise 中使用泛型来指定返回值的类型。
示例:
function fetchData(): Promise<string> {
return new Promise((resolve) => {
resolve("数据");
});
}
34. 如何在 TypeScript 中实现私有和保护属性?
解析:使用 private 和 protected 关键字来定义类的私有和保护属性。
示例:
class Person {
private name: string;
protected age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
35. 解释 TypeScript 中的 this 类型。
解析:this 类型用于在类型中表示当前类的实例,通常用于链式调用。
示例:
class Chainable {
value: number;
constructor(value: number) {
this.value = value;
}
add(n: number): this {
this.value += n;
return this;
}
}
const result = new Chainable(10).add(5).add(3).value; // 18
36. TypeScript 中的类型推断和类型注解的区别是什么?
解析:
- 类型推断:TypeScript 自动推断变量的类型。
- 类型注解:手动为变量或函数指定类型。
37. 如何在 TypeScript 中处理类型不兼容?
解析:可以使用类型断言来处理类型不兼容的情况。
示例:
let value: any = "Hello";
let strLength: number = (value as string).length;
38. TypeScript 中的函数参数默认值是什么?
解析:可以为函数参数设置默认值,如果调用函数时未提供该参数,则使用默认值。
示例:
function greet(name: string = "World"): string {
return `Hello, ${name}!`;
}
39. 解释 TypeScript 中的 Partial 类型。
解析:Partial 类型用于将对象的所有属性变为可选。
示例:
interface Person {
name: string;
age: number;
}
const updatePerson = (person: Person, updates: Partial<Person>) => {
return { ...person, ...updates };
};
40. 如何在 TypeScript 中处理异步错误?
解析:使用 try/catch 块处理异步函数中的错误。
示例:
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
} catch (error) {
console.error("Error fetching data:", error);
}
}
41. TypeScript 中的 Readonly 类型是什么?
解析:Readonly 类型用于将对象的所有属性设置为只读,不能被修改。
示例:
interface Person {
name: string;
age: number;
}
const person: Readonly<Person> = { name: "Alice", age: 30 };
// person.age = 31; // 错误:无法分配到 "age" ,因为它是只读属性
42. 如何在 TypeScript 中使用条件类型?
解析:条件类型用于根据条件选择不同的类型。
示例:
type IsString<T> = T extends string ? "yes" : "no";
type Test1 = IsString<string>; // "yes"
type Test2 = IsString<number>; // "no"
43. TypeScript 中的 Infer 关键字是什么?
解析:infer 关键字用于在条件类型中声明一个类型变量,并在条件成立时推断出其类型。
示例:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
44. 如何在 TypeScript 中实现接口的合并?
解析:多个同名接口会自动合并,合并后的接口包含所有属性。
示例:
interface Vehicle {
wheels: number;
}
interface Vehicle {
color: string;
}
const bike: Vehicle = { wheels: 2, color: "red" };
45. TypeScript 中的 typeof 操作符有什么用?
解析:typeof 操作符用于获取变量的类型,可以用于类型注解。
示例:
const name = "Alice";
type NameType = typeof name; // string
46. 如何在 TypeScript 中使用 instanceof 来进行类型保护?
解析:instanceof 操作符用于检查对象是否为某个类的实例,从而实现类型保护。
示例:
class Dog {
bark() {
console.log("Woof!");
}
}
function makeSound(animal: Dog | string) {
if (animal instanceof Dog) {
animal.bark();
} else {
console.log(animal);
}
}
47. 解释 TypeScript 中的 keyof 操作符。
解析:keyof 操作符用于获取对象类型的所有键,返回一个联合类型。
示例:
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
48. 如何在 TypeScript 中实现类型的映射?
解析:类型映射允许根据已有类型生成新类型。
示例:
type Person = {
name: string;
age: number;
};
type ReadonlyPerson = {
readonly [K in keyof Person]: Person[K];
};
49. TypeScript 中的 this 类型如何使用?
解析:this 类型用于表示当前类的实例,通常用于链式调用。
示例:
class Builder {
value: number = 0;
add(n: number): this {
this.value += n;
return this;
}
}
const result = new Builder().add(5).add(10).value; // 15
50. 如何在 TypeScript 中创建一个返回 Promise 的函数?
解析:可以通过 Promise 对象来创建异步函数。
示例:
function fetchData(): Promise<string> {
return new Promise((resolve) => {
setTimeout(() => {
resolve("数据加载完成");
}, 1000);
});
}
51. TypeScript 中的 Function 类型是什么?
解析:Function 类型表示一个可以被调用的函数,接受任意参数并返回任意类型。
示例:
let myFunction: Function;
myFunction = (a: number, b: number): number => a + b;
52. 如何在 TypeScript 中使用 unknown 类型?
解析:unknown 类型表示任何类型,但在使用前必须进行类型检查。
示例:
let value: unknown;
value = "Hello";
if (typeof value === "string") {
console.log(value.toUpperCase()); // 合法
}
53. 解释 never 类型在 TypeScript 中的使用场景。
解析:never 类型用于表示不会发生的情况,例如抛出错误的函数。
示例:
function throwError(message: string): never {
throw new Error(message);
}
54. 如何在 TypeScript 中实现类型重映射?
解析:类型重映射允许修改现有类型的属性,通常与映射类型一起使用。
示例:
type Person = {
name: string;
age: number;
};
type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
type NullablePerson = Nullable<Person>;
55. TypeScript 中的 asserts 关键字有什么用?
解析:asserts 关键字用于声明一个类型保护函数,表明在满足某个条件时,参数的类型是确定的。
示例:
function assertIsString(value: any): asserts value is string {
if (typeof value !== "string") {
throw new Error("不是字符串");
}
}
56. 如何在 TypeScript 中定义和使用泛型接口?
解析:可以使用泛型参数来定义接口,以便支持不同的数据类型。
示例:
interface Box<T> {
contents: T;
}
const stringBox: Box<string> = { contents: "Hello" };
const numberBox: Box<number> = { contents: 42 };
57. 解释 TypeScript 中的 Omit 类型。
解析:Omit 类型用于从对象类型中排除特定的属性。
示例:
interface Person {
name: string;
age: number;
email: string;
}
type PersonWithoutEmail = Omit<Person, "email">; // { name: string; age: number; }
58. TypeScript 中的 Pick 类型有什么用?
解析:Pick 类型用于从对象类型中选择特定的属性。
示例:
interface Person {
name: string;
age: number;
email: string;
}
type NameAndEmail = Pick<Person, "name" | "email">; // { name: string; email: string; }
59. 如何在 TypeScript 中进行类型转换?
解析:可以使用类型断言进行类型转换。
示例:
let value: any = "Hello";
let strLength: number = (value as string).length; // 或者使用 <string>value
60. 解释 TypeScript 中的模块和命名空间的区别。
解析:
-
模块:通过
import和export进行管理,支持文件级别的封装。 - 命名空间:用于将相关代码组织在一起,主要用于全局作用域管理。
61. 如何在 TypeScript 中使用 async/await?
解析:async/await 是用于处理异步操作的语法糖,使得异步代码看起来更像同步代码。
示例:
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
62. TypeScript 中的 default 导出和命名导出有什么区别?
解析:
-
默认导出:一个模块只能有一个默认导出,使用
export default。 -
命名导出:一个模块可以有多个命名导出,使用
export。
示例:
// defaultExport.ts
export default function greet() {
console.log("Hello!");
}
// namedExport.ts
export const PI = 3.14;
export function add(a: number, b: number) {
return a + b;
}
63. 解释 TypeScript 中的元组类型。
解析:元组类型用于表示已知元素数量和类型的数组。
示例:
let person: [string, number] = ["Alice", 30];
64. TypeScript 中的 instanceof 和 typeof 的区别是什么?
解析:
-
typeof用于检查基本数据类型,如string、number、boolean等。 -
instanceof用于检查对象是否是某个类的实例。
示例:
const str = "Hello";
console.log(typeof str); // "string"
class Dog {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
65. 如何在 TypeScript 中处理类型的联合和交叉?
解析:联合类型允许一个变量可以是多种类型之一,而交叉类型将多个类型合并为一个。
示例:
type A = { x: number };
type B = { y: number };
let union: A | B = { x: 10 };
union = { y: 20 }; // 合法
let intersection: A & B = { x: 10, y: 20 }; // 必须包含 A 和 B 的所有属性
66. 解释 TypeScript 中的 never 类型的使用场景。
解析:never 类型表示不会正常结束的类型,通常用于抛出异常的函数或无限循环。
示例:
function infiniteLoop(): never {
while (true) {}
}
67. 如何在 TypeScript 中实现防抖(debounce)函数?
解析:防抖是指在某个事件发生后延迟执行函数,避免短时间内多次调用。
示例:
function debounce(func: Function, delay: number) {
let timeout: NodeJS.Timeout;
return function (...args: any[]) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), delay);
};
}
68. TypeScript 中的 null 和 undefined 有什么区别?
解析:
-
null表示“无”或“空值”,通常由程序员手动赋值。 -
undefined表示变量已声明但未赋值。
69. 如何在 TypeScript 中定义和使用接口的扩展?
解析:可以通过 extends 关键字扩展接口。
示例:
interface Animal {
name: string;
}
interface Dog extends Animal {
bark(): void;
}
70. 如何在 TypeScript 中实现函数的默认参数?
解析:可以为函数参数设置默认值,如果调用时未提供该参数,则使用默认值。
示例:
function greet(name: string = "World"): string {
return `Hello, ${name}!`;
}
71. 解释 TypeScript 中的 as 关键字。
解析:as 关键字用于类型断言,告诉编译器将变量视为特定类型。
示例:
let value: any = "Hello";
let strLength: number = (value as string).length; // 使用 as 进行类型断言
72. 如何在 TypeScript 中使用命名空间?
解析:命名空间用于将相关代码组织在一起,避免全局命名冲突。
示例:
namespace MyNamespace {
export function greet() {
console.log("Hello, Namespace!");
}
}
MyNamespace.greet();
73. TypeScript 中的 export = 和 import = require() 有什么区别?
解析:export = 用于CommonJS模块的导出,而 import = require() 用于导入CommonJS模块。
示例:
// module.ts
function greet() {
console.log("Hello!");
}
export = greet;
// app.ts
import greet = require("./module");
greet();
74. 如何在 TypeScript 中实现类型的深拷贝?
解析:可以使用递归函数实现对象的深拷贝。
示例:
function deepCopy<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj));
}
75. 解释 TypeScript 中的 this 类型的使用。
解析:this 类型用于表示当前上下文中的类型,通常用于链式调用和方法。
示例:
class Chainable {
value: number = 0;
add(n: number): this {
this.value += n;
return this;
}
}
const result = new Chainable().add(5).add(10).value; // 15
76. 如何在 TypeScript 中使用 @types 进行类型定义?
解析:通过 @types 组织的类型定义用于为 JavaScript 库提供类型支持,通常使用 npm install @types/包名 安装。
77. TypeScript 中的 Partial 类型有什么用?
解析:Partial 类型用于将对象类型的所有属性变为可选属性。
示例:
interface Person {
name: string;
age: number;
}
const updatePerson = (person: Person, updates: Partial<Person>) => {
return { ...person, ...updates };
};
78. 如何在 TypeScript 中实现类型的映射?
解析:类型映射允许根据已有类型生成新类型。
示例:
type Person = {
name: string;
age: number;
};
type ReadonlyPerson = {
readonly [K in keyof Person]: Person[K];
};
79. 解释 TypeScript 中的 keyof 操作符。
解析:keyof 操作符用于获取对象类型的所有键,返回一个联合类型。
示例:
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
80. 如何在 TypeScript 中使用 type 和 interface 定义类型?
解析:type 用于定义基本类型、联合类型、元组等,而 interface 用于定义对象的结构。
示例:
type StringOrNumber = string | number;
interface Person {
name: string;
age: number;
}
81. TypeScript 中的 Symbols 类型是什么?
解析:Symbols 是一种基本数据类型,表示唯一且不可变的值,通常用于对象属性的唯一标识符。
示例:
const sym = Symbol('description');
const obj = {
[sym]: 'value'
};
console.log(obj[sym]); // "value"
82. 如何在 TypeScript 中实现类型的条件类型?
解析:条件类型基于输入类型选择输出类型。
示例:
type IsString<T> = T extends string ? "Yes" : "No";
type Test1 = IsString<string>; // "Yes"
type Test2 = IsString<number>; // "No"
83. 如何在 TypeScript 中使用 function overload?
解析:可以为同一函数定义多个类型签名,之后实现一个满足所有签名的函数。
示例:
function combine(x: string, y: string): string;
function combine(x: number, y: number): number;
function combine(x: any, y: any): any {
return x + y;
}
84. 什么是 TypeScript 的 Mapped Types?
解析:映射类型用于基于已有类型创建新类型,通常用于修改属性。
示例:
type Person = {
name: string;
age: number;
};
type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
type ReadonlyPerson = Readonly<Person>;
85. 如何在 TypeScript 中使用 unknown 类型?
解析:unknown 类型表示未知类型,必须进行类型检查才能使用。
示例:
let value: unknown;
value = "Hello";
if (typeof value === "string") {
console.log(value.toUpperCase()); // 合法
}
86. 解释 TypeScript 中的 Pick 类型。
解析:Pick 类型用于从对象类型中选择特定的属性以创建新类型。
示例:
interface Person {
name: string;
age: number;
email: string;
}
type NameAndEmail = Pick<Person, "name" | "email">; // { name: string; email: string; }
87. 如何在 TypeScript 中使用 Omit 类型?
解析:Omit 类型用于从对象类型中排除特定的属性。
示例:
interface Person {
name: string;
age: number;
email: string;
}
type PersonWithoutEmail = Omit<Person, "email">; // { name: string; age: number; }
88. TypeScript 中的 readonly 修饰符有什么用?
解析:readonly 修饰符用于将属性设置为只读,不能被修改。
示例:
interface Person {
readonly name: string;
age: number;
}
const person: Person = { name: "Alice", age: 30 };
// person.name = "Bob"; // 错误:只读属性
89. TypeScript 中的 any 类型何时使用?
解析:any 类型用于表示任意类型,通常用于不确定类型的情况,但会丢失类型检查。
90. 如何在 TypeScript 中实现类型的交叉?
解析:交叉类型将多个类型合并为一个,要求包含所有类型的属性。
示例:
type A = { x: number };
type B = { y: number };
type C = A & B; // { x: number; y: number; }
const obj: C = { x: 10, y: 20 };
91. 如何在 TypeScript 中实现抽象类?
解析:抽象类不能被实例化,可以定义抽象方法,让子类实现。
示例:
abstract class Animal {
abstract makeSound(): void; // 抽象方法
}
class Dog extends Animal {
makeSound() {
console.log("Woof!");
}
}
92. 解释 TypeScript 中的 as 关键字的用法。
解析:as 关键字用于类型断言,将一个类型转换为另一个类型。
示例:
let value: any = "Hello";
let strLength: number = (value as string).length; // 使用 as 进行类型断言
93. 如何在 TypeScript 中处理 Promise 和 async/await?
解析:可以使用 Promise 对象处理异步操作,利用 async/await 语法简化代码结构。
示例:
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
94. 如何在 TypeScript 中实现防抖和节流?
解析:防抖和节流都是控制函数执行频率的技术。
示例:
防抖:
function debounce(func: Function, wait: number) {
let timeout: NodeJS.Timeout;
return function(...args: any[]) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
节流:
function throttle(func: Function, limit: number) {
let lastFunc: NodeJS.Timeout;
let lastRan: number;
return function(...args: any[]) {
if (!lastRan) {
func.apply(this, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if ((Date.now() - lastRan) >= limit) {
func.apply(this, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
95. 如何在 TypeScript 中使用 import 和 export?
解析:通过 import 和 export 关键字进行模块化管理。
示例:
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
// app.ts
import { add } from './math';
console.log(add(2, 3));
96. 解释 TypeScript 中的 never 类型。
解析:never 类型表示函数不会正常结束,通常用于抛出错误或无限循环的函数。
示例:
function throwError(message: string): never {
throw new Error(message);
}
97. 如何在 TypeScript 中实现接口的多重继承?
解析:TypeScript 支持接口的多重继承,可以通过 extends 关键字实现。
示例:
interface A {
a: number;
}
interface B {
b: number;
}
interface C extends A, B {
c: number;
}
const obj: C = { a: 1, b: 2, c: 3 };
98. TypeScript 中的 type 和 interface 有何不同?
解析:
-
interface主要用于定义对象的结构,可以被实现和扩展。 -
type可以定义联合类型、交叉类型,也可以用于基本类型的别名。
99. 如何在 TypeScript 中实现类型的序列化和反序列化?
解析:可以使用 JSON 方法进行序列化和反序列化。
示例:
interface Person {
name: string;
age: number;
}
const person: Person = { name: "Alice", age: 30 };
const jsonString = JSON.stringify(person); // 序列化
const parsedPerson: Person = JSON.parse(jsonString); // 反序列化
100. 解释 TypeScript 中的 global 声明。
解析:global 声明用于在全局范围内添加类型定义,通常用于模块化项目。
示例:
declare global {
interface Window {
myGlobalFunction: () => void;
}
}
81. TypeScript 中的 Symbols 类型是什么?
解析:Symbols 是一种基本数据类型,表示唯一且不可变的值,通常用于对象属性的唯一标识符。
示例:
const sym = Symbol('description');
const obj = {
[sym]: 'value'
};
console.log(obj[sym]); // "value"
82. 如何在 TypeScript 中实现类型的条件类型?
解析:条件类型基于输入类型选择输出类型。
示例:
type IsString<T> = T extends string ? "Yes" : "No";
type Test1 = IsString<string>; // "Yes"
type Test2 = IsString<number>; // "No"
83. 如何在 TypeScript 中使用 function overload?
解析:可以为同一函数定义多个类型签名,之后实现一个满足所有签名的函数。
示例:
function combine(x: string, y: string): string;
function combine(x: number, y: number): number;
function combine(x: any, y: any): any {
return x + y;
}
84. 什么是 TypeScript 的 Mapped Types?
解析:映射类型用于基于已有类型创建新类型,通常用于修改属性。
示例:
type Person = {
name: string;
age: number;
};
type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
type ReadonlyPerson = Readonly<Person>;
85. 如何在 TypeScript 中使用 unknown 类型?
解析:unknown 类型表示未知类型,必须进行类型检查才能使用。
示例:
let value: unknown;
value = "Hello";
if (typeof value === "string") {
console.log(value.toUpperCase()); // 合法
}
86. 解释 TypeScript 中的 Pick 类型。
解析:Pick 类型用于从对象类型中选择特定的属性以创建新类型。
示例:
interface Person {
name: string;
age: number;
email: string;
}
type NameAndEmail = Pick<Person, "name" | "email">; // { name: string; email: string; }
87. 如何在 TypeScript 中使用 Omit 类型?
解析:Omit 类型用于从对象类型中排除特定的属性。
示例:
interface Person {
name: string;
age: number;
email: string;
}
type PersonWithoutEmail = Omit<Person, "email">; // { name: string; age: number; }
88. TypeScript 中的 readonly 修饰符有什么用?
解析:readonly 修饰符用于将属性设置为只读,不能被修改。
示例:
interface Person {
readonly name: string;
age: number;
}
const person: Person = { name: "Alice", age: 30 };
// person.name = "Bob"; // 错误:只读属性
89. TypeScript 中的 any 类型何时使用?
解析:any 类型用于表示任意类型,通常用于不确定类型的情况,但会丢失类型检查。
90. 如何在 TypeScript 中实现类型的交叉?
解析:交叉类型将多个类型合并为一个,要求包含所有类型的属性。
示例:
type A = { x: number };
type B = { y: number };
type C = A & B; // { x: number; y: number; }
const obj: C = { x: 10, y: 20 };
91. 如何在 TypeScript 中实现抽象类?
解析:抽象类不能被实例化,可以定义抽象方法,让子类实现。
示例:
abstract class Animal {
abstract makeSound(): void; // 抽象方法
}
class Dog extends Animal {
makeSound() {
console.log("Woof!");
}
}
92. 解释 TypeScript 中的 as 关键字的用法。
解析:as 关键字用于类型断言,将一个类型转换为另一个类型。
示例:
let value: any = "Hello";
let strLength: number = (value as string).length; // 使用 as 进行类型断言
93. 如何在 TypeScript 中处理 Promise 和 async/await?
解析:可以使用 Promise 对象处理异步操作,利用 async/await 语法简化代码结构。
示例:
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
94. 如何在 TypeScript 中实现防抖和节流?
解析:防抖和节流都是控制函数执行频率的技术。
示例:
防抖:
function debounce(func: Function, wait: number) {
let timeout: NodeJS.Timeout;
return function(...args: any[]) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
节流:
function throttle(func: Function, limit: number) {
let lastFunc: NodeJS.Timeout;
let lastRan: number;
return function(...args: any[]) {
if (!lastRan) {
func.apply(this, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if ((Date.now() - lastRan) >= limit) {
func.apply(this, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
95. 如何在 TypeScript 中使用 import 和 export?
解析:通过 import 和 export 关键字进行模块化管理。
示例:
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
// app.ts
import { add } from './math';
console.log(add(2, 3));
96. 解释 TypeScript 中的 never 类型。
解析:never 类型表示函数不会正常结束,通常用于抛出错误或无限循环的函数。
示例:
function throwError(message: string): never {
throw new Error(message);
}
97. 如何在 TypeScript 中实现接口的多重继承?
解析:TypeScript 支持接口的多重继承,可以通过 extends 关键字实现。
示例:
interface A {
a: number;
}
interface B {
b: number;
}
interface C extends A, B {
c: number;
}
const obj: C = { a: 1, b: 2, c: 3 };
98. TypeScript 中的 type 和 interface 有何不同?
解析:
-
interface主要用于定义对象的结构,可以被实现和扩展。 -
type可以定义联合类型、交叉类型,也可以用于基本类型的别名。
99. 如何在 TypeScript 中实现类型的序列化和反序列化?
解析:可以使用 JSON 方法进行序列化和反序列化。
示例:
interface Person {
name: string;
age: number;
}
const person: Person = { name: "Alice", age: 30 };
const jsonString = JSON.stringify(person); // 序列化
const parsedPerson: Person = JSON.parse(jsonString); // 反序列化
100. 解释 TypeScript 中的 global 声明。
解析:global 声明用于在全局范围内添加类型定义,通常用于模块化项目。
示例:
declare global {
interface Window {
myGlobalFunction: () => void;
}
}
101. TypeScript 中的 KeyRemapping 是什么?
解析:KeyRemapping 是在映射类型中重命名键的能力,使得可以根据某些条件重命名对象的属性。
示例:
type Person = {
name: string;
age: number;
};
type Mapped = {
[K in keyof Person as Uppercase<K>]: Person[K];
};
// Mapped 的类型为 { NAME: string; AGE: number; }
102. 如何在 TypeScript 中使用 asserts 声明?
解析:asserts 声明用于类型保护,表示一个函数在通过某个条件时会确保其参数的类型。
示例:
function isString(value: any): asserts value is string {
if (typeof value !== "string") {
throw new Error("Not a string");
}
}
let myValue: any = "Hello";
isString(myValue); // 此时 myValue 被认为是 string 类型
103. TypeScript 如何处理 this 指向?
解析:在 TypeScript 中,可以使用箭头函数保持 this 的上下文,或者在方法中使用 this 类型来明确指向。
示例:
class Counter {
count = 0;
increment() {
setTimeout(() => {
this.count++; // 这里的 this 指向 Counter 实例
}, 1000);
}
}
104. 什么是 TypeScript 的 Union Types 和 Intersection Types?
解析:
- Union Types 允许一个变量可以是多种类型之一。
- Intersection Types 将多个类型合并为一个类型,要求包含所有类型的属性。
示例:
type StringOrNumber = string | number; // Union
type A = { x: number };
type B = { y: number };
type C = A & B; // Intersection
105. 如何在 TypeScript 中定义和使用 Type Guards?
解析:类型保护是用于在运行时检查类型的机制,通常通过 typeof、instanceof 或自定义类型保护函数实现。
示例:
function isString(value: any): value is string {
return typeof value === "string";
}
function print(value: string | number) {
if (isString(value)) {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
106. TypeScript 中的 ReadonlyArray 是什么?
解析:ReadonlyArray 是一种数组类型,表示数组的所有元素都是只读的,不能被修改。
示例:
let arr: ReadonlyArray<number> = [1, 2, 3];
// arr[0] = 10; // 错误:无法分配到 "0",因为它是只读属性
107. 如何在 TypeScript 中使用 null 和 undefined 的类型检查?
解析:可以在类型中显式指定 null 和 undefined,并使用类型保护进行检查。
示例:
function processValue(value: string | null | undefined) {
if (value != null) { // 同时检查 null 和 undefined
console.log(value.toUpperCase());
} else {
console.log("Value is null or undefined");
}
}
108. 什么是 TypeScript 的 Declaration Merging?
解析:声明合并是指 TypeScript 允许多个同名的接口或命名空间合并为一个。
示例:
interface User {
name: string;
}
interface User {
age: number;
}
const user: User = { name: "Alice", age: 30 }; // 合并后的类型
109. TypeScript 中的 Function Overloads 如何实现?
解析:可以定义多个函数签名,随后实现一个函数来满足所有签名。
示例:
function combine(x: string, y: string): string;
function combine(x: number, y: number): number;
function combine(x: any, y: any): any {
return x + y;
}
110. 如何在 TypeScript 中使用 import type?
解析:import type 用于仅导入类型,而不导入实际值,有助于减少编译时的依赖。
示例:
import type { User } from './user';
function processUser(user: User) {
console.log(user.name);
}
111. 如何在 TypeScript 中处理 Promise 的错误?
解析:可以使用 try/catch 块来处理 async 函数中的错误,或在 .catch 方法中处理 Promise 的错误。
示例:
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
} catch (error) {
console.error("Error fetching data:", error);
}
}
112. 如何在 TypeScript 中实现 Constructor Signature?
解析:可以定义构造函数的签名,并在类中实现该签名。
示例:
interface PersonConstructor {
new (name: string): Person;
}
class Person {
constructor(public name: string) {}
}
function createPerson(ctor: PersonConstructor, name: string) {
return new ctor(name);
}
const john = createPerson(Person, "John");
113. TypeScript 中的 Tuple Types 有什么特点?
解析:元组类型用于表示已知元素数量和类型的数组,元组的每个元素可以具有不同的类型。
示例:
let tuple: [string, number] = ["Alice", 30];
114. 如何在 TypeScript 中处理 Any 和 Unknown 的区别?
解析:
-
any可以赋值为任何类型,关闭了类型检查。 -
unknown表示未知类型,必须进行类型检查后才能使用。
115. 如何在 TypeScript 中实现从 Promise 中获取返回值的类型?
解析:可以使用条件类型和 infer 关键字来提取 Promise 的返回类型。
示例:
type Awaited<T> = T extends Promise<infer U> ? U : T;
type Result = Awaited<Promise<string>>; // string
116. 解释 TypeScript 的 Record 类型。
解析:Record 类型用于构建对象类型,键是某种类型,值是另一种类型。
示例:
type Page = "home" | "about" | "contact";
type PageInfo = Record<Page, { title: string }>;
// PageInfo 的类型为 {
// home: { title: string },
// about: { title: string },
// contact: { title: string }
// }
117. 如何在 TypeScript 中定义一个递归类型?
解析:可以定义一个类型引用自身来实现递归类型。
示例:
type NestedArray<T> = T | NestedArray<T>[];
const nested: NestedArray<number> = [1, [2, [3]]];
118. 如何在 TypeScript 中使用 template literal types?
解析:模板字面量类型用于构造字符串类型,可以将字符串字面量组合成新类型。
示例:
type Direction = "left" | "right";
type Movement = `move ${Direction}`; // "move left" | "move right"
119. TypeScript 中的 Conditional Types 如何实现?
解析:条件类型用于根据输入类型选择输出类型。
示例:
type IsString<T> = T extends string ? "Yes" : "No";
type Result1 = IsString<string>; // "Yes"
type Result2 = IsString<number>; // "No"
120. 如何在 TypeScript 中处理深拷贝?
解析:可以使用递归函数或 JSON 方法进行深拷贝。
示例:
function deepClone<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj));
}
121. 如何在 TypeScript 中实现 Type Assertion?
解析:类型断言用于告诉 TypeScript 编译器某个值的具体类型,可以使用 as 关键字或尖括号语法。
示例:
let someValue: unknown = "Hello World";
let strLength: number = (someValue as string).length; // 使用 as 进行类型断言
// 或者使用尖括号
// let strLength: number = (<string>someValue).length;
122. TypeScript 中的 Function 类型如何声明?
解析:可以通过函数签名来声明 Function 类型。
示例:
let myFunction: (x: number, y: number) => number;
myFunction = (a, b) => a + b;
123. 如何在 TypeScript 中定义 Union Types?
解析:联合类型允许一个变量可以是多种类型之一。
示例:
let value: string | number;
value = "Hello"; // 合法
value = 42; // 合法
// value = true; // 错误
124. 解释 TypeScript 中的 Intersection Types。
解析:交叉类型将多个类型合并为一个,包含所有类型的属性。
示例:
type A = { x: number };
type B = { y: number };
type C = A & B; // { x: number; y: number; }
const obj: C = { x: 10, y: 20 };
125. TypeScript 中的 never 类型有什么应用场景?
解析:never 类型表示不会正常结束的值,通常用于抛出异常或无限循环的函数。
示例:
function throwError(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}
126. 如何在 TypeScript 中使用 Namespacing?
解析:命名空间用于将相关代码组织在一起,以避免全局命名冲突。
示例:
namespace MyNamespace {
export function greet() {
console.log("Hello, Namespace!");
}
}
MyNamespace.greet();
127. 如何在 TypeScript 中创建和使用 Abstract Classes?
解析:抽象类不能被实例化,可以定义抽象方法,要求子类实现。
示例:
abstract class Animal {
abstract makeSound(): void; // 抽象方法
}
class Dog extends Animal {
makeSound() {
console.log("Woof!");
}
}
const dog = new Dog();
dog.makeSound(); // "Woof!"
128. TypeScript 中的 Template Literal Types 有何用途?
解析:模板字面量类型允许基于字符串字面量构建新类型。
示例:
type Direction = "left" | "right";
type Movement = `move ${Direction}`; // "move left" | "move right"
129. 如何在 TypeScript 中使用 Keyof 操作符?
解析:keyof 操作符用于获取对象类型的所有键,返回一个联合类型。
示例:
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
130. 解释 TypeScript 中的 Readonly 和 Partial 类型。
解析:
- Readonly:将对象的所有属性设置为只读。
- Partial:将对象的所有属性变为可选。
示例:
type Person = {
name: string;
age: number;
};
type ReadonlyPerson = Readonly<Person>; // 所有属性只读
type PartialPerson = Partial<Person>; // 所有属性可选
131. TypeScript 中的 Mapped Types 有什么用途?
解析:映射类型允许根据已有类型创建新类型,通常用于修改属性。
示例:
type Person = {
name: string;
age: number;
};
type ReadonlyPerson = {
readonly [K in keyof Person]: Person[K];
};
132. 如何在 TypeScript 中使用 Conditional Types?
解析:条件类型根据输入类型选择输出类型。
示例:
type IsString<T> = T extends string ? "Yes" : "No";
type Result1 = IsString<string>; // "Yes"
type Result2 = IsString<number>; // "No"
133. 如何在 TypeScript 中处理 Promise 的返回值?
解析:可以使用 Awaited 类型提取 Promise 的返回类型。
示例:
type Awaited<T> = T extends Promise<infer U> ? U : T;
type Result = Awaited<Promise<string>>; // string
134. 解释 TypeScript 中的 Record 类型。
解析:Record 类型用于构建对象类型,键是某种类型,值是另一种类型。
示例:
type Page = "home" | "about" | "contact";
type PageInfo = Record<Page, { title: string }>;
// PageInfo 的类型为 {
// home: { title: string },
// about: { title: string },
// contact: { title: string }
// }
135.如何在 TypeScript 中使用 Function Overloads?
解析:通过定义多个函数签名来实现函数重载。
示例:
function greet(person: string): string;
function greet(person: string, age: number): string;
function greet(person: string, age?: number): string {
return age ? `Hello, ${person}. You are ${age} years old.` : `Hello, ${person}.`;
}
136. 如何在 TypeScript 中使用 this 类型?
解析:使用 this 类型可以在类方法中表示当前实例的类型。
示例:
class Chainable {
value: number = 0;
add(n: number): this {
this.value += n;
return this;
}
}
const result = new Chainable().add(5).add(10).value; // 15
137. TypeScript 中的 typeof 操作符如何使用?
解析:typeof 操作符用于获取变量的类型,可以用于类型注解。
示例:
const name = "Alice";
type NameType = typeof name; // string
138. 解释 TypeScript 中的 infer 关键字。
解析:infer 关键字用于在条件类型中声明类型变量,并在条件成立时推断出其类型。
示例:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
139. 如何在 TypeScript 中使用 async/await?
解析:async/await 是用于处理异步操作的语法,使得异步代码看起来更像同步代码。
示例:
async function fetchData(): Promise<string> {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
140. 如何在 TypeScript 中实现深拷贝?
解析:可以使用递归函数或 JSON 方法进行深拷贝。
示例:
function deepClone<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj));
}