流程通用约束
在Flow中,在某些情况下你会想要创建一个通用函数或类,但想要限制可以作为类型参数传递的内容。
通用约束的用途
假设您有一个包装 Map 的类,但在插入之前进行了浅拷贝:
class ShallowMap<T> {
map: Map<string, T>;
constructor() {
this.map = new Map();
}
get(key: string) {
return this.map.get(key);
}
set(key: string, value: T) {
// Make a shallow copy. Flow will give an error on this line.
const copy = {...value};
this.map.set(key, copy);
}
}
Flow 不允许您这样做,因为虽然对象可以传播,但其他类型不能:
// This works.
const spreadEmptyObject = {...Object.create(null)};
const spreadObjectWithProperty = {...{id: 2}};
// This doesn't.
const spreadNumber = {...0};
const spreadString = {...''};
没有什么可以说T
必须是对象。
添加表示“T”的东西必须是一个对象
这很简单;只需在泛型类型声明后添加冒号和约束类型:
// `T` has to be an object.
class ShallowMap<T: Object> {
map: Map<string, T>;
constructor() {
this.map = new Map();
}
get(key: string) {
return this.map.get(key);
}
set(key: string, value: T) {
// Flow is okay with this line now.
const copy = {...value};
this.map.set(key, copy);
}
}
更具体的约束
约束可以更具体,允许与泛型类型进行更复杂的交互,因为它们符合某些条件。例如,使用属性来T
确定键的泛型映射:
type Keyable = {
key: string,
};
// `T` has a string property called `key`.
class AutoKeyMap<T: {key: string}> {
map: Map<string, T>;
constructor() {
this.map = new Map();
}
get(key: string) {
return this.map.get(key);
}
set(value: T) {
// Since `T` has a string property `key`, we can access it.
const key = value.key;
this.map.set(key, value);
}
}