我正在编写一个 api 库,并且有一个界面,其中某些键可以根据请求期间显示的内容进行更改,即如果添加某些参数,键可以从
string
类型更改为 object
类型:
interface MyObject {
name: string;
email: string;
}
interface MyAddress {
street: string;
state: string;
country: string;
}
interface MyPerson {
id: string;
personalDetails: string | MyObject;
address: string | MyAddress;
}
假设用户调用
library.person.get()
,他们应该得到:
{
"id": "id_123456",
"personalDetails": "id_7890123",
"address": "id_4567890"
}
但是,如果他们打电话给
library.person.get({ expand: ['personalDetails', 'address'] })
他们应该得到:
{
"id": "id_123456",
"personalDetails": {
"name": "Joe",
"email": "[email protected]"
},
"address": {
"street": "fake st",
"state": "Fake",
"Country": "FK"
}
}
如果我尝试仅使用 Union 来执行此操作,当我获取
personalDetails.name
时,我会收到 "name" does not exist on type "string"
的错误。如果只有 2 个属性,我只需在发送响应之前键入 check 并相应地键入响应。然而,有 6 个可能的字段可以做到这一点,以及这 6 个字段的任意组合,这会使在发回时尝试正确输入变得非常混乱。
所以我的问题:有没有办法检查传递的
expand
数组中是否存在特定字段,然后根据传递的内容添加/更改接口中的类型?我想启动一个没有这些字段的界面,然后根据参数添加它们:
interface MyPerson {
id: string;
}
interface MyPersonWithAddressId extends MyPerson {
address: string;
}
interface MyPersonWithAddress extends MyPerson {
address: MyAddress
}
但是,正如前面提到的,这对于 6 个属性及其所有可能的组合来说太混乱了。
可行的替代方案是在 MyPerson 上为地址 ID 和详细信息 ID 设置单独的字段吗?
否则,您可以添加检查并使用类型断言来明确您要返回的类型。
if (expand.includes('address')) {
return address as MyAddress
}
return address as string
我认为你必须在“客户端”方面这样做,尽管假设我了解情况。