面试题答案
一键面试使用 type
进行类型定义
// 定义基础类型
type Name = string;
type Age = number;
// 定义复杂属性类型
type Address = {
street: string;
city: string;
zip: number;
};
// 定义对象类型
type Person = {
name: Name;
age: Age;
address: Address;
hobbies: string[];
};
// 定义嵌套的对象数组类型
type PeopleArray = Person[];
type
可以用于定义别名,它能给已有类型起一个新名字,如 Name
和 Age
,也能定义联合类型、交叉类型等复杂类型。在这个例子中,我们通过 type
定义了基础类型、复杂属性类型、对象类型以及嵌套对象数组类型。
使用 interface
进行类型定义
// 定义基础类型(这里只是为了对比,实际基础类型很少用interface)
interface NameInterface {
value: string;
}
interface AgeInterface {
value: number;
}
// 定义复杂属性类型
interface AddressInterface {
street: string;
city: string;
zip: number;
}
// 定义对象类型
interface PersonInterface {
name: string;
age: number;
address: AddressInterface;
hobbies: string[];
}
// 定义嵌套的对象数组类型
interface PeopleArrayInterface {
[index: number]: PersonInterface;
}
interface
主要用于定义对象的形状,它有很好的可扩展性,可以通过接口继承来扩展已有接口。例如:
interface EmployeeInterface extends PersonInterface {
employeeId: number;
department: string;
}
利用特性完成类型体操
type
的特性利用:- 联合类型和交叉类型:如果对象属性可能是多种类型之一,可以使用联合类型,如
type MaybeNumberOrString = number | string;
。交叉类型可以用于合并多个类型的属性,如type MergedType = { a: string } & { b: number };
。在嵌套对象数组中,如果某个属性可能是不同类型对象中的属性,可以用联合类型来灵活推导。 - 条件类型:可以使用条件类型进行类型的判断和选择,例如
type IsString<T> = T extends string? true : false;
。在处理嵌套对象数组时,如果根据某个属性值来决定其他属性的类型,可以使用条件类型来实现。
- 联合类型和交叉类型:如果对象属性可能是多种类型之一,可以使用联合类型,如
interface
的特性利用:- 接口继承:通过接口继承可以很方便地复用已有接口的属性,并添加新的属性。如上面的
EmployeeInterface
继承自PersonInterface
,在处理复杂类型系统时,对于具有层次关系的对象类型,接口继承可以很好地进行类型约束和推导。 - 索引签名:如
interface PeopleArrayInterface { [index: number]: PersonInterface; }
,可以定义对象数组的类型,在处理嵌套对象数组时,通过索引签名可以灵活定义数组元素的类型,同时也可以用于定义对象中属性名不确定但属性类型确定的情况。
- 接口继承:通过接口继承可以很方便地复用已有接口的属性,并添加新的属性。如上面的