打字稿:如何在两个相似的界面之间进行过滤

时间:2019-07-18 14:18:54

标签: typescript

我正在尝试编写一个可以接收几个相似对象的函数。像这样:

SELECT COUNT(*) FROM pages WHERE id_parent = YOUR_PAGE_ID OR (id = YOUR_PAGE_ID AND id_parent IS NOT NULL)

然后,我有一条简单的interface BannerProps { type: typeof possibleBannerTypes[number]; data?: unknown } 语句链,它们根据type参数返回不同的UI组件。

if/else if

function test(bannerData: EmailBounceBannerProps | BannerProps) { if (bannerData.type === 'anotherBanner') { // do something } else if (bannerData.type === 'emailBounce') { console.log(bannerData.data.reason) } } 属性设置为特定值(type)的对象具有我也想键入的data属性,以便可以在VS Code中使用类型检查和Intellisense。

emailBounce

但是,我似乎无法使其正常工作,打字稿似乎无法弄清何时填充interface EmailBounceBannerProps extends BannerProps{ type: 'emailBounce'; data: { reason: string; }; } type === 'emailBounce属性。

我在TypeScript游乐场上创建了一个小片段来说明此问题:

Code snippet

我要做的就是让它通过无错误,同时获得基于data的代码建议

error message from the above link

我很确定自己之前已经成功完成了类似的工作,但是我无法弄清楚自己在做什么错。我也不确定这种做法或代码模式是什么,所以到目前为止,我在Google上搜索并没有获得任何成功的结果。

有人有解决方案,或者有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

第一个问题是possibleBannerTypes将被扩展为string[],我们需要一个as const来保持文字类型。

第二个问题是,由于您在分支BannerProps上与bannerData.type === 'emailBounce'进行了联合,因此您并没有真正缩小范围,因为bannerData仍然可以是EmailBounceBannerProps或{ {1}}。这意味着BannerProps将是data,而仅仅是unknown | { reason: string }

您需要一个默认案例,该案例要从unknown属性中排除任何已知案例。您可以使用type键入此默认接口的Exclude并在联合中使用它代替type

BannerProps