具有Typeguard的通用伪造过滤器无法正确缩小类型

时间:2020-09-19 14:56:03

标签: typescript

考虑一下这段代码,该代码定义了一个带有Typeguard的过滤功能,用于过滤出虚假的值。

function falsyFilter<T>(
  x: T
): x is Exclude<T, null | undefined | false | 0> { return !!x; }

const filtered = ['a', 'b', 'a', 'b'].map(x => x === 'a' ? x : 0).filter(falsyFilter);

console.log(filtered);

const consumeString = (s: string) => s+s;

filtered.map(consumeString);

我希望最后一行不会产生任何类型错误。现实是不同的。我得到:

Argument of type '(s: string) => string' is not assignable to parameter of type '(value: 0 | "a", index: number, array: (0 | "a")[]) => string'.
  Types of parameters 's' and 'value' are incompatible.
    Type 'string | number' is not assignable to type 'string'.
      Type 'number' is not assignable to type 'string'.(2345)

您可以在游乐场here中看到示例。

我不确定是否发现了错误,或者不了解那里发生了什么。如果我在0内部的三元组中使用null而不是map,一切都会按预期进行。

编辑: 我认为它与如何在0的参数中将number推断为falsyFilter有关。因此,当发生这种情况时,基本上会要求函数检查类型number的值是否为number,这始终是正确的(但函数返回的是boolean),所以也许打字稿只是忽略该函数实际返回的内容。

如果有人可以确认那会很酷。

0 个答案:

没有答案