打字稿检查多个变量是否未定义

Typescript check multiple variable for undefined

我有以下代码块

const { att: { p, r } = {}, dir: { hdg } = {} } = record;

if ([p, r, hdg].some((e) => e === undefined)) {
    return null;
}
//TS2532: Object is possibly 'undefined'.
const heading = hdg.toValue("rad");

我解构一个对象,然后我检查是否有任何属性未定义,如果其中任何一个是我存在的函数,否则我继续执行。

即使在保护子句之后打字稿仍然抱怨对象可能未定义。

我如何编写这个保护子句让编译器知道任何字段都可以是 0 或布尔值,除了

if (p === undefined || r === undefined || hdg === undefined) {
    return null;
}

你能做的最好的事情就是像这样使用 Arraytype predicate

type SomeType = { toValue(s: string): unknown };

function test(p?: SomeType, r?: SomeType, hdg?: SomeType) {

    const toCheck = [p, r, hdg];

    if (checkForNulls(toCheck)) {
        const [p, r, hdg] = toCheck;
        const heading = hdg.toValue("rad");
    }
}

function checkForNulls<T>(args: (undefined | T)[]): args is T[] {
    return args.every(e => e !== undefined)
}

TypeScript playground

此解决方案的一个缺点是它将每个 Array 项目类型扩展为所有实际项目的联合类型,因此它仅在要检查的变量属于同一类型时才有效。否则原始类型将丢失。

这是另一个允许恢复原始类型的解决方案。它适用于函数重载和元组,但它需要根据需要编写尽可能多的重载用法:

type SomeType = { toValue(s: string): unknown };

function test(p?: boolean, r?: number, hdg?: SomeType) {

    const toCheck = [p, r, hdg] as const;

    if (checkForNulls(toCheck)) {
        const [p, r, hdg] = toCheck;
        const heading = hdg.toValue("rad");
    }
}

function checkForNulls<T>(args: readonly [T | undefined]): args is [T]
function checkForNulls<T, U>(args: readonly [T | undefined, U | undefined]): args is [T, U]
function checkForNulls<T, U, V>(args: readonly [T | undefined, U | undefined, V | undefined]): args is [T, U, V]
function checkForNulls<T>(args: readonly (undefined | T)[]): args is T[] {
    return args.every(e => e !== undefined)
}

TypeScript playground