具有不同类型的映射类型属性名称

时间:2021-04-24 00:24:59

标签: typescript typescript-typings

想象一下这些树类型:

type A1 = { m1: boolean };
type A2 = { m2: number };
type B = { m1: string; m2: string };

我想创建一个新类型,它必须具有相同的属性名称,但可以是它自己的类型。例如,A1A2 的并集具有与 B 相同的属性名称,但类型不同,这很好。

预期示例:

type SafeRetype<T, Z extends T> = { 
    [K in keyof T]?: Z[K]; // This is where I need help
};

type C1 = SafeRetype<B, A1 | A2>; // Expect  { m1?: string; m2?: string };

预期的失败示例:

type D1 = { z: string };
type Err = SafeRetype<B, D1>; // Expect error because missing "z" does not exist in B (m1|m2)

我试图实现的目标是能够拥有描述属性结构的主要类型,然后确保其他类型仅(全部或部分)具有前一种类型的属性,并且具有自由度改变属性的类型。

Playground

2 个答案:

答案 0 :(得分:1)

在您的情况下,A1 | A2 不扩展 B

为了让它只接受具有相同键的对象,你可以定义第二个泛型应该是一个与第一个具有相同键和任何值的对象:

type SafeRetype<T, Z extends Record<keyof T, any>> = Partial<T>

type SafeRetype<T, Z extends { [key in keyof T]: any}> = Partial<T>

在这种情况下,尝试使用 D1 时会出现错误


另一种选择是

type SafeRetype<T, Z> = Z extends Record<keyof T, any> ? Partial<T> : never

type Err = SafeRetype<B, D1>;

它不会在第二行导致错误,但值将是 never 并且每当您尝试在其上分配任何内容时都会发生错误

答案 1 :(得分:0)

您的确切要求和用例是什么有点含糊不清。但听起来您只需要 A1A2 的交集的组合,但使用类型属性映射(加上可选参数)来覆盖类型@每个键。

type A1 = { m1: boolean };
type A2 = { m2: number };

type B = {
    [key in keyof (A1 & A2)]?: string;
}

TypeScript intellisense snippet

编辑:自然,这可以很容易地变成可重用的“通用”:

type A1 = { m1: boolean };
type A2 = { m2: number };

type B<T, N> = {
    [key in keyof T]?: N;
}

type C = B<A1 & A2, string>;
相关问题