我正在从文件中读取数据,该文件中的数据可能比我的代码所关心的更多。我要处理的每个对象类型都有一个打字稿类型。但是对于某些不受支持的对象类型,我想对该对象做些事情。
问题在于打字稿认为我已经用尽了所有可能性,并且我的默认子句无法使用。
// Untyped example data source.
function loadFromSomeFile(): any {
return [{ objType: "A", a: 1 }, { objType: "B", b: 2 }] as any
}
// Union type of supported data from data source.
type A = { objType: "A", a: number }
type B = { objType: "B", b: number }
type ObjTypes = A | B
// Load the data.
const arr: ObjTypes[] = loadFromSomeFile()
// Switch on the type of each object.
for (const obj of arr) {
switch (obj.objType) {
case "A":
console.log('A', obj.a)
break
case "B":
console.log('B', obj.b)
break
default:
// Fall though case for unsupported objType
console.log('unkown objType: ' + obj.objType)
// ^ TS Error: objType does not exist on type 'never'
}
}
Error on Typescript Playground
我想尝试向工会添加第三个选项,例如:
type X = { objType: string } // unknown
type ObjTypes = A | B | X
但是现在obj.objType === 'A'
打字稿不能分辨是A
还是X
,因为它是两者的有效类型。
如何告诉打字稿可能还有未知的和未处理的值,并且我的清单并不完整?
答案 0 :(得分:1)
经过一段时间的努力,我决定为未知类型提供一个具有固定值的具体类型,这是不正确的。
type A = { objType: "A", a: number }
type B = { objType: "B", b: number }
type Unknown = { objType: '___unknown-obj-type___' }
type ObjTypes = A | B | Unknown
这将导致交换机的默认子句落入此类型。而且我仍然可以在运行时访问对象属性以获得真实值。
感觉有点像黑客入侵,但是到目前为止,这对代码可读性的影响最小,恕我直言。
答案 1 :(得分:0)
使用:
return [
{ objType: "A", a: 1 },
{ objType: "B", b: 2 },
{ objType: "C" }
{ foo: "bar" }
] as any
作为数据,并将类型设置为:
type ObjTypes = A | B | any
然后,在每个case
块中,将对象转换为预期的类型,即A
或B
等。
case "A":
let a = <A>obj;
console.log('A', a.a)
//console.log('A', a.x) // TS error!
break
登录到控制台:
A 1
B 2
unknown objType: C
unknown objType: undefined
查看更新后的Typescript Playground
答案 2 :(得分:0)
由于不仅可以从文件中获取A或B,所以不要将类型声明为A |B。 B。
请参见Playground