meow
meow copied to clipboard
[TS] Any way to predefine the flags then typecheck them in options?
Currently the type of flags are difficult to predefine, it'll be easier to write the meow(..., ...) function then get the returned type.
But I'm trying to predefine the flags' type then use it to typecheck the meow() function. e.g.:
// interfaces/config.ts
export interface IFlags {
flag1: string;
flag2: boolean;
flag3: number;
}
export interface IConfig {
argv: meow.IResult<IFlags>; // similar to meow.Result but pass in flag type not flag def
some: string;
other: boolean;
configs: number[];
}
// config.ts
import {IFlags, IConfig} from './interfaces/config.ts';
const argv = anotherWayToMeow<IFlags>( // similar to current meow() but pass in flag type not def
`Usage: xxxxxxx`,
{
flags: {
// better to have typecheck here,
// if not at least can predefine the result flags
flag1: { alias: 'a', type: 'string' },
flag2: { alias: 'b' }, // error because missing type: 'boolean'
// error because missing flag3
},
},
)
const some = 'xxxx';
const other = process.env.MY_ENV === 'other';
const configs = [1,2,3];
const config: IConfig = { argv, some, other, configs };
export default config;
Why do you need to predefine them? The Meow types are smart enough to use the correct types depending on what you specify in the flag.type property. See: https://github.com/sindresorhus/meow/commit/3e05a2ee38559b848b487d3fae892b271dfb5908
// @NiGhTTraX
That's because:
- I want to share the type of flags to other files.
- In my team, we're used to design a module/file (result in interfaces & type aliases) before coding it.
- Personally, I'm used to firstly write down the type I want then use it to type-check my impl. (this is the reason I use ts instead of js)
@whitetrefoil you don't need to pass a generic type to meow if you can define your expected result type:
type Flags = {
foo: number;
}
const cli: { flags: Flags } = meow({
flags: {
foo: { type: 'number' }
}
});
You would get a type error if you tried to use type: 'string' instead because the result wouldn't be assignable to your type.
@NiGhTTraX That's a nice workaround. I'll use it before I find a better way (if there is). Thanks a lot!
The solution suggested by @NiGhTTraX sounds like the proper one to me.
It's even the one used in meow's type tests:
https://github.com/sindresorhus/meow/blob/629af48c24a2f19636512b2f532cfcd9419f9be1/index.test-d.ts#L8-L16
Would this not be solved by a very simple export of AnyFlags type? Type errors would be show at the same location as the flags definition, rather then where they are passed.
// file_1.ts
const flags: AnyFlags = {
unicorn: {
type: 'string',
},
};
// file_2.ts
meow(flags);