打字稿和过滤器布尔值

Typescript and filter Boolean

考虑在 strictNullChecks 开启的情况下关注 code

var a: (number | null)[] = [0, 1, 2, 3, null, 4, 5, 6];
var b: { value: number; }[] = a.map(x => x != null && { value: x }).filter(Boolean);

由于以下原因编译失败:

Type '(false | { value: number; })[]' is not assignable to type '{ value: number; }[]'.
  Type 'false | { value: number; }' is not assignable to type '{ value: number; }'.
    Type 'false' is not assignable to type '{ value: number; }'.

但是很明显,false 会被 .filter(Boolean) 过滤掉。

null 相同的问题。

有没有办法(除了写 as number[])来标记该值不包含 falsenull

如果您真的不想更改生成的 JavaScript,而是更愿意强制 TypeScript 编译器识别 Boolean 作为对 false 值的保护,你可以这样做:

type ExcludesFalse = <T>(x: T | false) => x is T;     
var b: { value: number; }[] = a
  .map(x => x != null && { value: x })
  .filter(Boolean as any as ExcludesFalse);

这是可行的,因为如果回调是类型保护,您断言 Booleantype guard, and because Array.filter() is overloaded 到 return 的缩小数组。

上面的 (Boolean as any as ExcludesFalse) 是我能想到的最简洁的代码,它既有效又不会改变生成的 JavaScript。常量 Boolean 被声明为全局 BooleanConstructor 接口的实例,您可以将类似 ExcludesFalse 的类型保护签名合并到 BooleanConstructor 中,但不是以某种方式这让你只需要说 .filter(Boolean) 就可以了。您可以更喜欢类型保护并尝试表示对所有虚假值的保护(except NaN),但您的示例不需要它。

总之,希望对您有所帮助;祝你好运!

你可以使用这样的函数

function nonNullable<T>(value: T): value is NonNullable<T> {
  return value !== null && value !== undefined;
}

type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T; // from lodash

function truthy<T>(value: T): value is Truthy<T> {
    return !!value;
}

[1, 2, 0, null].filter(nonNullable) // number[]
[1, 2, 0, null].filter(truthy) // number[]

不可为空 - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#predefined-conditional-types