首页 > 解决方案 > 打字稿泛型:来自接口子级的只读值

问题描述

鉴于此输入:

export type Test = {
    one: {
        a: string;
        b: string;
        c: string;
    };
    two: {
        a: string;
        b: string;
        d: string;
    };
}

我需要一个CombinedChildren<T>输出以下类型的泛型:

export type Combined = {
    a?: string;
    b?: string;
    c?: string;
    d?: string;
}

基本上,它采用 children 属性并将它们组合起来,即使它们并不存在于所有 children 中也包括它们

试过了

export type KeyOfTest = Partial<Test[keyof Test]>
export type MappedKeyOfTest = Partial<{
    [key in keyof Test[keyof Test]]: Test[keyof Test][key]
}>

但没有一个输出正是我想要的。

标签: typescriptgenerics

解决方案


我们可以将其分解为几个步骤。首先,我们通过 得到所有子类型的联合Test[keyof Test]。然后我们想要一个所有这种类型的联合,所以我们使用一种将联合类型转换为交集类型的实用程序类型(取自 @jcalz 的这个答案)。最后,我们应用Partial到结果类型。

export type Test = {
    one: {
        a: string;
        b: string;
        c: string;
    };
    two: {
        a: string;
        b: string;
        d: string;
    };
    three: {
      a: string;
      e: number;
    }
}

// union to intersection converter by @jcalz: https://stackoverflow.com/a/50375286/8580499
// Intersect<{ a: 1 } | { b: 2 }> = { a: 1 } & { b: 2 }
type Intersect<T> = (T extends any ? ((x: T) => 0) : never) extends ((x: infer R) => 0) ? R : never;

// Combined = { a?: string; b?: string; c?: string; d?: string; e?: number }
type Combined = Partial<Intersect<Test[keyof Test]>>;

游乐场链接


推荐阅读