bombshell-dev / clack

Effortlessly build beautiful command-line apps
https://clack.cc
5.25k stars 88 forks source link

feat: improve group `types` for readability #105

Closed Mist3rBru closed 1 year ago

Mist3rBru commented 1 year ago

This PR aims to improve type readability of group function, introducing Prettify type, which unwrap all the complex intern types to a top level one.

type Prettify<T> = {
    [P in keyof T]: T[P]
} & {}

It adds Prettify to group return type:

//before 
declare function group<T>(
    prompts: PromptGroup<T>,
    opts?: PromptGroupOptions<T>
): Promise<PromptGroupAwaitedReturn<T>>;

const result = await group({ foo: () => text({} as any) });
//    ^? const result: PromptGroupAwaitedReturn<{ foo: string | symbol }>

// after
declare function group<T>(
    prompts: PromptGroup<T>,
    opts?: PromptGroupOptions<T>
): Promise<Prettify<PromptGroupAwaitedReturn<T>>>;

const result = await group({ foo: () => text({} as any) });
//    ^? const result: { foo: string }

And to results param, I also took e the freedom to Omit the current key:

// before
type PromptGroup<T> = {
    [P in keyof T]: (opts: {
            results: Partial<PromptGroupAwaitedReturn<T>>;
    }) => void | Promise<T[P] | void>;
};

interface PromptGroupOptions<T> {
    onCancel?: (opts: { results: Partial<PromptGroupAwaitedReturn<T>> }) => void;
}

group({
    foo: () => text({} as any),
    bar: ({ results }) => text({} as any)
    //      ^? results: Partial<PromptGroupAwaitedReturn<{ foo: string | symbol; bar: unknown }>>
}, {
  onCancel: ({ results }) => {}
  //           ^? results: Partial<PromptGroupAwaitedReturn<{ foo: string | symbol; bar: unknown }>>
})

// after
type PromptGroup<T> = {
    [P in keyof T]: (opts: {
            results: Prettify<Partial<PromptGroupAwaitedReturn<Omit<T, P>>>>;
    }) => void | Promise<T[P] | void>;
};

interface PromptGroupOptions<T> {
    onCancel?: (opts: { results: Prettify<Partial<PromptGroupAwaitedReturn<T>>> }) => void;
}

group({
    foo: () => text({} as any),
    bar: ({ results }) => text({} as any)
    //      ^? results: { foo?: string | undefined }
}, {
  onCancel: ({ results }) => {}
  //           ^? results: { foo?: string | undefined, bar?: unknown }
})
changeset-bot[bot] commented 1 year ago

⚠️ No Changeset found

Latest commit: f2bf6155a4f186503f832ba0ea69d6e49b73bfc1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

cpreston321 commented 1 year ago

Hey @Mist3rBru, this is flat out nice!

Good work 👏🏼

ulken commented 1 year ago

No objections on my part either 👍 I'm gonna go ahead and merge this.