说说你对泛型的理解
一、泛型是什么类型?怎么使用?
1、定义:
泛型程序设计是程序设计语言的一种风格或范式 , 定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性.
2、使用方式
●泛型通过<>的形式进行表述,可以声明:
//声明泛型函数
function returnItem<T>(para: T): T {
return para
}
//声明泛型接口
interface ReturnItemFn<T> {
(para: T): T
}
//声明泛型类
class Stack<T> {
private arr: T[] = []
public push(item: T) {
this.arr.push(item)
}
public pop() {
this.arr.pop()
}
}
二、说一下interface和type的区别
相同点:
1、都可以描述 '对象' 或者 '函数'
interface:
interface User {
name: string
age: number
}
interface SetUser {
(name: string, age: number): void;
}
type:
type User = {
name: string
age: number
};
type SetUser = (name: string, age: number)=> void;
2、都允许拓展(extends)
interface 和 type 都可以拓展,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 extends interface 。 虽然效果差不多,但是两者语法不同。
不同点:
1、type 可以而 interface 不行
-
type 可以声明基本类型,联合类型,元组
-
type 可以使用 typeof 获取实例的类型进行赋值
// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div
其它操作:
type StringOrNumber = string | number;
type Text = string | { text: string };
type NameLookup = Dictionary<string, Person>;
type Callback<T> = (data: T) => void;
type Pair<T> = [T, T];
type Coordinates = Pair<number>;
type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
2、interface 可以而 type 不行
-
interface 能够声明合并
interface User {
name: string
age: number
}
interface User {
sex: string
}
/*
User 接口为 {
name: string
age: number
sex: string
}
*/
一般来说,如果不清楚什么时候用interface/type,能用 interface 实现,就用 interface , 如果不能就用 type 。接口和类型别名的区别:
●接口定义了一个契约,描述了对象的形状(属性和方法),以便在多个地方共享。它可以被类、对象和函数实现。
●类型别名给一个类型起了一个新名字,便于在多处使用。它可以用于原始值、联合类型、交叉类型等。与接口不同,类型别名可以用于原始类型、联合类型、交叉类型等,而且还可以为任意类型指定名字。
三、如何约束泛型参数的类型范围?
可以使用泛型约束(extends关键字)来限制泛型参数的类型范围,确保泛型参数符合某种特定的条件。
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
loggingIdentity({length: 10, value: 3}); // 参数满足 Lengthwise 接口要求,可以正常调用
四、什么是泛型约束中的 keyof 关键字,举例说明其用法。
●keyof 是 TypeScript 中用来获取对象类型所有键(属性名)的操作符。
●可以使用 keyof 来定义泛型约束,限制泛型参数为某个对象的键。
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3 };
getProperty(x, "a"); // 正确
getProperty(x, "d"); // 错误:Argument of type '"d"' is not assignable to parameter of type '"a" | "b" | "c"'
(拓展):
五、ArkTS 中如何联合枚举类型的 Key?
enum str {
A,
B,
C
}
type strUnion = keyof typeof str; // 'A' | 'B' | 'C'