请原谅我的标题有点长。
给定以下类型
type A = {
foo: string;
bar: number;
baz: boolean;
}
我喜欢创建一个新的“部分”类型B
type B = Partial<A>
这样B必须包含A的至少一个属性,并且只允许A的属性
//compiles
const b1 = {
foo: "yeah"
}
//errors
const b2 = {}
const b3 = {lala: "lala"}
const b4 = {foo: "foo is alowed", but_not_this: false}
###
type A = {
foo: string;
bar: number;
baz: boolean;
type AtLeastOne<Obj Keys = keyof Obj>= Keys扩展Obj ?Pick< Obj Keys>:永远不要
type NonEmpty<T> = Partial<T> & AtLeastOne<T>
type Result = NonEmpty<A>
/ /编译
const b1: Result = {
foo: "yeah"
/ /错误
const b2: Result = {}
const b3: Result = { lala: "lala" }
const b4: Result = { foo: "foo is alowed", but_not_this: false }
操场上
解释
部分 & Pick | Pick | Pick这是你应该结束的最小要求类型。
首先,我们需要确保该对象不是空的。它应该有三种道具之一。
考虑distributive-conditional-types
type AtLeastOne<Obj, Keys = keyof Obj> = Keys extends keyof Obj ? Pick<Obj, Keys> : never
根据文档Pick<Obj Keys>-将被应用到每个键。因此AtLeastOne返回Pick | Pick | Pick。
现在你需要的最简单的部分就是使用交集来合并AtLeastOne和Partial的返回类型
type NonEmpty<T> = Partial<T> & AtLeastOne<T>
你可以在我的typescript博客中找到更多有趣的例子