《前后端面试题
》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux... 。

文章目录
- 一、本文面试题目录
-
-
- [11. TypeScript的基础类型有哪些?与JavaScript的原始类型有何关联?](#11. TypeScript的基础类型有哪些?与JavaScript的原始类型有何关联?)
- [12. `any`、`unknown`、`never`、`void`的区别是什么?分别在什么场景下使用?](#12.
any
、unknown
、never
、void
的区别是什么?分别在什么场景下使用?) - [13. `null`和`undefined`在TypeScript中默认是哪些类型的子类型?如何修改这一行为?](#13.
null
和undefined
在TypeScript中默认是哪些类型的子类型?如何修改这一行为?) - [14. 类型断言的两种语法是什么?使用时需要注意什么风险?](#14. 类型断言的两种语法是什么?使用时需要注意什么风险?)
- [15. 什么是类型推断?TypeScript在哪些场景下会自动推断类型?](#15. 什么是类型推断?TypeScript在哪些场景下会自动推断类型?)
- [16. 如何定义数组类型?`number[]`与`Array<number>`有区别吗?](#16. 如何定义数组类型?
number[]
与Array<number>
有区别吗?) - [17. 元组(Tuple)的特点是什么?与数组的核心区别是什么?如何给元组设置可选元素?](#17. 元组(Tuple)的特点是什么?与数组的核心区别是什么?如何给元组设置可选元素?)
- [18. 枚举(Enum)的作用是什么?数字枚举和字符串枚举的区别?枚举会被编译成什么代码?](#18. 枚举(Enum)的作用是什么?数字枚举和字符串枚举的区别?枚举会被编译成什么代码?)
- [19. 什么是字面量类型?如何结合联合类型实现"有限选项"约束?](#19. 什么是字面量类型?如何结合联合类型实现“有限选项”约束?)
- [20. `bigint`和`symbol`类型在TypeScript中如何使用?与JavaScript有何差异?](#20.
bigint
和symbol
类型在TypeScript中如何使用?与JavaScript有何差异?)
-
- 二、100道TypeScript面试题目录列表
一、本文面试题目录
11. TypeScript的基础类型有哪些?与JavaScript的原始类型有何关联?
- 答案 :TypeScript的基础类型包括:
number
、string
、boolean
、null
、undefined
、symbol
、bigint
、object
、array
、tuple
、enum
、any
、unknown
、void
、never
。
其中,number
、string
、boolean
、null
、undefined
、symbol
、bigint
与JavaScript的原始类型一一对应,是对JavaScript原始类型的直接映射。TypeScript在此基础上扩展了array
(数组)、tuple
(元组)、enum
(枚举)等复合类型,以及any
、unknown
、void
、never
等用于类型控制的特殊类型。
- 示例代码:
typescript
// 对应JavaScript原始类型
const num: number = 10;
const str: string = "hello";
const bool: boolean = true;
const n: null = null;
const u: undefined = undefined;
const sym: symbol = Symbol("key");
const big: bigint = 100n;
// TypeScript扩展类型
const arr: number[] = [1, 2, 3];
const tuple: [string, number] = ["age", 25];
enum Color { Red, Green }
12. any
、unknown
、never
、void
的区别是什么?分别在什么场景下使用?
-
答案:
-
any
:表示任意类型,关闭类型检查。变量声明为any
后,可赋值任意类型,也可调用任意方法(即使不存在)。- 场景:临时兼容JavaScript代码,或处理类型完全动态的数据(如JSON.parse的结果)。
-
unknown
:表示未知类型,比any
更安全。变量声明为unknown
后,不能直接调用方法或赋值给其他类型(需先类型检查)。- 场景:接收未知类型的输入(如API返回值),需显式验证类型后再使用。
-
void
:表示函数无返回值(或返回undefined
)。- 场景:定义没有返回值的函数(如仅执行副作用的函数)。
-
never
:表示永远不会发生的值(函数永不返回)。- 场景:抛出异常的函数、无限循环的函数,或用于类型守卫的穷尽检查。
-
-
示例代码:
typescript
// any:关闭类型检查
const value: any = "hello";
value.toUpperCase(); // 允许
value.foo(); // 不报错(运行时可能出错)
// unknown:需先验证类型
const input: unknown = "test";
if (typeof input === "string") {
input.toUpperCase(); // 验证后允许
}
// void:无返回值函数
function log(message: string): void {
console.log(message);
}
// never:永远不返回
function throwError(): never {
throw new Error("出错了");
}
function infiniteLoop(): never {
while (true) {}
}
13. null
和undefined
在TypeScript中默认是哪些类型的子类型?如何修改这一行为?
- 答案 :在默认配置下,
null
和undefined
是所有类型的子类型,即可以赋值给任意类型(如number
、string
等)。
这种行为可通过tsconfig.json
中的strictNullChecks
配置修改:
-
当
strictNullChecks: true
时,null
和undefined
只能赋值给any
、unknown
、null
、undefined
本身,或显式声明允许null
/undefined
的类型(如string | null
)。 -
示例代码:
typescript
// strictNullChecks: false(默认)
let str: string = "hello";
str = null; // 不报错
str = undefined; // 不报错
// strictNullChecks: true
let str: string = "hello";
str = null; // 报错
str = undefined; // 报错
// 显式允许null/undefined
let nullableStr: string | null = "hello";
nullableStr = null; // 不报错
14. 类型断言的两种语法是什么?使用时需要注意什么风险?
-
答案:类型断言用于告诉编译器"我知道这个值的类型是什么",强制将一种类型转换为另一种类型,有两种语法:
<类型>值
:如<string>value
值 as 类型
:如value as string
(推荐,在JSX中必须使用)
-
风险:类型断言是开发者手动干预类型检查,若断言错误(实际类型与断言类型不符),编译时不会报错,但运行时可能出现异常。因此,断言前应确保类型兼容。
-
示例代码:
typescript
const value: unknown = "hello";
// 两种断言语法
const str1: string = <string>value;
const str2: string = value as string;
// 错误示例(风险)
const num: number = value as number; // 编译不报错,运行时实际是string,可能引发错误
15. 什么是类型推断?TypeScript在哪些场景下会自动推断类型?
- 答案:类型推断是TypeScript根据代码上下文自动确定变量、函数参数或返回值类型的能力,无需显式声明类型。
常见推断场景:
- 变量初始化:声明变量时赋值,推断为值的类型。
- 函数返回值:根据return语句推断返回值类型。
- 函数参数默认值:根据默认值推断参数类型。
- 数组和对象:根据初始值推断数组元素类型或对象属性类型。
- 示例代码:
typescript
// 1. 变量初始化推断
let age = 25; // 推断为number
let name = "Alice"; // 推断为string
// 2. 函数返回值推断
function add(a: number, b: number) {
return a + b; // 推断返回值为number
}
// 3. 参数默认值推断
function greet(name = "Guest") { // 推断name为string
console.log(`Hello, ${name}`);
}
// 4. 数组和对象推断
const numbers = [1, 2, 3]; // 推断为number[]
const user = { name: "Bob", age: 30 }; // 推断为{ name: string; age: number }
16. 如何定义数组类型?number[]
与Array<number>
有区别吗?
- 答案 :TypeScript中定义数组类型有两种方式:
类型[]
:如number[]
(表示数字数组)Array<类型>
:如Array<number>
(泛型语法,与前者等价)
number[]
与Array<number>
在功能上完全一致,没有区别,只是语法形式不同。类型[]
是简洁写法,Array<类型>
是泛型写法,后者更适合复杂场景(如嵌套数组Array<Array<number>>
)。
- 示例代码:
typescript
// 两种定义方式等价
const arr1: number[] = [1, 2, 3];
const arr2: Array<number> = [4, 5, 6];
// 嵌套数组
const nestedArr1: number[][] = [[1], [2]];
const nestedArr2: Array<Array<number>> = [[3], [4]];
17. 元组(Tuple)的特点是什么?与数组的核心区别是什么?如何给元组设置可选元素?
-
答案:
-
元组特点:元组是一种特殊的数组,其元素数量固定,且每个位置的元素类型可以不同(需显式声明)。
-
与数组的核心区别:
- 数组元素类型通常相同,长度可变;
- 元组元素类型可不同,长度固定(声明时指定)。
-
设置可选元素 :在元组类型的元素后加
?
,表示该元素可选(必须放在最后)。
-
-
示例代码:
typescript
// 元组:固定长度,类型可不同
const user: [string, number] = ["Alice", 25];
// 数组:长度可变,类型通常相同
const ages: number[] = [25, 30, 35];
// 可选元素的元组(最后一个元素可选)
const data: [string, number?] = ["test"]; // 不报错
const data2: [string, number?] = ["test", 100]; // 不报错
18. 枚举(Enum)的作用是什么?数字枚举和字符串枚举的区别?枚举会被编译成什么代码?
-
答案:
-
枚举作用:定义一组命名的常量,提高代码可读性和可维护性(如表示状态、选项等固定值集合)。
-
数字枚举 vs 字符串枚举:
- 数字枚举:默认值从0开始自增,可手动指定初始值,支持反向映射(通过值获取键)。
- 字符串枚举:每个成员必须显式赋值字符串,不支持反向映射,更适合需要明确字符串值的场景。
-
编译结果:
- 数字枚举编译为对象(包含正向映射和反向映射);
- 字符串枚举编译为仅包含正向映射的对象。
-
-
示例代码:
typescript
// 数字枚举
enum Direction {
Up, // 0
Down, // 1
Left = 10, // 手动指定
Right // 11(自增)
}
console.log(Direction.Up); // 0
console.log(Direction[0]); // "Up"(反向映射)
// 字符串枚举
enum Status {
Success = "OK",
Error = "FAIL"
}
console.log(Status.Success); // "OK"
编译后代码(简化):
javascript
// 数字枚举编译结果
var Direction = {
0: "Up", 1: "Down", 10: "Left", 11: "Right",
Up: 0, Down: 1, Left: 10, Right: 11
};
// 字符串枚举编译结果
var Status = {
Success: "OK",
Error: "FAIL"
};
19. 什么是字面量类型?如何结合联合类型实现"有限选项"约束?
- 答案 :字面量类型是指具体的值作为类型(如
"red"
、10
、true
),变量只能取该字面量值。
结合联合类型(|
)可实现"有限选项"约束,即变量只能从指定的几个字面量值中选择。
- 示例代码:
typescript
// 字面量类型
const num: 10 = 10; // 只能是10
const str: "success" = "success"; // 只能是"success"
// 联合类型 + 字面量:有限选项约束
type Alignment = "left" | "center" | "right";
let align: Alignment = "left"; // 允许
align = "center"; // 允许
align = "top"; // 报错(不在选项中)
// 应用场景:函数参数约束
function setAlignment(align: Alignment) {
console.log(`Aligning to ${align}`);
}
setAlignment("right"); // 允许
setAlignment("justify"); // 报错
20. bigint
和symbol
类型在TypeScript中如何使用?与JavaScript有何差异?
-
答案:
-
bigint
:用于表示超出number
范围的大整数,TypeScript中需显式声明类型为bigint
,值后加n
。与JavaScript相比,TypeScript强制类型检查,不允许bigint
与number
直接运算(需显式转换)。 -
symbol
:用于创建唯一标识符,TypeScript中声明类型为symbol
,通过Symbol()
创建。与JavaScript相比,TypeScript可通过unique symbol
子类型确保符号的唯一性(需用const
声明)。
-
-
示例代码:
typescript
// bigint使用
const big: bigint = 100n; // 显式声明类型
const larger: bigint = BigInt(9007199254740991); // 超过number最大值
// 类型检查(TypeScript特有)
const num: number = 10;
// big + num; // 报错(不允许bigint与number直接运算)
const sum = big + BigInt(num); // 需显式转换
// symbol使用
const sym1: symbol = Symbol("key");
const sym2: symbol = Symbol("key");
console.log(sym1 === sym2); // false(唯一)
// unique symbol(TypeScript特有)
const uniqueSym: unique symbol = Symbol("unique");
type UniqueSymType = typeof uniqueSym; // 仅表示该唯一符号