基于字符串数组创建TypeScript条件类型/接口的技术问询
解决TypeScript动态生成条件属性接口的问题
首先先帮你修正一个基础类型的拼写错误:你的storage类型里的字符串写成了'sorage',应该改成'storage',否则后续类型判断会出错:
export type storage = 'storage'; // 修正拼写
接下来解决你核心的问题:根据传入的tech数组动态生成接口,仅包含数组中存在的字符串对应的属性,不存在的设为never。你之前用tech.includes()的思路是对的,但这是运行时逻辑,TypeScript类型系统无法直接在类型层面使用运行时方法,我们需要用泛型+映射类型来实现编译时的条件判断。
完整解决方案代码
首先先整理你的基础类型和子接口类型(假设你已经定义了各子接口firestoreType等):
// firebase/types/tech-types.ts export type firestore = 'firestore'; export type auth = 'auth'; export type database = 'database'; export type storage = 'storage'; export type Tech = firestore | auth | database | storage; // 定义字符串到对应子接口的映射,方便后续类型查找 export type TechToHookMap = { firestore: firestoreType; // 你的firestore钩子子接口 auth: authType; // 你的auth钩子子接口 database: databaseType; // 你的database钩子子接口 storage: storageType; // 你的storage钩子子接口 };
然后重构CreateFirebaseContext函数,使用泛型捕获传入数组的具体元素类型,再用映射类型生成动态接口:
// firebase/context/CreateFirebaseContext.ts import type { Tech, TechToHookMap } from '../types/tech-types'; // 假设你已经定义了firebaseConfigType type firebaseConfigType = { /* 你的Firebase配置类型 */ }; export const CreateFirebaseContext = <T extends Tech>( firebaseConfig: firebaseConfigType, tech: T[] ) => { // 动态生成条件接口:如果T包含当前属性名,使用对应子接口,否则设为never type HooksCollectionType = { [K in keyof TechToHookMap]: T extends K ? TechToHookMap[K] : never; }; // 后续可以基于HooksCollectionType创建上下文、返回钩子等逻辑 // 比如创建上下文: const FirebaseContext = createContext<HooksCollectionType | null>(null); // 示例返回内容 return { FirebaseContext, // 其他需要导出的内容 }; };
效果说明
当你调用函数时传入不同的tech数组,TypeScript会自动推导对应的接口类型:
- 比如调用
CreateFirebaseContext(config, ['firestore', 'auth']),生成的HooksCollectionType会是:{ firestore: firestoreType; auth: authType; database: never; storage: never; } - 如果只传入
['database'],则:{ firestore: never; auth: never; database: databaseType; storage: never; }
代码组织优化建议
作为TypeScript新手,给你几个规范方面的小建议:
- 类型文件职责单一:把基础类型、类型映射统一放在
firebase/types/目录下的单独文件中(比如tech-types.ts),不要分散在多个文件里,方便维护和复用。 - 避免函数内部定义复杂类型:像
HooksCollectionType这种可以复用的类型,建议提到函数外部顶层,或者放到类型文件中。 - 类型命名规范:TypeScript中类型名建议使用大驼峰(比如
Tech而不是tech,HooksCollectionType而不是hooksCollectionType),和变量名区分开,提高可读性。 - 注释补充:对于复杂的类型逻辑(比如映射类型的条件判断),可以加简单注释说明作用,方便后续自己或他人理解。
内容的提问来源于stack exchange,提问作者ohaleks
相关产品推荐
相关产品推荐

