从Typescript接口中选择键并更改它们的类型



我有这样一个接口:

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"],
}

这个解决方案的一个缺点是,它的类型只硬编码为数组和所有其他类型。如果您使用其他类型,则必须添加更多类型,例如需要添加数组的数组。

最新更新