2017-12-27 327 views
1

考虑下面的代码片段:Array.prototype.filter和歧视联盟的最小类型注释?

type asdf = '.' | number; 
const foo: asdf[] = ['.', 1, 3, '.']; 
const bar: number[] = foo.filter(v => typeof v === 'number'); 

它无法编译,因为编译器无法推断出的bar类型是number[]

  1. 为什么编译器不能推导出正确的类型?
  2. 什么是使编译器理解类型的最小类型注释?

回答

1

您需要使用type guard来实现此目的。

一个类型后卫是一个函数,它接收一个项目v并声明它是类型Foo。在你的榜样,你的类型后卫看起来就像这样:

function isNumber(value: asdf): value is number { 
    return typeof value === "number"; 
} 

然后,您将通过该值到您的filter功能,像这样:

const bar: number[] = foo.filter(isNumber); 

如果你想保持你的函数内联,你可以做这样的(但我认为这是一个有点不太清楚):

const bar: number[] = foo.filter((item): item is number => typeof item === "number"); 

你的代码是行不通的,因为你没有足够的item is number一部分 - 告诉合作mpiler,如果断言(typeof item === "number")返回true,则item的类型为number

+0

内联版本**完全**是我希望的解决方案。非常感谢! – LudvigH