Skip to content

Instantly share code, notes, and snippets.

@hasparus
Created April 10, 2019 20:20
Show Gist options
  • Save hasparus/81f55626cde945a4b3c2d5b3a84cde49 to your computer and use it in GitHub Desktop.
Save hasparus/81f55626cde945a4b3c2d5b3a84cde49 to your computer and use it in GitHub Desktop.
Improved type inference in @types meow
// Type definitions for meow 5.x
// Project: https://github.com/sindresorhus/meow
// Definitions by: KnisterPeter <https://github.com/KnisterPeter>
// Lindsey Smith <https://github.com/praxxis>
// Jason Dreyzehner <https://github.com/bitjson>
// TODO?? hasparus <https://github.com/hasparus>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.4
import * as buildOptions from "minimist-options";
// prettier-ignore
/**
* @author https://stackoverflow.com/users/2887218/jcalz
* @see https://stackoverflow.com/a/50375286/10325032
*/
type UnionToIntersection<Union> =
(Union extends any
? (argument: Union) => void
: never
) extends (argument: infer Intersection) => void
? Intersection
: never;
type StringToTypeD = {
boolean: boolean;
string: string;
};
type StringToType<T> = T extends keyof StringToTypeD
? StringToTypeD[T]
: never;
type PropertyFlags<FlagsSpec> = {
[K in keyof FlagsSpec]: FlagsSpec[K] extends "string" | "boolean"
? StringToType<FlagsSpec[K]>
: FlagsSpec[K] extends { type: infer TT }
? StringToType<TT>
: never
};
type AliasFlags<FlagsSpec> = UnionToIntersection<
{
[K in keyof FlagsSpec]: FlagsSpec[K] extends {
alias: infer A;
type: infer TT;
}
? (A extends string ? Record<A, StringToType<TT>> : never)
: never
}[keyof FlagsSpec]
>;
declare function meow<T extends buildOptions.Options>(
helpMessage: string | ReadonlyArray<string>,
options: meow.Options<T>
): meow.Result<T>;
declare function meow<T extends buildOptions.Options>(
options: string | ReadonlyArray<string> | meow.Options<T>
): meow.Result<T>;
declare namespace meow {
interface Options<T extends buildOptions.Options> {
description?: string | boolean;
help?: string | boolean;
version?: string | boolean;
pkg?: any;
argv?: ReadonlyArray<string>;
inferType?: boolean;
flags?: T;
autoHelp?: boolean;
autoVersion?: boolean;
/**
* Caution: Explicitly specifying undefined for booleanDefault
* has different meaning from omitting key itself.
*/
booleanDefault?: boolean | null;
}
interface Result<T extends buildOptions.Options> {
input: string[];
flags: PropertyFlags<T> & AliasFlags<T>;
pkg: any;
help: string;
showHelp(code?: number): void;
showVersion(): void;
}
interface Flags {
[name: string]: any;
}
}
export = meow;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment