Skip to content
This repository has been archived by the owner on Aug 22, 2023. It is now read-only.

strongly-typed args #43

Open
cyberhck opened this issue Aug 4, 2018 · 10 comments
Open

strongly-typed args #43

cyberhck opened this issue Aug 4, 2018 · 10 comments
Labels
enhancement New feature or request

Comments

@cyberhck
Copy link

cyberhck commented Aug 4, 2018

EDIT FROM JEFF: despite what this says, we already support strongly-typed flags, but with typescript 3.x I think it would also be possible to support args

As of now, when I try to lookup what values are present on args and flags, it's quite tricky and it's not accurate because of any typing. If we could make it generic something like this:

import {Command, flags} from '@oclif/command'

interface IFlags {
  help: IBooleanFlag
  name: string
  connected: boolean
}
interface IArgs {
  file: string
}

export default class ReactComponent extends Command<IFlags, IArgs> {
  static description = 'Generate react components'

  static flags = {
    help: flags.help({char: 'h'}),
    name: flags.string({char: 'n', description: 'Component Name'}),
    connected: flags.boolean({char: 'c', description: 'add connect()'})
  }
  static args = [{name: 'file'}]
  async run() {
    const {args, flags} = this.parse(ReactComponent)
    const name = flags.name || 'world'
  }
}

I do realize that doing argument parsing is different than it is now, that could be tackled either with next major version with breaking changes, or we can find a way around that (or simply say parse will return that type). This would improve experience by so much.

@jdx
Copy link
Contributor

jdx commented Aug 4, 2018

Flags are already strongly typed. With TypeScript 2 args are not possible, but it might be possible with TypeScript 3. I don't think we need to use genetics though

@cyberhck
Copy link
Author

cyberhck commented Aug 4, 2018

I mean, flags are strongly typed already, but the type inference isn't great, for some reason when I type flags. my IDE doesn't already seem to know what they are, and also it shadows the same var from static

@jdx
Copy link
Contributor

jdx commented Aug 6, 2018

It must be something in your setup because it works in the sample project
screen shot 2018-08-06 at 10 27 01 am

@jdx jdx changed the title use generics in command class strongly-typed args Aug 6, 2018
@scvgoe
Copy link

scvgoe commented Aug 12, 2019

any progress on this?

@cspotcode
Copy link

Ideally, I'd like to describe args and flags as another class with decorators. For example:

class MyCommandOptions {
  @flag()
  force: boolean;
  @argument({/* additional options here */})
  name: string;
}

Then, when I parse flags and arguments, I'm given an instance of that class, or at least an object matching the interface.

@RasPhilCo
Copy link
Contributor

@cspotcode neat idea, adding it to list of possible features

@jdx
Copy link
Contributor

jdx commented Jan 21, 2020

Decorators were something I considered but that would mean non-TS CLIs would have to use babel which I wasn’t willing to do.

The TC39 proposal is moving slowly and my understanding is it’s also not compatible with TS decorators.

I do like the syntax, but really decorators aren’t a “thing” yet.

@cspotcode
Copy link

That's totally fair, but if I may make the case for decorators:

They'll be optional. There will be a non-decorator way to achieve the same effect. This means anyone not using TS or babel can use the non-decorator approach, which is totally fine and will work well. Those on TS and Babel can opt-in to the nicer syntax with less repetition. Again, totally optional.

The decorators are not modifying the class other than building a metadata object; for example, they're not wrapping methods or generating getter/setter pairs. They'll be a minimal layer on top of the non-decorator API. This is using such a limited subset of decorator functionality that differences between the 2 specs should not be an issue. The decorator needs a reference to the class and the name of the field. We can avoid getting into decorator metadata, requiring users to specify the type via arguments to the decorator. (@argument({type: 'string'}) foo: string)

@moltar
Copy link

moltar commented May 23, 2020

What about declaring args like flags by specifying an object, but add a position prop which will signify the position of the arg?

@cspotcode
Copy link

cspotcode commented May 23, 2020 via email

@RasPhilCo RasPhilCo added the enhancement New feature or request label Dec 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants