Created
April 25, 2022 16:31
-
-
Save ProdigySim/73913e526d12719476582238a3fce2aa to your computer and use it in GitHub Desktop.
First pass at enabling inferred names and types on output answers object for enquirer library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/module-type-overrides/enquirer.d.ts b/module-type-overrides/enquirer.d.ts | |
index 27dee4e90..5172f0c5c 100644 | |
--- a/module-type-overrides/enquirer.d.ts | |
+++ b/module-type-overrides/enquirer.d.ts | |
@@ -67,6 +67,21 @@ declare namespace Enquirer { | |
...args: ConstructorParameters<new (...args: any) => T> | |
) => T; | |
+ export function prompt<Name extends string, Q extends prompt.Question>( | |
+ question: Q & { name: Name } | |
+ ): Promise<Record<Name, AnswerTypeForQuestion<Q>>>; | |
+ export function prompt<Q extends prompt.Question & { name?: undefined }>( | |
+ question: Q | |
+ ): Promise<AnswerTypeForQuestion<Q>>; | |
+ export function prompt<Name extends string>( | |
+ question: prompt.CustomQuestion & { name: Name } | |
+ ): Promise<SpecificAnswers<Name>>; | |
+ export function prompt< | |
+ T extends string, | |
+ Name extends string, | |
+ Qs extends ReadonlyArray<prompt.Question & { type: T } & { name: Name }> | |
+ >(questions: [...Qs]): Promise<AnswersForNamedQuestions<[...Qs]>>; | |
+ | |
export function prompt(question: prompt.Question): Promise<Answers>; | |
export function prompt(questionFn: (this: Enquirer) => prompt.Question): Promise<Answers>; | |
export function prompt( | |
@@ -81,6 +96,9 @@ declare namespace Enquirer { | |
export namespace prompt { | |
export function on(type: types.PromptType, handler: (p: Prompt<any>) => void): void; | |
+ export type NamedQuestion<Name extends string> = Extract<Question, { name: string }> & { | |
+ name: Name; | |
+ }; | |
export type Question = | |
| AutoCompleteQuestion | |
| BasicAuthQuestion | |
@@ -102,7 +120,9 @@ declare namespace Enquirer { | |
| TextQuestion | |
| ToggleQuestion; | |
- export type AutoCompleteQuestion = AutoCompleteQuestion.Single | AutoCompleteQuestion.Multiple; | |
+ export type AutoCompleteQuestion = | |
+ | AutoCompleteQuestion.Single<any> | |
+ | AutoCompleteQuestion.Multiple<any>; | |
export type BasicAuthQuestion = { | |
type: 'basicauth'; | |
} & BasicAuthQuestionOptions; | |
@@ -135,25 +155,37 @@ declare namespace Enquirer { | |
} & internalTypes.CommonQuestion<V, A>; | |
export namespace AutoCompleteQuestion { | |
- export type Options = { | |
+ export type Options<T extends SelectQuestion.Choice[]> = { | |
type?: 'autocomplete'; | |
- choices: SelectQuestion.Choice[]; | |
+ choices: T; | |
suggest?: ( | |
input: string, | |
choices: SelectQuestion.ChoiceOptions[] | |
) => SelectQuestion.ChoiceOptions[] | Promise<SelectQuestion.ChoiceOptions[]>; | |
} & types.QuestionBase; | |
- export type SingleOptions = { multiple?: false } & Type & | |
- Options & | |
+ export type SingleOptions<T extends SelectQuestion.Choice[]> = { | |
+ multiple?: false; | |
+ } & Options<T> & | |
types.Initializer<string | number, string> & | |
types.Formatter<string, string>; | |
- export type MultipleOptions = { multiple: true } & Type & | |
- Options & | |
+ export type MultipleOptions<T extends SelectQuestion.Choice[]> = { | |
+ multiple: true; | |
+ } & Options<T> & | |
types.Initializer<string | number, string[]> & | |
types.Formatter<string, string[]>; | |
- export type Single = { type: 'autocomplete' } & SingleOptions; | |
- export type Multiple = { type: 'autocomplete' } & MultipleOptions; | |
+ export type Single<T extends SelectQuestion.Choice[]> = { | |
+ type: 'autocomplete'; | |
+ } & SingleOptions<T>; | |
+ export type SingleAnswer<Q extends SingleOptions<any>> = SelectQuestion.ChoiceValue< | |
+ Q['choices'][number] | |
+ >; | |
+ export type Multiple<T extends SelectQuestion.Choice[]> = { | |
+ type: 'autocomplete'; | |
+ } & MultipleOptions<T>; | |
+ export type MultipleAnswer<Q extends MultipleOptions<any>> = Array< | |
+ SelectQuestion.ChoiceValue<Q['choices'][number]> | |
+ >; | |
} | |
export type BasicAuthQuestionOptions = { | |
@@ -335,6 +367,19 @@ declare namespace Enquirer { | |
*/ | |
value?: string; | |
}; | |
+ type GetChoiceValue<T extends string | ChoiceOptions | Promise<string | ChoiceOptions>> = | |
+ T extends string | |
+ ? T | |
+ : T extends Promise<infer U> | |
+ ? U extends { value: infer V } | |
+ ? infer V | |
+ : U | |
+ : T extends { value: infer U } | |
+ ? U | |
+ : never; | |
+ export type ChoiceValue<T extends Choice> = T extends () => infer U | |
+ ? GetChoiceValue<U> | |
+ : GetChoiceValue<Exclude<T, Function>>; | |
} | |
export type SnippetQuestionOptions = { | |
@@ -644,6 +689,32 @@ declare namespace Enquirer { | |
} | |
export type Answers = Record<string, types.Answer>; | |
+ export type SpecificAnswers<Names extends string> = Record<Names, types.Answer>; | |
+ | |
+ type QuestionAnswersMap = { | |
+ input: string; | |
+ numeral: number; | |
+ invisible: string; | |
+ password: string; | |
+ list: string[]; | |
+ }; | |
+ export type AnswerTypeForQuestion<Q extends prompt.Question> = | |
+ Q extends prompt.AutoCompleteQuestion.Single<any> | |
+ ? prompt.AutoCompleteQuestion.SingleAnswer<Q> | |
+ : Q extends prompt.AutoCompleteQuestion.Multiple<any> | |
+ ? prompt.AutoCompleteQuestion.MultipleAnswer<Q> | |
+ : Q['type'] extends keyof QuestionAnswersMap | |
+ ? QuestionAnswersMap[Q['type']] | |
+ : types.Answer; | |
+ export type AnswerForQuestion< | |
+ Name extends string, | |
+ Q extends prompt.Question & { name: Name } | |
+ > = Record<Name, AnswerTypeForQuestion<Q>>; | |
+ export type AnswersForNamedQuestions< | |
+ Qs extends ReadonlyArray<prompt.Question & { name: string }> | |
+ > = { | |
+ [K in Qs[number] as K['name']]: AnswerTypeForQuestion<K>; | |
+ }; | |
export class State { | |
type: string; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment