I am using yargs
to parse the command line parameters. Below is the code:
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { ArgType } from './types';
const argv = yargs(hideBin(process.argv))
.option('migrateName', {
alias: 'n',
description: 'migration name',
type: 'string',
})
.demandOption('migrateName')
.help()
.alias('help', 'h').parse();
console.log(argv.migrateName)
I got a compile error:
Property 'migrateName' does not exist on type '{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; } | Promise<{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; }>'.
Property 'migrateName' does not exist on type 'Promise<{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; }>'
it says migrateName
doesn't exist on argv. But when looking at the argv
type, it has an or
operator. It's type is:
{
[x: string]: unknown;
migrateName: string;
_: (string | number)[];
$0: string;
} | Promise<{
[x: string]: unknown;
migrateName: string;
_: (string | number)[];
$0: string;
}>
I don't understand why typescript
complains about this type even it already has migrateName
in its type.
The version I am using is:
"@types/yargs": "^17.0.10",
"yargs": "^17.4.1",
"typescript": "^4.6.3"
CodePudding user response:
TypeScript is actually describing the error, it's just a bit hard to read because there are some repeated types that have been expanded.
The entire error you have is this:
Property 'migrateName' does not exist on type '{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; } | Promise<{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; }>'.
Property 'migrateName' does not exist on type 'Promise<{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; }>'
If we look carefully, there are actually two lines to this error and a bunch of types that are repeated.
This type is repeated three times in the error message:
{ [x: string]: unknown; migrateName: string; _: (string | number)[]; $0: string; }
That looks like the CLI arguments you are trying to parse.
In our head, let's imagine that we have an alias for that type - let's call it Arguments
.
If we use our imaginary Arguments
type alias in that error message we get this:
Property 'migrateName' does not exist on type 'Arguments | Promise<Arguments>'.
Property 'migrateName' does not exist on type 'Promise<Arguments>'
Now it's looking a bit clearer!
The yargs types say that the parse()
function can return either the arguments themselves or a promise containing those arguments.
The TypeScript error is saying that you haven't handled all possible return types.
If a promise is returned then it won't have the migrateName
property you are trying to access.
Solution
The simple fix is to use yargs's parseSync()
function instead of parse()
.