我有一个类型:
type first = {
one: number;
two: string;
three: {
four: string,
five: number,
}
}
它适用于我在应用程序的一部分中声明的变量的一个实例,但不适用于变量的另一个(第二个)实例。
适合于变量第二个实例的类型如下:
type second = {
one: number;
two: string;
three: {
four: string,
five: number[], //difference
}
}
我不想从头开始声明一种新类型,而希望通过替换属性first
的类型来吸收现有类型three
。
我试图这样做:
type second = Pick<first, Exclude<keyof first, 'three'>> & {
three: {
four: string,
five: number[], //difference
}
}
但是它给了我一个错误,我在悬停时得到了这个类型定义:
type second = {
one: number;
two: string;
three: {
four: string,
five: number,
};
three: {
four: string,
five: number,
};
}
注意2个属性three
。
我在做什么错了?
答案 0 :(得分:1)
您的解决方案应该起作用,我只有两个发现:
您可以在类型查询中向下一级使用相同的方法,而无需重写内部对象
注意交集类型,假设它们的行为与手工生成的类型完全相同并不总是正确的。参见this question。我们可以解决使用附加映射类型使类型变平的问题。
记住这些,这就是我要做的:
type first = {
one: number;
two: string;
three: {
four: string,
five: number,
}
}
type Identity<T> = { [P in keyof T]: T[P] }
type Replace<T, K extends keyof T, TReplace> = Identity<Pick<T, Exclude<keyof T, K>> & {
[P in K] : TReplace
}>
type second = Replace<first, 'three', Replace<first['three'], 'five', number[]>>
let d: second = {
one: 1,
two: "",
three : {
four: "",
five: [0]
}
}
答案 1 :(得分:0)
您可以尝试通过使用联合来替换类型定义的一部分。以下是过度简化:
type SecondType = FirstType & {
three: {
four: string,
five: number[],
}
};
上述解决方案会给您带来麻烦。一个简单的联合并没有真正取代属性“三”,它实际上为属性“三”和“五”创建了两个相互冲突的定义。每当您尝试访问它们时,您的 IDE 都会向您发出警告。
解决方案是删除该属性,然后将其重新合并:
type SecondType =
Omit<FirstType, 'three'> &
{ three: {
four: string,
five: number[]
}};