参数“ err”和“错误”的类型不兼容。输入'ExecException | “ null”不可分配给“ Error”类型

时间:2018-11-20 04:27:17

标签: node.js typescript

这是我的程序:

import * as child_process from 'child_process'

let global_npm_modules = ''

const initial_command = 'npm ls -g --depth=0 --json'
const shell = 'powershell'
const callback = (err: Error, stdout: string | Buffer, stderr: string | Buffer) => {
    if (err) {
        console.log('There was an error\n\n', err)
        return
    }

    console.log(stdout)
}

child_process.exec(initial_command, {shell: shell}, callback)

并且tslint在最后一行中抱怨callback并给出了错误:

[ts]
Argument of type '(err: Error, stdout: string | Buffer, stderr: string | Buffer) => void' is not assignable to parameter of type '(error: ExecException | null, stdout: string | Buffer, stderr: string | Buffer) => void'.
  Types of parameters 'err' and 'error' are incompatible.
    Type 'ExecException | null' is not assignable to type 'Error'.
      Type 'null' is not assignable to type 'Error'.
const callback: (err: Error, stdout: string | Buffer, stderr: string | Buffer) => void


我不太确定我在这里缺少什么。我在这里关闭了Node文档:https://nodejs.org/dist/latest-v11.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback

我只是使用本节中提供的类型:

callback <Function> called with the output when process terminates.

error <Error>
stdout <string> | <Buffer>
stderr <string> | <Buffer>


这是我的tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "rootDir": "src",
    "outDir": "dist",
    "lib": [
      "esnext",
      "dom"
    ],
    "strict": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "declaration": true
  },
  "exclude": [
    "node_modules",
    "dist"
  ]
}

我还安装了@types/node

编辑

文档使用Node来说明child_process.exec()”“如果提供了回调函数,则会使用参数(错误,标准输出,标准错误)调用该函数。成功后,错误将为null。 “

但是使用TypeScript,Error类型被定义为

interface Error {
    stack?: string;
}

我应该将| null参数添加为可能的类型吗?还是error软件包的错误?

2 个答案:

答案 0 :(得分:1)

回调的第一个参数的类型定义为ExecException | null,并且ExecException扩展了Error。而且由于程序员已向库提供了回调函数,并将由库调用该回调函数,所以该回调函数应涵盖传递给它的参数的所有可能性。

您的callback: (error: Error, /* code omitted */) => ChildProcess只能处理error类型为Error的类型声明,而不能处理error为null的情况。所以tsc发出类型错误。

我现在可以想到两种解决方案:

  1. | null添加到error的类型声明中
    const callback = (err: Error | null, stdout: string | Buffer, stderr: string | Buffer) => {
        if (err) {
            console.log('There was an error\n\n', err)
            return
        }

        console.log(stdout)
    }
  1. 从现有声明中推断回调的预期类型,然后使用该推断类型声明回调。
    type CallbackType = typeof child_process.exec extends (cmd: string, options: any, callback: infer P) => ChildProcess ? P : any 

    const callback: CallbackType  = (err, stdout, stderr) => {
        if (err) {
            console.log('There was an error\n\n', err)
            return
        }

        console.log(stdout)
    }

Check it in online repl

答案 1 :(得分:0)

此问题的可能解决方案是添加

"compilerOptions": {
    "strictNullChecks": false
}

tsconfig.json

但希望在将来,我能找到不需要此解决方案的

编辑

或者可以将| null添加为err的类型注释。我选择选择这种更具体的解决方案。