是否可以在TypeScript中精确键入_.invert? [英] Is it possible to precisely type _.invert in TypeScript?

查看:91
本文介绍了是否可以在TypeScript中精确键入_.invert?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在lodash中, _.invert 函数会反转对象的键和值:

In lodash, the _.invert function inverts an object's keys and values:

var object = { 'a': 'x', 'b': 'y', 'c': 'z' };

_.invert(object);
// => { 'x': 'a', 'y': 'b', 'z': 'c' }

lodash键入当前声明它总是返回stringstring映射:

The lodash typings currently declare this to always return a stringstring mapping:

_.invert(object);  // type is _.Dictionary<string>

但是有时候,尤其是如果您使用的是

But sometimes, especially if you're using a const assertion, a more precise type would be appropriate:

const o = {
  a: 'x',
  b: 'y',
} as const;  // type is { readonly a: "x"; readonly b: "y"; }
_.invert(o);  // type is _.Dictionary<string>
              // but would ideally be { readonly x: "a", readonly y: "b" }

是否可以精确地输入?该声明接近:

Is it possible to get the typings this precise? This declaration gets close:

declare function invert<
  K extends string | number | symbol,
  V extends string | number | symbol,
>(obj: Record<K, V>): {[k in V]: K};

invert(o);  // type is { x: "a" | "b"; y: "a" | "b"; }

键是正确的,但是值是输入键的并集,即您失去了映射的特异性.有可能做到这一点吗?

The keys are right, but the values are the union of the input keys, i.e. you lose the specificity of the mapping. Is it possible to get this perfect?

推荐答案

您可以使用保留了正确值的更复杂的映射类型来做到这一点:

You can do it using a more complicated mapped type that preserves the correct value:

const o = {
    a: 'x',
    b: 'y',
} as const;

type AllValues<T extends Record<PropertyKey, PropertyKey>> = {
    [P in keyof T]: { key: P, value: T[P] }
}[keyof T]
type InvertResult<T extends Record<PropertyKey, PropertyKey>> = {
    [P in AllValues<T>['value']]: Extract<AllValues<T>, { value: P }>['key']
}
declare function invert<
    T extends Record<PropertyKey, PropertyKey>
>(obj: T): InvertResult<T>;

let s = invert(o);  // type is { x: "a"; y: "b"; }

AllValues首先创建一个包含所有keyvalue对的联合(因此在您的示例中为{ key: "a"; value: "x"; } | { key: "b"; value: "y"; }).然后,在映射类型中,我们映射联合中的所有value类型,对于每个value,我们使用Extract提取原始key.只要没有重复的值(如果有重复的值,我们将在出现值的地方获得键的并集)将很好地工作

AllValues first creates a union that contains all key, value pairs (so for your example this will be { key: "a"; value: "x"; } | { key: "b"; value: "y"; }). In the mapped type we then map over all value types in the union and for each value we extract the original key using Extract. This will work well as long as there are no duplicate values (if there are duplicate values we will get a union of the keys wehere the value appears)

这篇关于是否可以在TypeScript中精确键入_.invert?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆