Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 如何从并集/交集对象类型的值生成类型?_Typescript_Ramda.js - Fatal编程技术网

Typescript 如何从并集/交集对象类型的值生成类型?

Typescript 如何从并集/交集对象类型的值生成类型?,typescript,ramda.js,Typescript,Ramda.js,我遇到了一个困难的类型,它想知道如何将一个类型定义为预定义对象类型中所有可能值的并集 假设我们有一个自动生成的类型Person,如下所示: type Person={ 收藏夹颜色:字符串 年龄:数目 女:布尔 } 如何使用Person类型创建等于string | number | boolean的联合类型 在我的用例中,类型Person是自动生成的。我在对象上使用Ramda函数,将函数应用于每个对象的值: 从'ramda'导入{map} 教室.people.forEach(person=> /

我遇到了一个困难的类型,它想知道如何将一个类型定义为预定义对象类型中所有可能值的并集

假设我们有一个自动生成的类型
Person
,如下所示:

type Person={
收藏夹颜色:字符串
年龄:数目
女:布尔
}
如何使用
Person
类型创建等于
string | number | boolean
的联合类型

在我的用例中,类型
Person
是自动生成的。我在对象上使用Ramda函数,将函数应用于每个对象的值:

从'ramda'导入{map}
教室.people.forEach(person=>
//Ramda的“map”应用于此处的“block”对象:
映射(属性=>{
//Ramda的类型定义不足以推断类型
//,因此需要手动对其进行注释。
返回函数(属性)
},人)
)
我正在寻找的行为本质上等同于
keyof
——但据我所知,TypeScript中没有
valueof
。等效的实现是什么样子的

多谢各位


编辑:通常情况下,解决方案是@kaya3:
type ValueOf=T[keyof T]
建议的。然而,仔细检查后,我的情况似乎受到以下问题的困扰:

type PersonCommonFields = {
  age: number,
  name: string
}
type PersonFragment =
  | { favouriteColor: string }
  | { female: boolean }
  | { eyeColor: Color }
  | { born: Date }
type Person = PersonCommonFields & PersonFragment
在这种情况下,上面定义的
ValueOf
返回
number | string
,即只返回
PersonCommonFields
中的值,忽略
PersonFragment
。本例的预期结果是
number | string | boolean | Color | Date

有没有其他办法来解决这种情况


很多(很多!)提前感谢

我注意到,如果您将
PersonFragment
中的
|
更改为
&
,它就会工作(换句话说,创建一个单一类型而不是联合类型)。似乎您希望这些字段是可选的,是否可以对单个类型使用
Partial
(与仅使每个字段可选相同的行为)


1:

受@Wex答案的启发,我找到了一个解决办法,虽然不完美,但目前已经足够了

graphql codegen
生成以下类型:

type PersonCommonFields = {
  age: number,
  name: string
}
type A = { favoriteColor: string }
type B = { female: boolean }
type C = { eyeColor: Color }
type D = { born: Date }
type PersonFragment = A | B | C | D
由此我创建了代码中使用的
type Person=PersonCommonFields&PersonFragment
。理想情况下,只有最后一种类型(
Person
)可以用来提出解决方案,因为随着GraphQL模式的发展,随着时间的推移,它不需要随着
PersonFragment
的发展而保持最新,并在其联合中包含更多的类型(
E
F
G
等)

但通过重新安排,我们可以做到:

type PersonFields =
  | Person[keyof PersonCommonFields]
  | A[keyof A]
  | B[keyof B]
  | C[keyof C]
  | D[keyof D]
这将创建所需的类型
number | string | favoriteColor | boolean | Color | Date

ValueOf=T[keyof T]
类型无法按您希望的方式为联合类型工作,因为
keyof
不会分布在联合上。例如,
keyof({foo:1}{bar:2})
的类型是
never
而不是
'foo'|'bar'

相反,我们可以使用a,它确实分布在工会上(顾名思义)

类型ValueOfUnion=T扩展推断U?永远不会
型式试验=数值单位
//测试=字符串|数字|布尔值|颜色|日期

从这个问题--你可以做
type ValueOf=T[keyof T]。谢谢!这就是我使用的方法。然而,如果
T
本身是不同类型的并集,它似乎没有返回正确的类型-但我将进一步研究这是否确实是正确的答案如果
T
是并集时
value的类型存在问题,我建议编辑该问题以询问该情况。我相信,
ValueOf
解决了
T
Person
的问题。这看起来更好——仅仅是因为它是一个,你能为
a
B
写一些简单的例子,并说出你想要的结果吗?我想我有一个可行的解决方案,但最好在回答之前把问题弄清楚,以免我误解。结果证明我的想法并不直接有效,但我认为这应该是可能的。我会再仔细考虑一下。这不太一样,因为原始类型至少需要一个可选属性。我开始使用的类型是自动生成的(通过
graphql codegen
),所以我必须从给定的类型开始…哎呀,我在你的问题中忽略了这一点。这个答案可能会帮助其他人,但不幸的是,它似乎对你没有任何帮助。很抱歉。
type PersonCommonFields = {
  age: number,
  name: string
}
type A = { favoriteColor: string }
type B = { female: boolean }
type C = { eyeColor: Color }
type D = { born: Date }
type PersonFragment = A | B | C | D
type PersonFields =
  | Person[keyof PersonCommonFields]
  | A[keyof A]
  | B[keyof B]
  | C[keyof C]
  | D[keyof D]