Giter Club home page Giter Club logo

Comments (4)

iclanton avatar iclanton commented on June 20, 2024

I'm not getting a repro of this issue. I've created a repo here with your example and invited you to it: https://github.com/iclanton/rushstack-4708-repro. Can you update that with your repro?

This is the output I get from various commands (I've run this on Windows and Linux, but not Mac):

> node lib\test
usage: widget [-h] [-v] <command> ...

The "widget" tool is a code sample for using the @rushstack/ts-command-line
library.

Positional arguments:
  <command>
    push         Pushes a widget to the service

Optional arguments:
  -h, --help     Show this help message and exit.
  -v, --verbose  Show extra logging detail

For detailed help about a specific command, use: widget <command> -h

> node lib\test push
WidgetCommandLine.onExecute CommandLineFlagParameter {
  longName: '--verbose',
  _shortNameValue: '-v',
  parameterGroup: undefined,
  parameterScope: undefined,
  description: 'Show extra logging detail',
  required: false,
  environmentVariable: undefined,
  undocumentedSynonyms: undefined,
  allowNonStandardEnvironmentVariableNames: undefined,
  _value: false,
  kind: 1,
  _parserKey: 'key_0'
}
PushAction.onExecute false scp

from rushstack.

Petah avatar Petah commented on June 20, 2024

Hmm, it seems to be an issue with my tsconfig.json. Not sure if thats a bug, or just incorrect setup on my part, but I have updated the tsconfig.json in that repo.

> node lib/test.js --verbose push --force
WidgetCommandLine.onExecute undefined
PushAction.onExecute true scp
> ./node_modules/.bin/ts-node src/test.ts --verbose push --force
WidgetCommandLine.onExecute undefined
PushAction.onExecute true scp

from rushstack.

iclanton avatar iclanton commented on June 20, 2024

This issue is the "target": "es2022" compiler option. See TypeScript docs here: https://www.typescriptlang.org/docs/handbook/2/classes.html#initialization-order

Comparing the TypeScript compiler output for es2021 vs es2022:

class WidgetCommandLine extends ts_command_line_1.CommandLineParser {
+    _verbose;
    constructor() {
        super({
            toolFilename: "widget",
            toolDescription: 'The "widget" tool is a code sample for using the @rushstack/ts-command-line library.',
        });
        this.addAction(new PushAction());
    }
    onDefineParameters() {
        // abstract
        this._verbose = this.defineFlagParameter({
            parameterLongName: "--verbose",
            parameterShortName: "-v",
            description: "Show extra logging detail",
        });
    }
    onExecute() {
        // override
        console.log("WidgetCommandLine.onExecute", this._verbose);
        return super.onExecute();
    }
}

Notice that the _verbose field is now emitted in the class. The onDefineParameters function is called by the CommandLineParser's constructor, which causes the problem. From the TypeScript docs, the initialization order is:

  1. The base class fields are initialized - _verbose is not defined at this point
  2. The base class constructor runs - **onDefineParameters is called, and _verbose is now defined as expected`
  3. The derived class fields are initialized - the _verbose field initializer, emitted by TS in >=ES2022, is executed and redefines _verbose as undefined
  4. The derived class constructor runs - other stuff happens, like the this.addAction(new PushAction()); line

To fix this issue, target <es2022, or move the parameter declarations into the WidgetCommandLine constructor, like ths:

export class WidgetCommandLine extends CommandLineParser {
-  private _verbose!: CommandLineFlagParameter;
+  private _verbose: CommandLineFlagParameter;

  public constructor() {
    super({
      toolFilename: "widget",
      toolDescription:
        'The "widget" tool is a code sample for using the @rushstack/ts-command-line library.',
    });

    this.addAction(new PushAction());
-  }
-
-  protected onDefineParameters(): void {
-    // abstract
+
+  // define parameters
    this._verbose = this.defineFlagParameter({
      parameterLongName: "--verbose",
      parameterShortName: "-v",
      description: "Show extra logging detail",
    });
  }

  protected onExecute(): Promise<void> {
    // override
    console.log("WidgetCommandLine.onExecute", this._verbose);
    return super.onExecute();
  }
}

We should probably consider removing the onDefineParameters function and, instead, explicitly recommending that users of ts-command-line initialize parameters directly in the constructor. This allows the removal of the non-null assertion on the _verbose field.

from rushstack.

iclanton avatar iclanton commented on June 20, 2024

Closing this out, since it seems like we've figured out the issue.

from rushstack.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.