【问题标题】:Use commander in typescript在打字稿中使用指挥官
【发布时间】:2017-10-03 12:26:36
【问题描述】:

我尝试在打字稿中使用指挥官,我想给我的 cli 一个合适的类型。所以我从这段代码开始:

import * as program from "commander";

const cli = program
  .version("1.0.0")
  .usage("[options]")
  .option("-d, --debug", "activate more debug messages. Can be set by env var DEBUG.", false)
  .parse(process.argv);

console.log(cli.debug)

但我收到此错误:

example.ts(9,17): error TS2339: Property 'debug' does not exist on type 'Command'.

所以我尝试添加一个接口,如文档中的here

import * as program from "commander";

interface InterfaceCLI extends commander.Command {
  debug?: boolean;
}

const cli: InterfaceCLI = program
  .version("1.0.0")
  .usage("[options]")
  .option("-d, --debug", "activate more debug messages. Can be set by env var DEBUG.", false)
  .parse(process.argv);

console.log(cli.debug)

我得到这个错误:

example.ts(3,32): error TS2503: Cannot find namespace 'commander'.

据我了解,cli实际上是commander.Command类型的类所以我尝试添加一个类:

import * as program from "commander";

class Cli extends program.Command {
    public debug: boolean;
}

const cli: Cli = program
  .version("1.0.0")
  .usage("[options]")
  .option("-d, --debug", "activate more debug messages. Can be set by env var DEBUG.", false)
  .parse(process.argv);

console.log(cli.debug)

这给了我这个错误:

example.ts(7,7): error TS2322: Type 'Command' is not assignable to type 'Cli'.
  Property 'debug' is missing in type 'Command'.

我不知道如何在我的文件或新的 .d.ts 文件中将属性添加到 Command 类。

【问题讨论】:

    标签: node.js typescript definitelytyped node-commander


    【解决方案1】:

    我想我找到了解决方案,我真的不知道这是否是一个好习惯,但尽管如此。

    import { Command } from 'commander';
    const cli = new Command();
    
    interface InterfaceCLI{
      debug?: boolean;
    }
    
    cli
      .version("1.0.0")
      .usage("[options]")
      .option("-d, --debug", "activate more debug messages. Can be set by env var DEBUG.", false)
      .parse(process.argv);
    
    const { debug } : InterfaceCli = <InterfaceCli><unknown>cli;
    console.log(debug) // here debug is your cli.debug, I just used object destructuring
    

    在我使用 type casting 的最后一行之前,我首先将非重叠类型转换为 unkown,然后,最后转换为我们的界面 - InterfaceCli

    【讨论】:

      【解决方案2】:

      使用您的第一个代码 sn-p 和以下依赖项,我没有收到错误:

      "dependencies": {
          "commander": "^2.11.0"
      },
      "devDependencies": {
        "@types/commander": "^2.9.1",
        "typescript": "^2.4.1"
      }
      

      Typescript 将 cli.debug 解释为 any。我猜类型声明已经更新了。所以,如果你对any 没问题,问题就解决了。

      如果你真的想告诉 Typescript debug 的类型,declaration merging 原则上是要走的路。它基本上是这样工作的:

      class C {
          public foo: number;
      }
      
      interface C {
          bar: number;
      }
      
      const c = new C();
      const fooBar = c.foo + c.bar;
      

      但是,有一个问题:program.Command is not a type but a variable。所以,你不能这样做:

      interface program.Command {
          debug: boolean;
      }
      

      虽然你可以这样做:

      function f1(): typeof program.Command {
          return program.Command;
      }
      
      type T = typeof program.Command;
      
      function f2(): T {
          return program.Command;
      }
      

      你不能这样做:

      interface typeof program.Command {
      }
      

      也不是这个:

      type T = typeof program.Command;
      
      interface T {
      }
      

      不知道这个问题能不能解决。

      【讨论】:

        猜你喜欢
        • 2016-05-10
        • 1970-01-01
        • 2010-11-24
        • 1970-01-01
        • 2014-12-06
        • 1970-01-01
        • 1970-01-01
        • 2019-02-05
        • 1970-01-01
        相关资源
        最近更新 更多