【问题标题】:Why do I lose whether or not a property is optional in this Mapped Type为什么我会丢失此映射类型中的属性是否可选
【发布时间】:2017-12-21 08:57:58
【问题描述】:

我有一个映射类型 Minus<A,B> 用于创建一个类型,该类型具有 A 上的所有属性,但 B 上的属性定义如下:

type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];

/**
 * Type T without any of the properties on U.
 */
export type Minus<T, U> = {[P in Diff<keyof T, keyof U>]: T[P]};

比如我有两个接口,A

interface A {
    thing1: string;
    thing2: number;
}

B

interface B {
    thing1: string;
}

那么Minus&lt;A, B&gt; 应该产生一个等价于

interface C {
    thing2: number;
}

在 A 上有可选类型之前,这很有效,因为这些在途中会丢失。

A 替换为

interface A {
    thing1: string;
    thing2?: number;
}

将产生一个看起来像的类型

interface C {
    thing2: number;
}

而不是想要的

interface C {
    thing2?: number;    
}

有趣的是,Readonly&lt;T&gt; 的行为似乎确实保留了属性是否是可选的; Readonly 将产生一个等价于

的类型
interface ReadonlyA {
    readonly thing1: string;
    readonly thing2?: number;
}

所以我怀疑这与我的 Diff 类型有关。

有没有人可以保留A 上的属性是否可选?

【问题讨论】:

标签: typescript typescript2.0 mapped-types


【解决方案1】:

解决方案是将Minus&lt;A, B&gt; 重新定义为

type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];

/**
 * Type T without any of the properties on U.
 */
export type Minus<T, U> = Pick<T, Diff<keyof T, keyof U>>;

这将正确地保留可选类型。

感谢Daniel Khoroshko 为我指出正确的方向

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    相关资源
    最近更新 更多