Skip to content

Instantly share code, notes, and snippets.

@toridoriv
Last active November 10, 2023 19:56
Show Gist options
  • Save toridoriv/c96e2a07b2eae3705c2f0cc6234b2bfd to your computer and use it in GitHub Desktop.
Save toridoriv/c96e2a07b2eae3705c2f0cc6234b2bfd to your computer and use it in GitHub Desktop.
Just trying something
// deno-lint-ignore-file no-explicit-any ban-types
export interface DenoManageFlag {
name: string;
abbreviation: string;
type: KeyOf<TypeMap>;
description: string;
options?: FlagOptions;
}
export interface DenoManageCommand<F extends Flags | null = null> {
name: string;
description: string;
action: Action<F>;
flags?: F extends null ? undefined : F;
}
export function defineCommand<T extends DenoManageCommand<any>>(command: T) {
return command;
}
type Action<F extends Flags | null> = F extends Flags
? (options: Expand<InferOptionsFromFlag<F>>) => void | Promise<void>
: () => void | Promise<void>;
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
type Flags = Record<string, DenoManageFlag>;
type FlagOptions = {
hidden?: boolean;
default?: unknown;
required?: boolean;
standalone?: boolean;
depends?: string[];
collect?: boolean;
};
type InferOptionsFromFlag<F extends Flags> = {
[K in keyof F]: TypeMap[F[K]["type"]];
};
type KeyOf<T> = T extends Record<infer K, any> ? K & {} : never;
type TypeMap = {
string: string;
number: number;
boolean: boolean;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment