TypeScript如何定义引用数组项键值的筛选类型?
实现TypeScript中基于应用名称推导Secrets类型的方案
要实现根据App的name值从Project的apps数组中筛选对应类型并推导Secrets配置类型,核心是利用TypeScript的Extract工具类型和条件类型来精准筛选联合类型。以下是具体实现步骤:
1. 基础类型定义
先明确枚举、应用、项目的核心类型结构,确保每个App的name为字面量类型(用于区分不同应用):
// 项目Key枚举 enum ProjectKey { Example1 = "example1", Example2 = "example2" } // 定义各应用专属的Secrets类型 type App1Secrets = "username" | "password" | "optionalSecret"; type App2Secrets = "apiKey" | "endpoint"; type App3Secrets = "dbUrl"; // 应用联合类型,每个应用的name为字面量,绑定对应Secrets type Example1Apps = | { name: "app1"; secrets: App1Secrets } | { name: "app3"; secrets: App3Secrets }; type Example2Apps = | { name: "app2"; secrets: App2Secrets }; // 项目类型,关联专属的应用数组 type Project<Apps extends { name: string; secrets: string }> = { apps: Apps[]; // 可添加其他项目配置字段(如projectName、env等) }; // 所有项目的强类型映射 type AllProjects = { [ProjectKey.Example1]: Project<Example1Apps>; [ProjectKey.Example2]: Project<Example2Apps>; };
2. 类型工具函数实现
创建一个通用类型工具,用于从指定项目中提取对应名称应用的Secrets类型:
// 类型工具:从目标项目的apps数组中,筛选指定name的App并返回其Secrets类型 type GetAppSecrets< TargetProject extends Project<any>, TargetAppName extends string > = Extract<TargetProject["apps"][number], { name: TargetAppName }>["secrets"];
3. 使用示例
通过类型工具即可精准推导目标应用的Secrets类型:
// 获取Example1项目中app1的Secrets类型 type Example1App1Secrets = GetAppSecrets<AllProjects[ProjectKey.Example1], "app1">; // 推导结果:"username" | "password" | "optionalSecret" // 获取Example2项目中app2的Secrets类型 type Example2App2Secrets = GetAppSecrets<AllProjects[ProjectKey.Example2], "app2">; // 推导结果:"apiKey" | "endpoint"
补充说明
你期望的AllProjects[ProjectKey.Example1]["apps"][{ name: "app1" }]["secrets"]写法不符合TypeScript的索引规则——索引仅支持字符串、数字或Symbol类型,无法直接用对象字面量作为索引。上述通过GetAppSecrets类型工具的方案,是在保持apps数组结构的前提下,实现强类型推导的最优方式。
内容的提问来源于stack exchange,提问作者Josh M.
相关产品推荐
相关产品推荐

