Roaders / ts-command-line-args

A typescript wrapper for command-line-args that allow you to generate config from existing TS interfaces
26 stars 11 forks source link

Can't get it working #18

Closed mmajcica closed 3 years ago

mmajcica commented 3 years ago

I started with a simple example, but I just can't get it working.

Consider the following example:

import { parse } from 'ts-command-line-args';

interface ISplunkArguments {
    baseUrl: string;
    token: string;
    filePath: string;
}

const args = parse<ISplunkArguments>({
    baseUrl: { type: String, alias: 'u', description: 'Base Url of Splunk server'},
    token: { type: String, alias: 't', description: 'Security token' }, 
    filePath: { type: String, alias: 'f', description: 'Full path to the report file' },
},
{
    helpArg: 'help',
});

console.log(`exampleConfig args: ${JSON.stringify(args)}`);

I just get the baseUrl underlined as an error and can't transpile my code.

Screenshot 2021-07-01 at 18 07 06

The error I'm getting is:

Type '{ type: StringConstructor; alias: string; description: string; }' is not assignable to type 'PropertyOptions<string>'.
  Property 'optional' is missing in type '{ type: StringConstructor; alias: string; description: string; }' but required in type '{ optional: true; }'.

Do you have any clue, this package seems really straight forward and easy to use and I would love to understand why this is not working.

Thanks

Roaders commented 3 years ago

It works for me:

image

The error I get is the helpArg. You have specified "help" but you have not defined a "help" boolean in your ISplunkArguments:

interface ISplunkArguments {
    baseUrl: string;
    token: string;
    filePath: string;
    help: boolean;
}

const argsTwo = parse<ISplunkArguments>(
    {
        baseUrl: { type: String, alias: 'u', description: 'Base Url of Splunk server' },
        token: { type: String, alias: 't', description: 'Security token' },
        filePath: { type: String, alias: 'f', description: 'Full path to the report file' },
        help: Boolean,
    },
    {
        helpArg: 'help',
    },
);

What version of typescript are you using? The project is compiled with version 4. Lower version should work but I am not sure what the minimum version is. Probably around 3.8 I would guess.

micimize commented 3 years ago

@mmajcica make sure your script is included in tsconfig.json#include e.g "include": ["src/", "scripts/"]

Roaders commented 3 years ago

If you push to a GitHub repo I can take a look and submit a PR to fix it.

mmajcica commented 3 years ago

It works for me:

image

The error I get is the helpArg. You have specified "help" but you have not defined a "help" boolean in your ISplunkArguments:

interface ISplunkArguments {
    baseUrl: string;
    token: string;
    filePath: string;
    help: boolean;
}

const argsTwo = parse<ISplunkArguments>(
    {
        baseUrl: { type: String, alias: 'u', description: 'Base Url of Splunk server' },
        token: { type: String, alias: 't', description: 'Security token' },
        filePath: { type: String, alias: 'f', description: 'Full path to the report file' },
        help: Boolean,
    },
    {
        helpArg: 'help',
    },
);

What version of typescript are you using? The project is compiled with version 4. Lower version should work but I am not sure what the minimum version is. Probably around 3.8 I would guess.

I just checked and VSCode is using the 4.3.2.

mmajcica commented 3 years ago

If you push to a GitHub repo I can take a look and submit a PR to fix it.

I'll prep a small project in a minute and paste a link.

mmajcica commented 3 years ago

If you push to a GitHub repo I can take a look and submit a PR to fix it.

Done. https://github.com/mmajcica/test-ts-command-line-args

Same result, new clean project from scratch:

Screenshot 2021-07-01 at 21 50 38
Roaders commented 3 years ago

Ok, I figured it out. It took me a while though! The error is actually correct. You do have to specify all the arguments as optional as they are all optional - because you have not turned on strictNullChecks. Without strict null checks anything can potentially be undefined - at least it looks that way to the typing system in use here.

Just set strictNullChecks to true in your tsconfig.json (in fact you should turn on the strict setting that turns on all the best practice settings) and it'll work.

mmajcica commented 3 years ago

Wow, not an easy one! That was it, it solves the problem.

The fact is that if we create a new tsconfig.json file via the tsc itself with tsc --inti we get the following:

{
  "compilerOptions": {
    "target": "es5",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
    "module": "commonjs",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "strict": true,                                 /* Enable all strict type-checking options. */
    "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true        /* Disallow inconsistently-cased references to the same file. */
  }
}

As you can see, by default we have "strict": true (enables all strict type-checking options). This is often a bit too much and I see it also often disabled. Maybe it would be good if this would be mentioned in the documentation.

Thanks