TS面试题
TypeScript(TS)提供了丰富的类型系统,涵盖基本类型、复合类型、特殊类型和高级类型
基本类型
1. 布尔类型(boolean
)
用于表示逻辑上的真或假,只有两个值:true
和 false
。
let isEnabled: boolean = false;
2. 数字类型(number
)
和 JavaScript 一样,TypeScript 里的所有数字都是浮点数,支持十进制、十六进制、二进制和八进制表示。
let decimal: number = 10;
let hex: number = 0xa;
let binary: number = 0b1010;
let octal: number = 0o12;
3. 字符串类型(string
)
用于表示文本数据,可以使用单引号('
)、双引号("
)或反引号(``)来定义。
let name: string = 'Alice';
let greeting: string = `Hello, ${name}!`;
复合类型
1. 数组类型
有两种定义方式,一种是在元素类型后面加上方括号,另一种是使用泛型数组类型。
// 方式一
let numbers1: number[] = [1, 2, 3];
// 方式二
let numbers2: Array<number> = [4, 5, 6];
2. 元组类型(tuple
)
允许表示一个已知元素数量和类型的数组,各元素的类型可以不同。
let person: [string, number] = ['Bob', 25];
3. 枚举类型(enum
)
为一组数值赋予更具描述性的名称,默认从 0 开始编号,也可手动指定。
enum Color {
Red = 1,
Green,
Blue
}
let myColor: Color = Color.Green;
特殊类型
1. 任意类型(any
)
当无法确定变量的具体类型时使用,可绕过类型检查,可赋值为任意类型的值。
let value: any = 'hello';
value = 123;
2. 空值类型(void
)
通常用于表示函数没有返回值,声明 void
类型的变量时,只能赋值为 undefined
或 null
(在非严格模式下)。
function showMessage(): void {
console.log('Message');
}
let result: void = undefined;
3. null
和 undefined
它们既是实际的值,也是 TypeScript 中的类型。在严格模式下,null
和 undefined
只能赋值给 any
以及它们自身对应的类型,undefined
还能赋值给 void
类型。
let u: undefined = undefined;
let n: null = null;
高级类型
1. 联合类型(Union Types
)
表示一个变量可以是几种类型之一,使用竖线(|
)分隔不同类型。
let id: number | string;
id = 1;
id = 'abc';
2. 交叉类型(Intersection Types
)
将多个类型合并为一个类型,新类型具备所有参与合并类型的特性,使用 &
符号。
interface Person {
name: string;
}
interface Employee {
employeeId: number;
}
type PersonEmployee = Person & Employee;
let emp: PersonEmployee = { name: 'John', employeeId: 123 };
3. 类型别名(Type Aliases
)
为类型创建一个新的名称,可用于基本类型、联合类型、交叉类型等,方便复用和提高代码可读性。
type Point = {
x: number;
y: number;
};
let myPoint: Point = { x: 1, y: 2 };
4. 字面量类型
将变量的取值限制为特定的字面量值,可与联合类型结合使用。
type Direction = 'up' | 'down' | 'left' | 'right';
let myDirection: Direction = 'up';
5. 类型断言(Type Assertion
)
手动告诉编译器某个变量的具体类型,有两种语法:尖括号语法和 as
语法。
let someValue: any = 'a string';
// 尖括号语法
let strLength1: number = (<string>someValue).length;
// as 语法
let strLength2: number = (someValue as string).length;
6. 映射类型
基于现有类型创建新类型,可对类型的属性进行修改,如变为可选、只读等。
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
let readonlyUser: ReadonlyUser = { name: 'Eve', age: 30 };
// readonlyUser.age = 31; // 错误,属性只读
7. 条件类型
根据条件选择不同的类型,语法为 T extends U ? X : Y
。
type IsString<T> = T extends string ? true : false;
type Result = IsString<'abc'>; // true
ts 泛型
TypeScript中的泛型是一种强大的工具,它允许开发者创建可复用的代码,提高代码的灵活性和可维护性。以下是关于泛型的介绍:
定义与作用
- 定义:泛型是指在定义函数、接口或类时,不预先指定具体的数据类型,而是在使用时再确定数据类型的一种特性。
- 作用:它能使代码更通用,可适应多种数据类型,避免为不同数据类型编写重复代码,增强了代码的可复用性、可维护性和可读性。
基本语法与示例
- 函数中的泛型:定义泛型函数时,在函数名后用尖括号
<>
声明类型参数,如function identity<T>(arg: T): T { return arg; }
,调用时可传入不同类型参数,如identity<string>("hello")
或identity<number>(123)
。 - 接口中的泛型:接口也可使用泛型来定义可适配多种类型的契约,如
interface GenericInterface<T> { value: T; method: (arg: T) => T; }
,实现该接口的类或对象需根据传入的具体类型来确定属性和方法的参数及返回值类型。 - 类中的泛型:类中使用泛型可让类在处理不同类型数据时更灵活,如
class GenericClass<T> { private value: T; constructor(arg: T) { this.value = arg; } getValue(): T { return this.value; } }
,创建类的实例时可指定具体类型,如let instance = new GenericClass<string>("value")
。
泛型约束
- 有时需对泛型的类型进行限制,这就是泛型约束。如
interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; }
,这里限定了泛型T
必须包含length
属性,保证在函数内部可安全使用length
属性。