【问题标题】:Why is it possible to pass a value of type 'any' to a typed parameter without an error?为什么可以将 \'any\' 类型的值传递给类型参数而不会出错?
【发布时间】:2023-01-28 08:44:00
【问题描述】:

TypeScript 转译器不会为以下代码发出错误:

function test1(test: any) {
    test2(test);
}

function test2(test: string) {

}

我预计此代码会发出错误,因为如果类型为“any”的对象可以毫无错误地传递给类型为“string”的参数,那么代码可能会导致在运行时将非字符串传递给 test2 .编译器知道这里存在潜在的类型安全违规应该是微不足道的吧?

我以为 TypeScript 的重点是在编译时确保类型安全?我在这里错过了什么?我需要在 tsconfig.json 中启用一个选项吗?

编辑:

我不认为我在上面包含的通用示例能够说明我的观点。这是我实际应用程序中的 sn-p。该代码是 Google Apps 脚本应用程序的一部分,我使用的是 @google/clasp 类型。

// 'sheet' is of type GoogleAppsScript.Spreadsheet.Sheet
// The return value of this function is any[][]
// There is nothing I can do to change this, it is an import from a library
const cells = sheet.getSheetValues(2, 1, -1, -1);

for (const cell of cells) {
    const registration = cell[0]; // any
    const profileName = cell[1]; // any
    const uuid = cell[2]; // any

    //
    // The signature of this constructor is as follows:
    // constructor(aircraft: InputAircraft, profileName: string, uuid: string)
    //
    // Passing 'any' to the parameters of this constructor does not cause any 
    // warning or error, even with strict=true in my tsconfig.conf or even 
    // with eslint set up with the @typescript-eslint/no-explicit-any rule 
    // turned on.
    //

    yield new InputProfile(registration, profileName, uuid);
}

【问题讨论】:

  • 是的 - 使用 any 违背了 TypeScript 的目的,因为它不是类型安全的,这就是为什么许多 linters 和一些配置设置警告反对它。简单的解决方案:永远不要使用any
  • @CertainPerformance 哪些设置会导致 TypeScript 发出使用 any 的警告?这正是我想要的。促使我发帖的问题是,我正在使用的库从特定函数返回 any[][],并且我将“any”对象之一传递给类型函数,但没有意识到发生了类型安全违规。显然,这意味着我实际上在代码中写入了一个错误,但我希望 TypeScript 会警告我这个错误,因为这实际上是静态类型检查的全部要点。
  • @CertainPerformance noImplicitAny 不起作用(不产生错误或警告)。我还有strict
  • 是的,因为你正在使用明确的任何 - 但 noImplicitAny 帮助其他any问题。结合 strict 和 linter,你会很高兴。

标签: typescript


【解决方案1】:

any 是故意留下来的大约类型检查器,用于处理遗留的非类型化 Javascript 代码。它应该只要在您有未键入或不易键入的代码的情况下使用。

使用 --strict(其中包括 noImplicitAny,除此之外),如果变量曾经出现,您将收到警告偶然类型为any。如果你写any,编译器会假定你是认真的并且知道你在做什么。如果你真的想去没有能力使用any根本,然后 no-explicit-any 是您可以打开的 ESLint 设置。

【讨论】:

  • 我在我的应用程序中使用的库从函数返回 any[][] 。如果我将此数组的“任何”元素传递给任何类型参数(或将它们分配给类型化变量),我想收到来自 TypeScript 的错误或警告。但是,尽管我打开了strict,但我没有收到任何错误或警告。
  • 我不确定我是否遵循您的要求。如果您想避免any,请使用no-explicit-any。如果你一个 any 并且不希望它是 any,然后转换它。如果你有一个 any 但不想转换它或用它做任何事情,那么......好吧,就丢弃它,因为那时它对你没有用。你打算怎么办如果不强制转换或使用元素,则使用 any[][]
  • 如果我无意中将 any 对象传递给类型化参数或变量而没有首先对其执行运行时类型检查(即 typeof value == 'string'),我希望 TypeScript 给我一个错误。
  • 然后投射到unknown[][]unknown 是表示“如果不进行转换我将无法对此做任何事情”的类型。 any 表示“我可以做任何事情,相信我”。
  • 为了知道将其转换为unknown[][],程序员首先需要知道它是any[][]。如果我忘记了一个特定的库函数返回 any 怎么办?对于这种情况,我希望编译器或 linter 出现错误,但我想不出任何方法来完成此操作。请参阅我更新的原始帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 2021-12-05
  • 2019-09-06
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多