基于Scott Wlaschin examples in F#, 我正在尝试使用Typescript设计功能域模型。
但是,为了为可选参数设置更严格定义的类型, 我注意到打字稿没有验证我预期的属性。
例如,对于这种类型:
type ObjectOne = {
propertyOfOneMustBeNumber: number
}
type ObjectTwo = {
propertyOfTwoMustBeNumber: number
}
type Options = ObjectOne | ObjectTwo
我有以下用例:
// valid
const test1: Options = {
propertyOfOneMustBeNumber: 1,
propertyOfTwoMustBeNumber: 2
}
// invalid:
// Object literal may only specify known properties,
// and 'unrecognized_property' does not exist in type 'Options'.
const test2: Options = {
propertyOfOneMustBeNumber: 1,
unrecognized_property: 'string'
}
// valid
const test3: Options = {
propertyOfOneMustBeNumber: 1,
propertyOfTwoMustBeNumber: 'string'
}
我理解为什么test2
变量出错了,
但为什么test3
变量没有错误,
即使propertyOfTwoMustBeNumber
是字符串而不是数字?
这在Flow类型系统中也有效。
答案 0 :(得分:1)
根据两种类型系统,test3
是ObjectOne
的有效子类型。
在任何一种类型系统中,您都可以使用区分属性:
type ObjectOne = {
kind: 'one';
propertyOfOneMustBeNumber: number
}
type ObjectTwo = {
kind: 'two';
propertyOfTwoMustBeNumber: number
}
type Options = ObjectOne | ObjectTwo
// error
const test2: Options = {
kind: 'one',
propertyOfOneMustBeNumber: 1,
unrecognized_property: 'string'
}
// error
const test3: Options = {
kind: 'two',
propertyOfOneMustBeNumber: 1,
propertyOfTwoMustBeNumber: 'string'
}
在flowtype中,您还可以使用Exact Type,它将阻止现有的任何类型的额外属性:
type ObjectOne = {|
propertyOfOneMustBeNumber: number
|}
在TypeScript中,您可以使用可选的never
属性从对应类型中排除属性:
type ObjectOne = {
propertyOfOneMustBeNumber: number;
propertyOfTwoMustBeNumber?: never;
}
type ObjectTwo = {
propertyOfOneMustBeNumber?: never;
propertyOfTwoMustBeNumber: number;
}