在vue3的源码里有这么一个类型
type UnwrapRefSimple<T> = T extends Function | BaseTypes | Ref | RefUnwrapBailTypes[keyof RefUnwrapBailTypes] | {
[RawSymbol]?: true;
}
? T
: T extends Map<infer K, infer V>
? Map<K, UnwrapRefSimple<V>> & UnwrapRef<Omit<T, keyof Map<any, any>>>
: T extends WeakMap<infer K, infer V>
? WeakMap<K, UnwrapRefSimple<V>> & UnwrapRef<Omit<T, keyof WeakMap<any, any>>>
: T extends Set<infer V> ? Set<UnwrapRefSimple<V>> & UnwrapRef<Omit<T, keyof Set<any>>> : T extends WeakSet<infer V> ? WeakSet<UnwrapRefSimple<V>> & UnwrapRef<Omit<T, keyof WeakSet<any>>> : T extends ReadonlyArray<any> ? {
[K in keyof T]: UnwrapRefSimple<T[K]>;
} : T extends object & {
[ShallowReactiveMarker]?: never;
} ? {
[P in keyof T]: P extends symbol ? T[P] : UnwrapRef<T[P]>;
} : T;
这里当UnwrapRefSimple<Map<string, string>>
时,会有一步是Omit<T, keyof Map<any, any>>
,也就是
Omit<Map<string, string>, keyof Map<any, any>>
这一步得到的结果不是{}吗?
也就是当UnwrapRefSimple<Map<string, string>>
最终得到的类型是
Map<string, string> & Omit<Map<string, string>, keyof Map<any, any>>
即Map<string, string> & {}
为什么要和{}交叉类型呢?
keyof
是获取目标类型上的所有成员字段
组成的联合类型
T extends Map<infer K, infer V>
则说明T
是一个mapLike
, 可能会有多的属性和方法,T 是一个 Map 只是情况之一所以这里当
T
是Map
的时候,得到的就是Map
,如果是MapLike
,就是对应MapLike
的类型