我有这样一个接口:
export interface MutationSheetDefinition {
_type: "mutation.sheet.definition"
id: string
name: string
mutations: MutationDefinition[]
referencedMutationSheets: MutationSheetReference[]
}
,我想要这个类型:
interface ValidatedMutationSheetDefinition {
name: ValidationOf<string>
mutations: ValidationOf<MutationDefinition>[]
referencedMutationSheets: ValidationOf<MutationSheetReference>[]
}
我知道我可以选择一个子集的接口使用:
type narrowed = Pick<MutationSheetDefinition, "name"| "mutations" | "referencedMutationSheets">
将得到
interface {
name: string
mutations: MutationDefinition[]
referencedMutationSheets: MutationSheetReference[]
}
但是我可以改变所选键的类型吗?
我将满足于为所有选中的键设置一个固定的类型,所以这将是:
interface {
name: Validation
mutations: Validation[]
referencedMutationSheets: Validation[]
}
你可以这样做:
type PickAndChangeToValidationOf<T, P extends keyof T> = {
[K in P]: T[K] extends (infer I)[]
? ValidationOf<I>[]
: ValidationOf<T[K]>
}
我不确定你想如何处理数组。在您的示例中,您移除了[]
并将其放在ValidationOf<T>
后面。上面的类型也这样做,但只针对第一级数组。如果你想要双嵌套数组的不同行为,你应该这样指定。
用法:
interface MutationSheetDefinition {
_type: "mutation.sheet.definition"
id: string
name: string
mutations: number[]
referencedMutationSheets: number[]
}
type Narrowed = PickAndChangeToValidationOf<MutationSheetDefinition, "name"| "mutations" | "referencedMutationSheets">
// type Narrowed = {
// name: ValidationOf<string>;
// mutations: ValidationOf<number>[];
// referencedMutationSheets: ValidationOf<number>[];
// }
游乐场你是(我交换了您的自定义类型与随机字符串,只是删除它们):
type MutationDefinition = "MutationDefinition";
type MutationSheetReference = "MutationSheetReference";
export interface MutationSheetDefinition {
_type: "mutation.sheet.definition"
id: string
name: string
mutations: MutationDefinition[]
referencedMutationSheets: MutationSheetReference[]
}
type Narrowed = Pick<MutationSheetDefinition, "name"| "mutations" | "referencedMutationSheets">;
type Validation = "Validation";
type Validational<Type> = {
[Property in keyof Type]: Type[Property] extends unknown[] ? Validation[] : Validation;
};
type Definition = Validational<Narrowed>;
const d: Definition = {
name: "Validation",
mutations: ["Validation", "Validation"],
referencedMutationSheets: ["Validation", "Validation"],
}
这个解决方案的一个缺点是,它的类型只硬编码为数组和所有其他类型。如果您使用其他类型,则必须添加更多类型,例如需要添加数组的数组。