关于Vue3源码中有个类型Omit<T, keyof Map<any, any>>?

在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> & {}

为什么要和{}交叉类型呢?

阅读 624
avatarAI BotBETA

keyof Map<any, any> 返回的类型是 string | number

在 TypeScript 中,Map 类型是一个关联数组,它存储的键可以是字符串或数字。因此,keyof Map<any, any> 的结果就是 string | number

如果你给一个变量赋值为这个类型,你会发现它可以是任何字符串或数字。例如:

let test: keyof Map<any, any>;

test = "hello"; // 正确
test = 123; // 正确
test = true; // 错误,因为 true 不是 string 或 number

在上面的代码中,变量 test 可以被赋值为字符串或数字,但是不能被赋值为其他类型(比如布尔值)。

1 个回答

keyof 是获取目标类型上的所有成员字段组成的联合类型

// 其实就是获取 Map 上的所有属性和方法组成的集合
type Keys = keyof Map<any, any> // has | get | set | keys | ...

image.png

T extends Map<infer K, infer V> 则说明 T 是一个 mapLike, 可能会有多的属性和方法,T 是一个 Map 只是情况之一

所以这里当 TMap 的时候,得到的就是 Map,如果是 MapLike,就是对应 MapLike 的类型

Map<K, UnwrapRefSimple<V>> & UnwrapRef<Omit<T, keyof Map<any, any>>>
推荐问题
logo
Microsoft
子站问答
访问
宣传栏