在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[]
除外)标记该值不包含false
或null
?
答案 0 :(得分:3)
如果您确实不想更改生成的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);
这是有效的,因为您断言Boolean
是type guard,并且因为Array.filter()
是overloaded,如果回调是类型保护,则返回缩小的数组。< / p>
以上(Boolean as any as ExcludesFalse
)是我能提出的最干净的代码,它既可以工作又不会改变生成的JavaScript。常量Boolean
被声明为全局BooleanConstructor
接口的一个实例,您可以将ExcludesFalse
类似的类型保护签名合并到BooleanConstructor
中,但不能在某种程度上合并这样你就可以说出.filter(Boolean)
并让它发挥作用。您可以通过类型防护来获得更好的机会,并尝试代表防范所有虚假值(except NaN
),但您不需要为您的示例。
无论如何,希望有所帮助;祝好运!
答案 1 :(得分:2)
只需使用.filter
删除所有null
值,并使用.map
提供默认值,如果值为null
,则不会因为filter
。
var a: (number | null)[] = [0, 1, 2, 3, null, 4, 5, 6];
var b: { value: number; }[] = a.filter(x => x != null).map(x => ({ value : x || 0 }));
答案 2 :(得分:2)
您可以使用类似的功能
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[]