You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于字符串数组创建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新手,给你几个规范方面的小建议:

  1. 类型文件职责单一:把基础类型、类型映射统一放在firebase/types/目录下的单独文件中(比如tech-types.ts),不要分散在多个文件里,方便维护和复用。
  2. 避免函数内部定义复杂类型:像HooksCollectionType这种可以复用的类型,建议提到函数外部顶层,或者放到类型文件中。
  3. 类型命名规范:TypeScript中类型名建议使用大驼峰(比如Tech而不是tech,HooksCollectionType而不是hooksCollectionType),和变量名区分开,提高可读性。
  4. 注释补充:对于复杂的类型逻辑(比如映射类型的条件判断),可以加简单注释说明作用,方便后续自己或他人理解。

内容的提问来源于stack exchange,提问作者ohaleks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 19:48:11