如何在没有任何或对象的情况下制作 TypeScript 类型保护?

Pau*_*ill 9 typescript eslint

我正在使用 typescript-eslint v3.1.0 并在 TypeScript 中具有以下类型保护功能:

interface JWTPayload {
    sub: number;
}

function isJWTPayload(obj: unknown): obj is JWTPayload {
    if (typeof obj !== 'object') {
        return false;
    }

    // eslint-disable-next-line @typescript-eslint/ban-types
    const obj2 = obj as object;

    if (!('sub' in obj2)) {
        return false;
    }

    const obj3 = obj2 as JWTPayload;

    if (!Number.isInteger(obj3.sub)) {
        return false;
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是这样的:在我想象的常见场景中禁用 lint 规则感觉不太好。是否有 TypeScript 模式可以避免这种情况?

一些背景:

被禁用的 typescript-eslint 规则是在https://github.com/typescript-eslint/typescript-eslint/pull/848中引入的,其中认为“99.9%的时间,你不希望使用[“对象”类型],而绝大多数代码库都不想使用它”。他们为什么会这么说?似乎每当您验证用户输入时都会使用它。有没有其他方法可以在不强制转换为“any”的情况下做到这一点?

fre*_*nte 7

我找到了一个没有any也不断言的解决方案:

type Message = {
  text: string;
}

function isObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null;
}

function isMessage(value: unknown): value is Message {
  return isObject(value) && typeof value["text"] === 'string';
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为第一个类型防护正确地检测到了人们所期望的对象。好的部分是isObject可以在任何其他类型的防护中重复使用。

注意:自定义类型防护本质上与断言相同,因此请谨慎使用它们。TypeScript 不提供运行时库来将值映射到本机以外的复杂类型instanceof。即使return true是完全“有效”但错误的。


归档时间:

查看次数:

3068 次

最近记录:

1 年,10 月 前