Skip to content

TypeScript: Infer prompt() return type object shape from question objects聽#463

Description

@karlhorky

Hi, first of all, thanks for enquirer 馃憤 Nice library!

Currently, enquirer has a return type of Promise<object>:

import { prompt } from 'enquirer';

const questions = [
  {
    type: 'input',
    name: 'name',
    message: 'What is your name?',
  },
  {
    type: 'input',
    name: 'username',
    message: 'What is your username?',
  },
];
const result = await prompt(questions);
   // ^? const result: object

Playground

It would be great if prompt() would infer the types from the questions object:

import { prompt } from 'enquirer';

const questions = [
  {
    type: 'input',
    name: 'name',
    message: 'What is your name?',
  },
  {
    type: 'input',
    name: 'username',
    message: 'What is your username?',
  },
];
const result = await prompt(questions);
   // ^? const result: { name: string; username: string; }

Alternatives considered

Pass in generics, this works today, but requires careful synchronization of the type and the questions - easy to make mistakes:

import { prompt } from 'enquirer';

type Result = {
  name: string;
  username: string;
};

const questions = [
  {
    type: 'input',
    name: 'name',
    message: 'What is your name?',
  },
  {
    type: 'input',
    name: 'username',
    message: 'What is your username?',
  },
];
const result = await prompt<Result>(questions);
   // ^? const result: { name: string; username: string; }

Activity

  1. changed the title [-]Infer object shape from question objects[/-] [+]TypeScript: Infer `prompt()` return type object shape from question objects[/+] on Jun 24, 2024
  2. cubxx commented on Aug 7, 2025

    @cubxx
    type Question = Exclude<Parameters<typeof prompt>[0], Function | unknown[]>;
    type Answers<Qs extends Question[], As = {}> = Qs extends [
      infer L extends Question & { name: string },
      ...infer R extends Question[],
    ]
      ? Answers<R, As & { [K in L['name']]: L['initial'] }>
      : As;
    const typedPrompt = <const T extends Question[]>(questions: T) =>
      prompt<Answers<T>>(questions);
    
    const answers = await typedPrompt([
      {
        name: 'projectName',
        type: 'input',
        message: 'Project name:',
        initial: 'my-project',
        result: (v) => v.trim(),
      },
      {
        name: 'useTypeScript',
        type: 'confirm',
        message: 'Use TypeScript?',
        initial: false,
      },
    ]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions