这与用于验证数组的每个项目是否已定义的类型保护密切相关,除了接受的答案不适用于元组。
接受的答案的类型保护与此类似:
function isDefined<T> (value: NonNullable<T> | undefined | null): value is NonNullable<T> {
return value !== null && value !== undefined
}
function isEachItemDefined<T> (value: ReadonlyArray<NonNullable<T> | undefined | null>): value is ReadonlyArray<NonNullable<T>> {
return value.every(isDefined)
}
但我现在的处境是这样的:
type Test = { value: number };
const array: readonly [Test | null, Test | null] = [null, null];
if (isEachItemDefined(array)) {
const [val1, val2] = array;
}
val1
和val2
的类型是Herp | null
。我想制作一个类型保护装置,将 null
从 val1
和 val2
中删除。理想情况下,类型保护应该适用于任意数组 - 可变、只读、元组和无序。知道如何去做吗?
NonNullable
应用于每个元素类型,如下所示:
function isEachItemDefined<T extends readonly any[]>(
arr: T
): arr is { [I in keyof T]: NonNullable<T[I]> } {
return arr.every(v => v != null)
}
如果
T
是像 Array<X>
这样的普通数组类型,那么受保护的类型就是 Array<NonNullable<X>>
。但是,如果 T
是像 [X, Y, Z]
这样的元组,那么受保护类型会将 NonNullable
应用于像 [NonNullable<X>, NonNullable<Y>, NonNullable<Z>]
这样的每个元素。它也适用于 readonly
数组 和 readonly
元组。
让我们测试一下:
type Test = { value: number };
const array: readonly [Test | null, Test | null] = [null, null];
if (isEachItemDefined(array)) {
array; // const array: readonly [Test, Test]
const [val1, val2] = array;
val1.value;
val2.value;
}
看起来不错。