我可以在函数上使用条件类型来指示布尔值或实现接口的对象吗?



我正在尝试这样的事情...

export class LinkInterface {
rel: string
href: string
method: string
}

然后在函数中

export function getLinkInterfaceForRel(links: LinkInterface[], targetRel: string): boolean | LinkInterface {
if (links.length < 1) return false;
const returnLink: LinkInterface[] = links.filter(el => el.rel.toLowerCase() === targetRel.toLowerCase());
return returnLink.length > 0 ? returnLink[0] : false;
}

我像这样使用函数:

const getStatisticsLinks = getLinkInterfaceForRel(this.question.links, 'Get_Statistics');
if (getStatisticsLinks) {
// This line is where the "property href does not exist" error happens during compile
this.service.get(getStatisticsLinks.href).subscribe(.....);
}

但是,在编译时我收到错误:Property 'href' does not exist on type 'boolean | LinkInterface'

我也尝试了这样的事情:

type LinkInterfaceOrBoolean = boolean | LinkInterface;
export function getLinkInterfaceForRel(links: LinkInterface[], targetRel: string): LinkInterfaceOrBoolean {}

但是我得到了类似的错误(href 在 LinkInterfaceOrBoolean 类型上不存在(。

我想我应该在这里使用条件类型,但很难理解这似乎是一件简单的事情 - 我应该做什么?

由于您希望测试if(getStatisticsLinks) { ... }并将类型缩小到测试通过时LinkInterface,这实际上非常容易。你的函数从不返回true,只返回false,所以返回类型可以是LinkInterface | false而不是LinkInterface | boolean

也就是说,我建议在这里返回undefined而不是false,因为这是指示没有结果的更常用方式。if条件仍然以相同的方式工作,因为undefined是假的。它还简化了实施:

function getLinkInterfaceForRel(links: LinkInterface[], targetRel: string): LinkInterface | undefined {
targetRel = targetRel.toLowerCase();
// could also use .find(...) here, which returns undefined if no match is found
return links.filter(el => el.rel.toLowerCase() === targetRel)[0];
}

游乐场链接

您需要编写自己的类型卫士来"缩小"类型范围,以便 TypeScript 编译器在this.service.get(getStatisticsLinks.href).subscribe(.....);中使用时知道getStatisticsLinks属于LinkInterface类型。

这是编写类型保护的一种方法:

function isLinkInterface(obj: LinkInterface | boolean): pet is LinkInterface {
return (obj as LinkInterface).href !== undefined;
}

然后,这就是您可以使用它的方式:

const getStatisticsLinks = getLinkInterfaceForRel(this.question.links, 'Get_Statistics');
if (getStatisticsLinks && isLinkInterface(getStatisticsLinks)) {    
this.service.get(getStatisticsLinks.href).subscribe(..);
}

仅当getStatisticsLinks属于LinkInterface类型(因为它具有 href 属性(时,isLinkInterface()类型防护才会返回true,然后有条件地调用this.service.get()

最新更新