【问题标题】:Typescript: define types without a field打字稿:定义没有字段的类型
【发布时间】:2019-06-15 18:05:33
【问题描述】:

我正在处理一个遗留数据集,并且我正在尝试在 typescript 中对一些有意义的类型进行建模。在此示例中,假设我有来自员工课程的工作经验数据:

EMPLOY            | START    | END
'my first employ' | 20180901 | 20181001
'my last employ'  | 20180901 | null

如果ENDnull,则表示它是实际雇员。由于我有几个关于这个领域概念的业务规则,我想用类型来建模它。这是我的代码:

interface ActualExperience {
  actual: true,
  employ: string,
  start: Date,
  end: undefined // <-- no end! 
}

interface PreviousExperience {
  actual: false,
  employ: string,
  start: Date,
  end: Date     // <-- end has a value!
}

type Experience = ActualExperience | PreviousExperience

到目前为止一切顺利。然后我想使用我的类型:

// this is OK
const previous: PreviousExperience = {
  actual: false,
  employ: 'my first employ',
  start: new Date(),
  end: new Date()
}

// ERROR! 
const actual: ActualExperience = {
  actual: true,
  employ: 'my last employ',
  start: new Date()
}

Typescript 要求我明确定义 end: undefined 以便映射到 ActualEmploy

// this is OK now!
const actual: ActualExperience = {
  actual: true,
  employ: 'my last employ',
  start: new Date(),
  end: undefined
}

这对我来说非常不切实际,因为我必须明确地向记录添加一个未定义的值,只是为了让我的编译器满意。

我该如何设计这种类型的模型?

【问题讨论】:

    标签: typescript type-systems domain-modelling


    【解决方案1】:

    将你的界面声明为:

    interface ActualExperience {
      actual: true,
      employ: string,
      start: Date
    }
    

    如果在后面的代码调用actual.end,javascript会返回undefined,不需要像你的界面“ActualExperience”那样定义

    【讨论】:

    • 我接受你的回答,因为它是正确的,无论如何我意识到我的情况稍微复杂一些。我要为此提出一个新问题。无论如何谢谢;)
    【解决方案2】:

    有两种方法可以解决这个问题。

    首先,如果没有特别需要在您的end: undefined 中明确包含ActualExperience,您可以直接删除它。

    其次,根据您要执行的操作,使用附加界面可能更有意义:

    interface BaseExperience {
      actual: boolean,
      employ: string,
      start: Date,
      end?: Date
    }
    

    然后您可以指定您当前的接口实现BaseExperience

    interface ActualExperience extends BaseExperience {
      actual: true,
      employ: string,
      start: Date
    }
    
    interface PreviousExperience extends BaseExperience {
      actual: false,
      employ: string,
      start: Date,
      end: Date
    }
    

    最后,你可以直接使用你的BaseExperience

    const someExperience: BaseExperience = {
      actual: true,
      employ: 'my last employ',
      start: new Date()
    }
    

    并以您想要的方式使用您的ActualExperience

    const actual: ActualExperience = {
      actual: true,
      employ: 'my last employ',
      start: new Date()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-07
      • 2016-04-28
      • 2018-01-16
      • 2021-08-20
      • 1970-01-01
      • 2020-07-07
      • 2018-12-03
      • 2019-02-10
      相关资源
      最近更新 更多