TypeScript:从Inquirer问题数组中获取正确的答案类型
如何从Inquirer问题数组推断答案对象类型?
我来帮你解决这个问题!你已经实现了单个问题的答案类型推断,现在只需要利用TypeScript的**键重映射(Key Remapping)**特性,就能把问题数组转换成对应的答案对象类型了。
完整解决方案代码
import { Question } from 'inquirer'; // 单个问题的答案类型推断(你已有的代码) type AnswerType<Q extends { type: string }> = Q extends { type: 'input' } ? string : Q extends { type: 'number' } ? number : Q extends { type: 'password' } ? string : Q extends { type: 'confirm' } ? boolean : never; // 修改后的答案对象类型推断 export type PromptAnswersFor<T extends ReadonlyArray<Question>> = { // 关键:用键重映射遍历每个问题,关联name和对应的AnswerType [Q in T[number] as Q['name']]: AnswerType<Q>; }; // 测试你的示例 const prompts = [ { type: 'input', name: 'foo', message: 'Enter a string', }, { type: 'number', name: 'bar', message: 'Enter a number', }, ] as const; type Answers = PromptAnswersFor<typeof prompts>; // 此时 Answers 的类型为 { foo: string; bar: number },完全符合你的需求!
关键知识点解释
键重映射的作用
你原来的写法[key in T[number]['name']]: string只能拿到所有name的联合类型作为键,但无法关联每个键对应的原始问题类型,所以值类型只能固定为string。而
[Q in T[number] as Q['name']]的写法会:- 遍历数组
T中的每一个问题元素Q - 用
Q['name']作为对象的键 - 同时利用
AnswerType<Q>根据当前问题的type推断出对应的值类型
- 遍历数组
as const的必要性
你的prompts数组后面加了as const,这会让TypeScript把数组元素的type和name推断为字面量类型(比如'input'、'foo'),而不是宽泛的string类型,这样AnswerType才能准确匹配对应的类型分支。
扩展说明
如果之后需要支持更多Inquirer的问题类型(比如list、rawlist等),只需要在AnswerType里添加对应的分支即可,比如:
type AnswerType<Q extends { type: string }> = Q extends { type: 'input' } ? string : Q extends { type: 'number' } ? number : Q extends { type: 'password' } ? string : Q extends { type: 'confirm' } ? boolean : Q extends { type: 'list' | 'rawlist' } ? string : // 列表类型返回选中的选项值 never;
内容的提问来源于stack exchange,提问作者DeX3
相关产品推荐
相关产品推荐

