Partial <t>,它将T中的一个字段保留为TypeScript中的requiered

时间:2018-02-27 12:36:04

标签: typescript

假设我们有界面

interface Thing {
  uuid: string;
  edges: number;
  corners: number;
}

并且您希望实现一种类型,其中除了uuid之外的所有类型都作为可选属性保留。将变更集传递给Thing时,这样的类型会非常有用,其中所有内容都由哈希映射中的uuid映射。

Partial<Thing>使Thing可选的所有字段都不是我们想要的,我们希望uuid仍然是强制性的。

如何使用尽可能少的代码重复来实现这样的类型?

2 个答案:

答案 0 :(得分:2)

您可以使用PartialPick来达到预期效果:

type PartialRequired<T, TRequired extends keyof T> = Partial<T> & Pick<T, TRequired>

type PartialThing = PartialRequired<Thing, 'uuid'>

let pp: PartialThing = {
    uuid: ""
}

以上版本有轻微的不便,uuid的类型string | (undefined & string)会按预期工作,但看起来很糟糕,我们可以使用Omit类型来获得更友好的类型:

type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];  
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>; 
type PartialRequired<T, TRequired extends keyof T> = Partial<Omit<T, TRequired>> & Pick<T, TRequired>

用法相同。

对于任一版本,您都可以指定更多必填字段:

type PartialThingWithEdges = PartialRequired<Thing, 'uuid' | 'edges'>

答案 1 :(得分:1)

可以通过扩展界面的偏导数来实现我之后的事情。

interface PartialThing extends Partial<Thing> {
  uuid: string;
}

然后强制PartialThing拥有uuid,但剩余的两个字段将保留为可选字段。