如何获得TypeScriptMap类型的逆类型?

p4rjhz4m  于 2023-01-10  发布在  TypeScript
关注(0)|答案(3)|浏览(121)

我希望获得TypeScriptMap类型的"逆"(其属性严格为字符串,以便"可逆")。为了说明我所需的结果,我需要一个泛型type

type Inverse<M> = ...

能够将

type MappedType = {
  key1: 'value1'
  key2: 'value2'
};

变成

/**
 * {
 *   value1: 'key1';
 *   value2: 'key2';
 * }
 */
type MappedTypeInverse = Inverse<MappedType>

我已经试过几种方法了......但都没用:
一个三个三个一个
这有可能吗?任何帮助都将不胜感激!

ewm0tg9j

ewm0tg9j1#

下面是一个精简的替代方案(除了帕特里克·罗伯特的好解决方案之外):

type KeyFromVal<T, V> = {
  [K in keyof T]: V extends T[K] ? K : never
}[keyof T];

// we assume the type to be an object literal with string values
// , should also work with number or symbol
type Inverse<M extends Record<string, string>> = {
  [K in M[keyof M]]: KeyFromVal<M, K>
};

type MappedType = {
  key1: 'value1'
  key2: 'value2'
};

type MappedTypeInverse = Inverse<MappedType> // { value1: "key1"; value2: "key2"; }
lsmd5eda

lsmd5eda2#

下面是实现这一点的方法:它借用了this answer的一些“邪恶魔法”,在过程的中间步骤将并集转换为交集:

type MappedType = {
    key1: 'value1';
    key2: 'value2';
};

type Intermediate<R extends Record<string, string>> =
    R extends Record<infer K, string>
    ? { [P in K]: { [Q in R[P]]: P; }; }
    : never;

type UnionToIntersection<U> =
    (U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
    ? I
    : never;

type Inverse<R extends Record<string, string>> =
    Intermediate<R> extends Record<string, infer T>
    ? { [K in keyof UnionToIntersection<T>]: UnionToIntersection<T>[K]; }
    : never;

type InverseMappedType = Inverse<MappedType>;
// type InverseMappedType = {
//     value1: 'key1';
//     value2: 'key2';
// }

这种方法的另一个好处是,当输入记录包含重复的属性值时,它输出具有适当属性值never的Map类型:

type MappedType = {
    key1: 'value1';
    key2: 'value1' | 'value2';
};

type InverseMappedType = Inverse<MappedType>;
// type InverseMappedType = {
//     value1: never;
//     value2: 'key2';
// }

比我更精通TypeScript的人可能知道一个比这个更短的方法来反转Map的类型,但这似乎至少完成了工作。

s4n0splo

s4n0splo3#

可以将Map类型与as运算符一起使用。
参见操场示例。

type Inverse<T> = {[K in keyof T as (T[K] & (string | number))]: K};

相关问题