从 Typescript 界面中选择键并更改它们的类型

Pick keys from a Typescript interface and change their types

我有这个界面:

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

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

你可以这样做:

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>[];
// }

Playground