我们有一个API响应,我们希望改进我们的类型,我将简化这个示例.假设API返回的内容如下所示,其中有一个值类型和一个关联值.
Note:遗憾的是,这是一个现有的API,我们只是试图使用它在当前形状中提供的东西.
{
meta: {
id: string;
name: string;
valueType: 'cat' | 'bird'
}
value: { paws: number } | { wings: number }
}
在此响应中,类型valueType
和value
之间实际上存在直接关系.因此,为了try 并改进对API响应的类型支持,我try 了如下内容.
type MetaType = {
id: string;
name: string;
};
type APIResponseType =
| {
meta: MetaType & {
valueType: 'cat';
};
value: { paws: number };
}
| {
meta: MetaType & {
valueType: 'bird';
};
value: { wings: number };
};
const sampleResponse: APIResponseType[] = [
{
meta: {
id: '123',
name: 'Garfield',
valueType: 'cat',
},
value: { paws: 4 },
},
{
meta: {
id: '123',
name: 'Woody',
valueType: 'bird',
},
value: { wings: 2 },
},
];
到目前为止,这种方法工作得很好,当静态输入数据时,类型确保了数据的正确形状.如果您try 在第一个对象中将valueType从cat
更改为bird
,则会导致类型错误.
现在,当我try 以动态方式与此数据交互并try 使用类型保护时,出现了问题.
sampleResponse.forEach((animal) => {
if (animal.meta.valueType === 'cat') {
console.log(animal.value.paws);
}
});
// TypeScript see's the type for value as this:
(property) value: { paws: number; } | { wings: number; }
因此,在这种情况下,尽管类型最初似乎可以工作,但它无法使用类型保护起到预期的作用,这仍然意味着我们需要进行强制转换.
那么,有没有办法通过另一种打字方法实现这一功能呢?