Typescript 键值关系保留 Object.entries 类型 [英] Typescript Key-Value relation preserving Object.entries type

查看:43
本文介绍了Typescript 键值关系保留 Object.entries 类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

打字稿提供的 Object.entries 类型具有返回类型 [string, T][] 但我正在搜索通用类型 Entries<;O> 表示这个函数的返回值,保持键和值的关系.

The typing for Object.entries provided by typescript has the return type [string, T][] but I am searching for a generic type Entries<O> to represent the return value of this function that keeps the relationship between the keys and the values.

例如.当具有像

type Obj = {
    a: number,
    b: string,
    c: number
}

我正在寻找一种 Entries<O> 类型,当与 Obj 一起提供时,它会产生以下类型之一(或类似的东西):

I'm looking for a type Entries<O> that results in one of the types below (or something similar) when provided with Obj:

(["a", number] | ["b", string] | ["c", number])[]
[["a", number], ["b", string], ["c", number]]
(["a" | "c", number] | ["b", string])[]

<小时>

这并不适用于 Object.entries 的所有用例 (见这里) 对我的具体情况没有问题.


That this isn't correct for all use cases of Object.entries (see here) is no problem for my specific case.

尝试过但失败的解决方案:

type Entries= [keyof O, O[keyof O]][] 对此不起作用,因为它只保留可能的键和值,而不保留它们之间的关系,如 Entries["a" |"b" |"c", 数字 |字符串].

type Entries<O> = [keyof O, O[keyof O]][] doesn't work for this as it only preserves the possible keys and values but not the relationship between these as Entries<Obj> is ["a" | "b" | "c", number | string].

type Entry<O, K extends keyof O> = [K, O[K]]
type Entries<O> = Entry<O, keyof O>[]

这里 Entry 的定义按预期工作,例如.Entry["a", number] 但是在第二行应用keyof O因为第二个类型变量再次导致与第一次尝试相同的结果.

Here the definition of Entry works as expected eg. Entry<Obj, "a"> is ["a", number] but the application of it in the second line with keyof O as the second type variable leads again to the same result as the first try.

推荐答案

这里有一个解决方案,但是注意当使用它作为 Object.entries 的返回类型时;这样做并不总是安全的(见下文).

Here's a solution, but beware when using this as a return type for Object.entries; it is not always safe to do that (see below).

如果您想将每个键与依赖于该键类型的内容配对,请使用 映射类型:

When you want to pair each key with something dependent on that key's type, use a mapped type:

type Entries<T> = {
    [K in keyof T]: [K, T[K]];
}[keyof T][];

type Test = Entries<Obj>;
// (["a", number] | ["b", string] | ["c", number])[]

第二个版本,它有一个包含属性而不是联合的元组类型,更难构建;可以将联合转换为元组,但您基本上应该这样做不要这样做.

The second version, which has a tuple type containing the properties instead of a union, is much harder to construct; it is possible to convert a union to a tuple but you basically shouldn't do it.

第三个版本易于管理,但比第一个版本复杂一些:您需要来自 PickByValue这个答案.

The third version is manageable, but a bit more complicated than the first version: you need PickByValue from this answer.

type Entries3<T> = {
    [K in keyof T]: [keyof PickByValue<T, T[K]>, T[K]]
}[keyof T][];

type Test3 = Entries3<Obj>;
// (["a" | "c", number] | ["b", string])[]

游乐场链接

我想我还应该解释一下为什么 Typescript Object.entries 提供更强的类型.当你有一个像 type Obj = {a: number, b: string, c: number} 这样的类型时,它只能保证一个值具有这些属性;保证该值不具有其他属性.例如,值 {a: 1, b: 'foo', c: 2, d: false} 可分配给类型 Obj(对象的过度属性检查文字除外).

I guess I should also explain why Typescript doesn't give a stronger type to Object.entries. When you have a type like type Obj = {a: number, b: string, c: number}, it's only guaranteed that a value has those properties; it is not guaranteed that the value does not also have other properties. For example, the value {a: 1, b: 'foo', c: 2, d: false} is assignable to the type Obj (excess property checking for object literals aside).

在这种情况下,Object.entries 将返回一个包含元素 ['d', false] 的数组.Entries 类型表示这不可能发生,但实际上它可以发生;所以 Entries 通常不是 Object.entries 的声音返回类型.当您自己知道这些值不会有多余的属性时,您应该只对 Object.entries 使用上述解决方案;Typescript 不会为你检查这个.

In this case Object.entries would return an array containing the element ['d', false]. The type Entries<Obj> says this cannot happen, but in fact it can happen; so Entries<T> is not a sound return type for Object.entries in general. You should only use the above solution with Object.entries when you yourself know that the values will have no excess properties; Typescript won't check this for you.

这篇关于Typescript 键值关系保留 Object.entries 类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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