是否有 TypeScript 编译器选项强制对对象属性进行类型检查?

Is there a TypeScript compiler option to force type checks on object properties?

为了编写更健壮的代码,我正在考虑将 TypeScript 用于我的基于 Web 的项目。到目前为止,我对这门语言的经验相对较少,但我 运行 遇到了一个我难以搜索的问题。

考虑下面的 TypeScript 代码:

public static getResponseCode(resObj: object): number {
    let c: number = resObj["c"]
    return c;
}

有没有办法强制 TypeScript 编译器将我拉到这里并告诉我 resObj["c"] 可能不是数字,我需要先检查它是否是数字?例如。我可以强制 TypeScript 让我重写代码(或类似的东西)吗?:

public static getResponseCode(resObj: object): number {
    if (typeof resObj["c"] !== "number") { return APIResponseCode.UnknownFailure; }

    let c: number = resObj["c"]
    return c;
}

我希望得到的结果与我的结果完全一样,因为 resObj["c"] 的类型是 any。我可以在这里做什么? TypeScript 中是否使用了通用模式?

您可以打开 noImplicitAny 编译器选项。编译器会在任何时候隐含任何东西时抱怨。

我们在tsconfig.json里面设置了noImplictAny。

{
    "compilerOptions": {
        "noImplicitAny": true
    }
}

或者我们在命令行中这样设置tsc --noImplicitAny

那会迫使你做某事。

例如,您可以明确使用 any。

public static getResponseCode(resObj: object): number {
    const resAny = resObj as any;
    if (resAny.c && typeof resAny.c !== "number") {
        return APIResponseCode.UnknownFailure;
    }

    const c: number = resAny.c;
    return c;
}

或者您可以使用 a union type and a type guard 的界面。

interface ResObj {
    c: boolean | string | number | object;
}

public static getResponseCode2(resObj: ResObj): number {

    if (typeof resObj.c !== "number") {
        return APIResponseCode.UnknownFailure;
    }

    const c: number = resObj.c;
    return c;
}

TypeScript 不进行 运行 时间类型检查。根据您要执行的操作,您有多种选择。首先是为resObj:

定义一个接口
interface ResObj { c: number; }

现在

public static getResponseCode(resObj: ResObj): number {
  let c: number = resObj.c;
  return c;
}

如果您传递 getResponseCodeResObj 不匹配的内容(c 属性 不是数字),您的代码现在将无法编译。

如果您希望 c 可能是一个数字,或者可能是一个字符串怎么办?在这种情况下,使用联合类型:

interface ResObj { c: number | string; }

您上面 getResponseCode 的原始版本现在将无法编译。 TypeScript 会抱怨它不知道如何将 string | number 转换为 number.

如果您按照建议编写代码:

public static getResponseCode(resObj: ResObj): number {
  if (typeof resObj.c !== "number") { return APIResponseCode.UnknownFailure; }

  let c: number = resObj.c;
  return c;
}

TypeScript 会很高兴,因为它的流分析检测到 typeof 检查并且知道在它到达 return 语句时 c 只能是一个数字。

对于更复杂的情况,您可以使用所谓的类型保护,它明确告诉 TypeScript 特定函数保证其参数的特定类型:

function isNumber(c: string | number): c is number {
  return typeof c === 'number';
}

现在你可以写了

public static getResponseCode(resObj: ResObj): number {
  if (!isNumber(resObj.c)) { return APIResponseCode.UnknownFailure; }

  let c: number = resObj.c;
  return c;
}