由typescript提供的Object.entries
的类型具有返回类型[string, T][]
,但我正在寻找一种通用类型Entries<O>
来表示该函数的返回值,该值保持函数之间的关系。键和值。
例如。当对象类型为
时type Obj = {
a: number,
b: string,
c: number
}
我正在寻找一种类型为Entries<O>
的类型,该类型在提供Obj
时会导致以下一种类型(或类似的类型):
(["a", number] | ["b", string] | ["c", number])[]
[["a", number], ["b", string], ["c", number]]
(["a" | "c", number] | ["b", string])[]
对于所有Object.entries(see here)用例来说,这都不是正确的,这对我的具体情况来说不是问题。
尝试并失败的解决方案:
type Entries<O> = [keyof O, O[keyof O]][]
对此不起作用,因为它仅保留可能的键和值,而不会保留它们之间的关系,因为Entries<Obj>
是["a" | "b" | "c", number | string]
。
type Entry<O, K extends keyof O> = [K, O[K]]
type Entries<O> = Entry<O, keyof O>[]
此处Entry
的定义符合预期,例如Entry<Obj, "a">
是["a", number]
,但在第二行中以keyof O
作为第二类型变量的应用会再次产生与第一次尝试相同的结果。
答案 0 :(得分:8)
当您想将每个按键与取决于该按键类型的某些东西配对时,请使用mapped type:
type Entries<T> = {
[K in keyof T]: [K, T[K]];
}[keyof T][];
type Test = Entries<Obj>;
// (["a", number] | ["b", string] | ["c", number])[]
第二个版本具有包含属性而不是并集的元组类型,很难构建。 it is possible to convert a union to a tuple,但您基本上不应该这样做。
第三个版本是可管理的,但比第一个版本复杂一些:您需要this answer中的PickByValue
。
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])[]
答案 1 :(得分:2)
我们可以使专用功能如下:
depictObjectKeyType<O>(o: O) {
return Object.keys(o) as (keyof O)[];
}
depictEntriesKeyType<T>(obj: T): Entries<T> {
return Object.entries(obj) as any;
}
并用作:
this.depictEntriesKeyType(data).forEach(....