假设我们有界面
interface Thing {
uuid: string;
edges: number;
corners: number;
}
并且您希望实现一种类型,其中除了uuid之外的所有类型都作为可选属性保留。将变更集传递给Thing
时,这样的类型会非常有用,其中所有内容都由哈希映射中的uuid
映射。
Partial<Thing>
使Thing
可选的所有字段都不是我们想要的,我们希望uuid
仍然是强制性的。
如何使用尽可能少的代码重复来实现这样的类型?
答案 0 :(得分:2)
您可以使用Partial
和Pick
来达到预期效果:
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
,但剩余的两个字段将保留为可选字段。