【问题标题】:Typescript: Type that requires at least one property [duplicate]打字稿:需要至少一个属性的类型[重复]
【发布时间】:2020-07-07 22:46:46
【问题描述】:

假设我有以下类型:

type SomeType = {
  propOne: any;
  propTwo: any;
  propThree: any;
}

propOne 是必需的,propTwopropThree 是可选的,但至少其中一个是必需的。如何定义具有该约束的类型?

// The following code is my expectation
let someVar1: SomeType = { propOne: 1, propTwo: "two" } //Okay
let someVar2: SomeType = { propOne: 1, propThree: "three" } //Okay
let someVar3: SomeType = { propOne: 1, propTwo: "two", propThree: "three" } //Okay
let someVar4: SomeType = { propOne: 1 } //Not Okay

【问题讨论】:

  • 你用的是哪个TS版本?因为在最新的 3.8 中只有第三种情况是正确的(没有 TS 错误)
  • @MarekSzkudelski 这是 OP 的预期结果。
  • 我会创建一个构造函数来强制执行这个“检查约束”,如果参数不符合预期会抛出异常。
  • @DaggeJ 依赖于这种类型作为一个类。但是,可以仅单独构造和使用它,而不涉及过程中的类。此外,构造函数将仅在构造时执行检查,如果实例被修改,则不会稍后。

标签: javascript typescript


【解决方案1】:

即使在编辑之后,您也可以使用相同的技巧:

type SomeType = {
  propOne: number;
  propTwo?: string;
  propThree?: string;
} & ({
  propTwo: string;
} | {
  propThree: string;
})

let someVar1: SomeType = { propOne: 1, propTwo: "two" } //Okay
let someVar2: SomeType = { propOne: 1, propThree: "three" } //Okay
let someVar3: SomeType = { propOne: 1, propTwo: "two", propThree: "three" } //Okay
let someVar4: SomeType = { propOne: 1 } //Not Okay

function f(s: SomeType) {
  let p1 = s.propOne; // number
  let p2 = s.propTwo; // string | undefined
  let p3 = s.propThree; // string | undefined
}

它强制您在声明时至少拥有一个属性,并且它允许您在使用该类型的对象时同时使用该类型的两个属性。

Playground

【讨论】:

  • 感谢您的快速响应,它解决了我的问题,但如果我有更复杂的类型,它会延长我的代码。
  • 您可能可以使用重复线程中的答案,例如:type SomeType = { propOne: any } & AtLeastOne<{ propTwo: any, propThree: any }>。然后你只声明一次你的属性
【解决方案2】:

这是 2 个对象的联合类型:

type SomeType = {
    propOne: any;
} | {
  propTwo: any;
}

Typescript 将要求对象的类型与此联合中的一种类型兼容。 Here is solution in playground

注意:如果您真的只有两个属性,这是最简单的解决方案。

【讨论】:

    猜你喜欢
    • 2021-08-02
    • 2021-03-02
    • 2022-01-17
    • 1970-01-01
    • 2020-06-20
    • 2017-11-18
    • 2011-07-21
    • 2015-01-14
    相关资源
    最近更新 更多