在打字稿中使用指挥官

时间:2017-05-05 06:23:05

标签: node.js typescript definitelytyped node-commander

我尝试在打字稿中使用指挥官,我想给我的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类添加属性。

2 个答案:

答案 0 :(得分:2)

使用您的第一个代码段和以下依赖项,我不会收到错误:

"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 {
}

我不知道这个问题是否可以解决。

答案 1 :(得分:0)

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

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的最后一行之前的行中,我首先强制转换为非重叠类型的未知对象,然后最后强制转换为我们的接口-InterfaceCli。 / p>