【问题标题】:Ensure subset interface from interface / PickDeep<>?确保来自接口/ PickDeep<>的子接口?
【发布时间】:2019-06-25 10:00:13
【问题描述】:

我正在寻找一种给定接口的方法:

interface Person {
  age: number,
  name: string,
  hometown?: {
    city: string,
    zip: number
  }
}

type SubPerson = EnsureSubInterface<Person, {
  name: string
}>

这将是有效的:

const x: SubPerson {
  name: "Tom"
}

这将是无效的:

const x: SubPerson {
  age: 12
}

【问题讨论】:

  • @HereticMonkey 我不认为这是有帮助的,这仍然会允许我试图限制的 T 的任何部分。
  • 为什么你说PickDeep 不会正常挑选工作? Pick&lt;Person, 'name' &gt;?

标签: typescript


【解决方案1】:

如果您只想确保第二个类型参数是任何给定级别的原始参数的子集,您可以使用DeepPartial(来自here)作为对EnsureSubInterface的第二个参数的约束

type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends Array<infer U>
    ? Array<DeepPartial<U>>
    : T[P] extends ReadonlyArray<infer U>
        ? ReadonlyArray<DeepPartial<U>>
        : DeepPartial<T[P]>
};

type EnsureSubInterface<T, U extends DeepPartial<T>> = U

interface Person {
    age: number,
    name: string,
    hometown?: {
        city: string,
        zip: number
    }
}

type SubPerson = EnsureSubInterface<Person, {
    name: string,
    hometown: {
        city: string,
    }
}>


type NotSubPerson = EnsureSubInterface<Person, {
    name: string,
    hometown: {
        city: number, // error
    }
}>


type NotSubPerson = EnsureSubInterface<Person, {
    name: string,
    hometown: {
        City: string, // error
    }
}>

根据您的 tslint 配置,您可能想要这样:

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends (infer U)[]
  ? DeepPartial<U>[]
  : T[P] extends ReadonlyArray<infer U>
      ? ReadonlyArray<DeepPartial<U>>
      : DeepPartial<T[P]>
};

【讨论】:

    猜你喜欢
    • 2019-10-16
    • 2010-12-15
    • 2017-06-09
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多