如果属性updatedAt
存在,我需要一个需要属性updatedBy
的接口或类型(反之亦然);但是,它应该允许不设置任何属性。
interface BaseRow {
id: string
createdAt: string
createdBy: string
}
interface Updated {
updatedAt: string
updatedBy: string
}
interface UpdatedRow extends BaseRow, Updated {}
type Row = BaseRow | UpdatedRow
基于以上所述,我希望以下内容会导致typescript编译器抛出错误,因为updatedAt
存在但updatedBy
不存在。
const x: Row = {
id: 'someID',
createdAt: 'someISO',
createdBy: 'someID',
updatedAt: 'someISO'
}
然而,上述内容并未引发任何错误。
为什么上述解决方案不能按预期工作?实现有条件地需要两个或更多属性的interface
或type
的最佳方法是什么?
答案 0 :(得分:2)
根据对对象literals实施严格检查的PR,执行的检查是:
...对象文字指定目标类型中不存在的属性
是错误的
虽然属性位于union类型的不同分支上,但属性存在于union类型上。由于其他更新的属性不存在,因此对象文字不符合UpdatedRow
接口,但它确实符合Row
接口,因此可以赋值给变量。这就是没有错误的原因。
在您的情况下可能适用或不适用的解决方案是通过在两个接口上添加键入不同字符串文字类型的字符串属性来确保更新的行与非更新的行不兼容:
interface BaseRow {
id: string
createdAt: string
createdBy: string
}
interface Updated {
type: 'u'
updatedAt: string
updatedBy: string
}
interface UpdatedRow extends BaseRow, Updated {}
type Row = (BaseRow & { type: 'n'}) | UpdatedRow
const x: Row = { // Error, no updatedBy
type: 'u',
id: 'someID',
createdAt: 'someISO',
createdBy: 'someID',
updatedAt: 'someISO'
}
const x2: Row = { // Error, with updatedAt is not assignable to (BaseRow & { type: 'n'})
type: 'n',
id: 'someID',
createdAt: 'someISO',
createdBy: 'someID',
updatedAt: 'someISO'
}