我们在面试的时候,经常会遇到TypeScript 的一些面试题,因此,今天这篇文章,我整理汇总了40道关于TypeScript 的基础知识的面试题。有提供详细的参考答案、代码示例以及相关的延伸阅读内容。
1.什么是 TypeScript,它与 JavaScript 有何不同?提供 TypeScript 代码示例。
答案:TypeScript 是 JavaScript 的超集,为该语言添加了静态类型。它允许开发人员定义变量、函数参数和返回值的数据类型,这有助于在编译时而不是运行时捕获错误。这是一个例子:
function greet(name: string): string { return `Hello, ${name}!`;}const message: string = greet('John');console.log(message); // Output: "Hello, John!"
**延伸阅读:**TypeScript 官方网站(https://www.typescriptlang.org/)
2.解释 TypeScript 中静态类型的概念及其好处。
答案:TypeScript 中的静态类型可以在开发过程中指定变量、函数参数和返回值的数据类型。这有助于及早捕获与类型相关的错误,从而提高代码质量和可维护性。
好处是拥有更好的代码文档、增强的工具支持以及提高的开发人员生产力。
**延伸阅读:**TypeScript 官方手册------基本类型(https://www.typescriptlang.org/docs/handbook/basic-types.html)
3.TypeScript 中的接口是什么?举个例子。
答案:TypeScript 中的接口定义了对象结构的契约,指定其属性和方法的名称和类型。它们促进强大的类型检查并实现更好的代码组织。这是一个例子:
interface Person { name: string; age: number;}function greet(person: Person): string { return `Hello, ${person.name}! You are ${person.age} years old.`;}const john: Person = { name: 'John', age: 30 };const message: string = greet(john);console.log(message); // Output: "Hello, John! You are 30 years old."
**延伸阅读:**TypeScript 官方手册------接口(https://www.typescriptlang.org/docs/handbook/interfaces.html)
4.使用 TypeScript 相对于纯 JavaScript 有什么好处?
答:TypeScript 提供了多种好处,包括静态类型、更好的代码分析和工具支持、改进的代码可读性、早期错误检测、更轻松的代码重构以及增强的代码文档。它还使开发人员能够编写更易于维护和扩展的应用程序。
延伸阅读:TypeScript 官方网站 --- 为什么选择 TypeScript?(https://www.typescriptlang.org/docs/handbook/why-typescript.html)
5.如何在 TypeScript 的接口中定义可选属性?举个例子。
答案:您可以使用 ? 在接口中定义可选属性。属性名称后面的修饰符。可选属性可能存在于实现该接口的对象中,也可能不存在。这是一个例子:
interface Person { name: string; age?: number;}const john: Person = { name: 'John' };const jane: Person = { name: 'Jane', age: 25 };
延伸阅读:TypeScript 官方手册------接口(https://www.typescriptlang.org/docs/handbook/interfaces.html)
6.解释 TypeScript 中联合类型的概念并提供示例。
答:联合类型允许一个变量有多种类型。它通过使用 | 来表示类型之间的符号。这允许变量存储任何指定类型的值。这是一个例子:
function printId(id: number | string): void { console.log(`ID: ${id}`);}printId(123); // Output: "ID: 123"printId('abc'); // Output: "ID: abc"
延伸阅读:TypeScript 官方手册------联合类型(https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html)
7.TypeScript 中的类型断言是什么?举个例子。
答案:当无法自动推断类型时,TypeScript 中的类型断言允许您显式告诉编译器变量的类型。这是使用 <type> 或 as type 语法实现的。这是一个例子:
let length: any = '5';let numberLength: number = <number>length; // Using <type> syntaxlet stringLength: number = length as number; // Using "as type" syntax
延伸阅读:TypeScript 官方手册------类型断言(https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions)
8.如何在 TypeScript 中定义具有可选参数和默认参数的函数?举个例子。
答案:您可以使用 ? 定义带有可选参数和默认参数的函数。可选参数的修饰符以及为参数分配默认值。这是一个例子:
function greet(name: string, message: string = 'Hello', times?: number): void { for (let i = 0; i < (times || 1); i++) { console.log(`${message}, ${name}!`); }}greet('John'); // Output: "Hello, John!"greet('Jane', 'Hi'); // Output: "Hi, Jane!"greet('Tom', 'Hey', 3); // Output: "Hey, Tom!", "Hey, Tom!", "Hey, Tom!"
延伸阅读:TypeScript 官方手册------函数(https://www.typescriptlang.org/docs/handbook/functions.html)
9.TypeScript 中的泛型是什么?举个例子。
答案:TypeScript 中的泛型允许您创建可与各种类型一起使用的可重用组件或函数。它们支持强类型,同时保持使用不同数据类型的灵活性。这是一个例子:
function identity<T>(arg: T): T { return arg;}const result1 = identity<number>(42); // Explicitly specifying the typeconst result2 = identity('hello'); // Inferring the type
延伸阅读:TypeScript 官方手册------泛型(https://www.typescriptlang.org/docs/handbook/generics.html)
10.通过示例解释 TypeScript 中的"keyof"关键字。
答案:TypeScript 中的"keyof"关键字是一个类型运算符,它返回表示对象键的文字类型的联合。它允许您对对象键执行类型安全操作。这是一个例子:
interface Person { name: string; age: number;}type PersonKeys = keyof Person; // "name" | "age"
延伸阅读:TypeScript 官方手册------索引类型(https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types)
11. TypeScript 中的类型保护是什么?它们如何工作?举个例子。
答案:类型防护是 TypeScript 表达式,它在运行时检查变量的类型,并允许您根据类型执行不同的操作。它们可以实现更好的类型推断,并提供一种更有效地处理联合类型的方法。
这是使用 typeof 和 instanceof 类型保护的示例:
function printValue(value: string | number): void { if (typeof value === 'string') { console.log(`The value is a string: ${value}`); } else if (typeof value === 'number') { console.log(`The value is a number: ${value}`); }}class Person { name: string; constructor(name: string) { this.name = name; }}function greet(person: Person | string): void { if (person instanceof Person) { console.log(`Hello, ${person.name}!`); } else if (typeof person === 'string') { console.log(`Hello, ${person}!`); }}const stringValue: string = 'Hello';const numberValue: number = 42;
printValue(stringValue); // Output: "The value is a string: Hello"printValue(numberValue); // Output: "The value is a number: 42"
const john: Person = new Person('John');
greet(john); // Output: "Hello, John!"greet('Jane'); // Output: "Hello, Jane!"
延伸阅读:TypeScript 官方手册 --- Type Guards(https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards)
12.解释 TypeScript 中条件类型的概念。举个例子。
答案:TypeScript 中的条件类型允许您创建依赖于条件的类型。它们用于根据类型之间的关系执行类型推断。这是一个例子:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;function add(a: number, b: number): number { return a + b;}type AddReturnType = ReturnType<typeof add>; // number
在此示例中,ReturnType 是推断函数返回类型的条件类型。
延伸阅读:TypeScript 官方手册------条件类型(https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types)
13.TypeScript 中的映射类型是什么?举个例子。
答案:TypeScript 中的映射类型允许您通过将属性映射到新类型来基于现有类型创建新类型。它们使您能够轻松修改现有类型或向现有类型添加属性。这是一个例子:
interface Person { name: string; age: number;}type PersonWithOptionalProperties = { [K in keyof Person]?: Person[K] };const john: Person = { name: 'John', age: 30 };const johnWithOptionalProperties: PersonWithOptionalProperties = { name: 'John' };
在此示例中,PersonWithOptionalProperties 是一个映射类型,它使 Person 的所有属性都是可选的。
延伸阅读:TypeScript 官方手册 --- 映射类型(https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)
14.解释 TypeScript 中的"部分"实用程序类型。举个例子。
答案:TypeScript 中的"部分"实用程序类型用于使现有类型的所有属性成为可选。它允许您从现有类型创建具有可选属性的新类型。这是一个例子:
interface Person { name: string; age: number;}type PartialPerson = Partial<Person>;const john: PartialPerson = { name: 'John' };
在此示例中,PartialPerson 是具有来自 Person 接口的可选属性的类型。
延伸阅读:TypeScript 官方手册------实用类型(https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype)
15.TypeScript 中的"只读"实用程序类型是什么?它是如何工作的?举个例子。
答案:TypeScript 中的"Readonly"实用程序类型用于使现有类型的所有属性变为只读。它可以防止对象创建后修改其属性。这是一个例子:
interface Person { readonly name: string; age: number;}const john: Readonly<Person> = { name: 'John', age: 30 };john.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.
在此示例中,age 属性可以修改,但 name 属性是只读的。
延伸阅读:TypeScript 官方手册------实用类型
16.映射类型中的"键重新映射"和"值重新映射"是什么?为每个提供示例。
回答:"键重映射"和"值重映射"是 TypeScript 中映射类型的两个特性。
"键重新映射"允许您使用 as 关键字更改现有类型的键。这是一个例子:
interface Person { name: string; age: number;}type MappedPerson = { [K in keyof Person as `new_${K}`]: Person[K] };const john: MappedPerson = { new_name: 'John', new_age: 30 };
在此示例中,Person 的键被重新映射为具有前缀"new_"。
"值重新映射"允许您使用条件类型更改现有类型的值。这是一个例子:
type ValueRemapped<T> = T extends 'a' ? 'x' : T extends 'b' ? 'y' : 'z';type Result = ValueRemapped<'a' | 'b' | 'c'>; // Result: 'x' | 'y' | 'z'
在此示例中,值"a"、"b"和"c"分别重新映射为"x"、"y"和"z"。
延伸阅读:TypeScript 官方手册 --- 映射类型(https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types)
17.解释 TypeScript 中的"Pick"实用程序类型。举个例子。
答案:TypeScript 中的"Pick"实用程序类型允许您通过从现有类型中选择特定属性来创建新类型。它有助于创建现有类型的子集。这是一个例子:
interface Person { name: string; age: number; city: string;}type PersonInfo = Pick<Person, 'name' | 'age'>;const john: PersonInfo = { name: 'John', age: 30 };
在此示例中,PersonInfo 是仅包含 Person 接口中的"name"和"age"属性的类型。
延伸阅读:TypeScript 官方手册------实用类型(https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)
18.TypeScript 中的"Omit"实用程序类型是什么?它是如何工作的?举个例子。
答案:TypeScript 中的"Omit"实用程序类型允许您通过从现有类型中排除特定属性来创建新类型。它有助于创建删除了某些属性的类型。这是一个例子:
interface Person { name: string; age: number; city: string;}type PersonWithoutCity = Omit<Person, 'city'>;const john: PersonWithoutCity = { name: 'John', age: 30 };
在此示例中,PersonWithoutCity 是一种从 Person 接口中排除"city"属性的类型。
延伸阅读:TypeScript 官方手册------实用类型(https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)
19.TypeScript 中的"条件映射类型"是什么?举个例子。
答:条件映射类型将条件类型和映射类型结合起来,根据条件执行类型转换。它们允许您根据现有类型的属性创建动态类型。这是一个例子:
interface Person { name: string; age: number;}type MappedConditional<T> = { [K in keyof T]: T[K] extends number ? string : T[K];};const john: MappedConditional<Person> = { name: 'John', age: '30' };
在此示例中,MappedConditional 是一个条件映射类型,它将 Person 的数字属性转换为字符串。
延伸阅读:TypeScript 官方手册 --- 映射类型(https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types)
20.条件类型中"keyof"和"in"关键字的用途是什么?举个例子。
答案:条件类型中的"keyof"关键字用于获取对象类型的键的并集。它允许您以类型安全的方式使用对象的键。"in"关键字检查属性键是否存在于从"keyof"获得的键的并集中。这是一个例子:
type CheckKey<T, K extends keyof T> = K extends 'name' ? true : false;interface Person { name: string; age: number;}type IsNameKey = CheckKey<Person, 'name'>; // Result: truetype IsCityKey = CheckKey<Person, 'city'>; // Result: false
在此示例中,CheckKey 是一个条件类型,用于检查提供的键是否为"name"。
延伸阅读:TypeScript 官方手册 --- keyof Type Operator、TypeScript 官方手册 --- in Operator(https://www.typescriptlang.org/docs/handbook/advanced-types.html#keyof-type-operator)