我有这些界面
interface CommonAnimalProps {
common: {
size: number,
weight: number,
origin: string,
}
}
interface DogProps extends CommonAnimalProps {
name: string
}
interface CatProps extends CommonAnimalProps {
furious: boolean
}
interface BirdProps extends CommonAnimalProps {
canFly: boolean
}
export enum AnimalType {
dog = "dog",
cat = "cat",
bird = "bird",
}
export interface AnimalTypeToAnimalPropsMap {
[AnimalType.dog]: (DogProps)[],
[AnimalType.cat]: (CatProps)[],
[AnimalType.bird]: (BirdProps)[]
}
export type AllAnimalValues<T> = T[keyof T]
export type AllAnimalTypesArray = AllAnimalValues<AnimalTypeToAnimalPropsMap>
export type AllAnimalTypes = AllAnimalValues<AnimalTypeToAnimalPropsMap>[0]
export type AllAnimalTypesArrayDiscriminating = AllAnimalTypes[]
这AllAnimalTypesArrayDiscriminating
将导致数组看起来像这样
const foo: AllAnimalTypesArrayDiscriminating = [
{
name: "Bello",
common: {
size: 10,
weight: 25,
origin: "Knowhwere"
},
},
{
furious: true,
common: {
size: 3,
weight: 5,
origin: "Anywhere"
},
},
{
canFly: false,
common: {
size: 39,
weight: 50,
origin: "Somewhere"
},
},
]
是否可以使用AllAnimalTypesArrayDiscriminating
并从中创建一个新的类型/接口(AllAnimalTypesArrayDiscriminatingModified
),其中结果数组中的每个元素bar
都有另一个 prop(color: string
)添加,CommonAnimalProps
以便结果如下所示
const bar: AllAnimalTypesArrayDiscriminatingModified = [
{
name: "Bello",
common: {
size: 10,
weight: 25,
origin: "Knowhwere",
color: 'red',
},
},
{
furious: true,
common: {
size: 3,
weight: 5,
origin: "Anywhere",
color: 'brown',
}
}, {
canFly: false,
common: {
size: 39,
weight: 50,
origin: "Somewhere",
color: 'white',
},
}
];
请注意,我无法修改原始内容CommonAnimalProps
以将其添加color
为可选参数。我也无法编辑DogProps, CatProps, BirdProps
。我正在寻找一种使用AllAnimalTypesArrayDiscriminating
(或任何其他我未排除的类型)来添加此属性的方法。有办法做到这一点吗?
迄今为止最简单的方法就是使用交集将适当嵌套的成员添加到
AllAnimalTypes
:这会在示例中为您提供所需的行为:
但请注意,这实际上并没有将该成员放入
AllAnimalTypes
union的每个成员中。它所做的只是说明,除了是一个AllAnimalTypes
值之外,它还应该string
在其common
属性处具有 -valued 属性。因此,虽然例如
DogProps & { common: { color: string } }
或多或少等同于{name: string, common: { size: number, weight: number, origin: string, color: string } }
,但它并不是以那种方式表示的,并且根据您执行的操作类型,这种差异可能会很明显。如果您确实想计算该类型,以便生成的联合中的每个成员都具有一个嵌套属性,该属性与其他公共属性直接位于同一对象类型中,则需要进行更多类型调整。以下是其中一种方法:
AddCommonColor
实用程序类型在哪里这是一个分配条件类型。该类型
T extends unknown ? ⋯T⋯ : never
看起来像是无操作,因为所有类型都T
扩展了unknown
,但此类型的重点不是执行检查,而是将部分分配⋯T⋯
给中的联合T
。也就是说,我们希望AddCommonColor<X | Y | Z>
评估为AddCommonColor<X> | AddCommonColor<Y> | AddCommonColor<Z>
。我们为给定联合成员计算的实际类型是
{ [K in keyof T]: K extends "common" ? T[K] & { color: string } : T[K] }
,这是一种映射类型common
,除了与之相交的之外,所有属性均保持不变{color: string}
。如果我们现在检查,
AllAnimalTypesModified
我们得到财产
color
位于common
每个工会成员的财产中。即使这也不是您想要看到的方式;可以像这样摆脱这种交集:产生
但这对于您的用例来说可能有些过度了。
游乐场链接到代码