0

I don't understand when I abstract options to a variable (or even import from another file), Typescript complains with:

Argument of type '{ exclude: { type: string; required: boolean; description: string; default: never[]; alias: string; }; someOtherFlag: { type: string; required: boolean; description: string; default: never[]; }; }' is not assignable to parameter of type '{ [key: string]: Options; }'.
  Property 'exclude' is incompatible with index signature.
    Type '{ type: string; required: boolean; description: string; default: never[]; alias: string; }' is not assignable to type 'Options'.
      Types of property 'type' are incompatible.
        Type 'string' is not assignable to type '"string" | "number" | "boolean" | "array" | "count" | undefined'.ts(2345)
import * as yargs from 'yargs';

const options = {
  exclude: {
    type: 'array',
    required: false,
    description: 'Files to exclude',
    default: [],
    alias: 'e'
  },
  someOtherFlag: {
    type: 'array',
    required: false,
    description: 'Another example flag'
    default: []
  }
};

// throws Typescript error
const cliOptions = yargs.options(options).argv;
cusejuice
  • 10,285
  • 26
  • 90
  • 145

1 Answers1

3

Do one of the following (first is using as const):

const options = {...} as const 

// or 
const options = {
  exclude: { type: "array"  as "array", ...},
  someOtherFlag: { type: "array" as "array", ...}
} 

Explanation:

Your options literal passed to yargs.options(options) seems to be fine, when looking at its type declaration.

There is one important point, why it doesn't work in the current form: options literal type gets widened. As a consequence, type: 'array' becomes type: string. yargs.options expects a string literal for type, so here it blows up.

Mentioned type widening basically happens because of an immutability check and lack of explicit type, if you want to read more on this topic.

ford04
  • 66,267
  • 20
  • 199
  • 171