No overload matches this call. Type 'string' is not assignable to type 'Signals'

前端 未结 3 1120
[愿得一人]
[愿得一人] 2021-02-11 16:40

I am using typescript to build a microservice and handling signals as well. The code was working fine till a few days ago but recently it started throwing errors. Couldn\'t find

3条回答
  •  日久生厌
    2021-02-11 17:24

    Solution 1: Keep numeric enum signals

    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
      })
    

    Solution 2: Use pure signal string literal types

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

    Solution 3: Change to string enum (no reverse mapping)

    enum signals2 {
      SIGHUP = "SIGHUP",
      SIGINT = "SIGINT",
      SIGTERM = "SIGTERM"
    }
    
    Object.values(signals2)
      .forEach(signal => {
        process.on(signal, ...) // works now
      })
    

    Why does the error happen?

    Numeric enums like signals include a reverse mapping. For example you can do the following:

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

    That is why you get (string | signals)[] back for Object.values(signals), where string stands for the enum keys and signals for the enum values.

    Now, parameter signal in process.on(signal, ...) must be one of the predefined Node.JS string literal types. However we pass in string | signals item type, so TS yells at this point.

提交回复
热议问题