meow
meow copied to clipboard
Expected behavior is unclear when using types and non-camelcase
Hello!
I came across a gotcha and wanted to document it for future users of this library.
As demonstrated by this sandbox https://codesandbox.io/s/meow-kebab-case-behavior-9rpoc, the type hints are inconsistent with the actual shape of the parsed object. The code below is from the sandbox to demonstrate:
import meow from "meow";
const cli = meow("", {
flags: {
"input-file": {
type: "string",
alias: "i",
default: "INPUT"
}
}
});
const camel = cli.flags.inputFile;
const kebab = cli.flags["input-file"];
type C = typeof camel; // unknown
type K = typeof kebab; // string;
console.log(camel, kebab);
// yet this outputs:
// > INPUT undefined
This leads to some tricky behavior when using meow, TS, and normalized names. Specifically, type hints and autocompletion will show cli.flags['input-file'] as the type-safe suggestion, when it's actually undefined.
I don't think it's possible for meow to handle this due to how TS generics work. But hopefully this saves someone else time that I spent trying to figure this out :D Unfortunately I don't know of a type-safe workaround.
And there's always the chance I'm doing something wrong, and if so, sorry for the noise. Thanks for the library!
// @NiGhTTraX Is there anything we can do to improve this other than better docs about it?
Unfortunately, no. We can't express the normalization of the flags through the type system. However, unnormalizedFlags should contain the flag under its original name with the correct type so in your case cli.unnormalizedFlags['input-file'] // number. It would be nice if this behavior were documented.
I tell you h'wat - you can: https://github.com/microsoft/TypeScript/pull/40336
Note the Split<>
We can now use https://github.com/sindresorhus/type-fest/blob/master/ts41/camel-case.d.ts PR welcome :)
Fixed by https://github.com/sindresorhus/meow/issues/155