【问题标题】:No overload matches this call. Type 'string' is not assignable to type 'Signals'没有重载匹配此调用。类型“字符串”不可分配给类型“信号”
【发布时间】:2020-01-03 10:24:42
【问题描述】:

我正在使用 typescript 来构建微服务并处理信号。该代码直到几天前都运行良好,但最近它开始抛出错误。找不到解决此问题的方法。

处理信号的代码。它只是文件的一部分。 src/main.ts

  enum signals {
    SIGHUP = 1,
    SIGINT = 2,
    SIGTERM = 15
  }
  const shutdown = (signal, value) => {
    logger.warn("shutdown!")
    Db.closeAll()
    process.exit(value)
  }
  Object.values(signals).forEach(signal => {
    process.on(signal, () => {
      logger.warn(`process received a ${signal} signal`)
      shutdown(signal, signals[signal])
    })
  })

当我执行ts-node src/main.ts 时,会抛出以下错误并退出。


/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:245
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
src/main.ts:35:16 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type 'string | signals' is not assignable to parameter of type 'Signals'.
      Type 'string' is not assignable to type 'Signals'.

35     process.on(signal, () => {
                  ~~~~~~

  node_modules/@types/node/base.d.ts:653:9
    653         on(event: Signals, listener: SignalsListener): this;
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The last overload is declared here.

    at createTSError (/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:245:12)
    at reportTSError (/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:249:19)
    at getOutput (/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:362:34)
    at Object.compile (/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:395:32)
    at Module.m._compile (/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:473:43)
    at Module._extensions..js (module.js:663:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/home/meraj/.nvm/versions/node/v8.10.0/lib/node_modules/ts-node/src/index.ts:476:12)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)

任何修复将不胜感激。或者,如果您能说出为什么它在 2 天前更早地工作而不是现在。

【问题讨论】:

  • process.on() 期望它的第一个参数是数字还是字符串?根据文档,它看起来应该是一个字符串。 Object.values(signals) 返回一个数字数组。我想你想要Object.keys(signals),我猜最近两天的变化是你将枚举值设置为数字而不是常量字符串。
  • 只要我说的是很长一段时间都没有改变的枚举,我想也许这个数字会造成问题并将其转换为字符串但仍然没有用。
  • 尝试从Object.values()更改为Object.keys()

标签: javascript node.js typescript signals


【解决方案1】:

我也遇到了这个奇怪的问题,但我使用类型断言(在我的例子中使用字符串枚举)解决了这个问题:

(Object.values(someEnum) as string[]).concat(otherStringArray);

【讨论】:

【解决方案2】:

当您向匿名函数传递了错误数量的参数时,有时会发生这种情况:

    Object.keys(data).reduce((key: string) => {

    }, {}); 

会报错:

没有重载匹配这个调用。重载 1 of 3

传递正确数量的参数:

    Object.keys(data).reduce((acc: any, key: string) => {
    }, {});

【讨论】:

  • 我收到了同样的消息“没有超载匹配此调用。”这是因为我没有传递正确数量的参数。
【解决方案3】:

解决方案1:保留numeric enumsignals

Object.values(signals)
  // numeric enum includes reverse mapping, filter numbers out and keep "SIGHUP" etc.
  .filter((s): s is NodeJS.Signals => typeof s !== "number") 
  .forEach(signal => {
    process.on(signal, ...) // works now
  })

解决方案 2:使用纯信号字符串字面量类型

// these string literal items are strongly typed by built-in NodeJS.Signals type
Object.values<NodeJS.Signals>(["SIGHUP", "SIGINT", "SIGTERM"])
  .forEach(signal => {
    process.on(signal, ...) // works now
  })

解决方案 3:更改为 string enum(无反向映射)

enum signals2 {
  SIGHUP = "SIGHUP",
  SIGINT = "SIGINT",
  SIGTERM = "SIGTERM"
}

Object.values(signals2)
  .forEach(signal => {
    process.on(signal, ...) // works now
  })

为什么会发生错误?

signals 这样的数字枚举包括reverse mapping。例如,您可以执行以下操作:

const r1 = signals.SIGHUP // r1 value: 1
const r2 = signals[signals.SIGINT] // r2 value: "SIGINT"
const r3 = signals[15] // r3 value: "SIGTERM"

这就是为什么你会得到 (string | signals)[] 以返回 Object.values(signals),其中 string 代表枚举键,signals 代表枚举值。

现在,process.on(signal, ...) 中的参数 signal 必须是 predefined Node.JS string literal types 之一。但是我们传入了string | signals 项目类型,所以 TS 在这一点上大喊大叫。

【讨论】:

    【解决方案4】:

    当您没有正确分配类型时会发生这种情况。

    您的变量数据类型必须与传递的数据类型匹配。

    organizationList: { id: string; name: string;  }[] = [] //if you do this way it type error
    organizationList: Organization[] = [] //correct defining method 
    
    get Org() {
        return this.list.filter((org: Organization) => org.id == this.id) //this data type must defined data type
      }
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2020-03-14
      • 1970-01-01
      • 2021-02-22
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多