是否可以在TypeScript中精确键入_.invert? [英] Is it possible to precisely type _.invert in TypeScript?
问题描述
在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键入当前声明它总是返回string
→string
映射:
The lodash typings currently declare this to always return a string
→string
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
首先创建一个包含所有key
,value
对的联合(因此在您的示例中为{ 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屋!