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

使用泛型作为类型索引时TypeScript类型错误排查

强类型项目-应用-配置结构的类型错误排查

我想要创建一个类型结构,用于定义一组项目(如软件项目),每个项目包含一个或多个应用(如API、UI),每个应用可拥有强类型配置属性(secrets、环境变量)。但编写代码时出现以下类型错误:

Type 'TProjectKey' cannot be used to index type 'AllProjects'.
Type "apps" cannot be used to index type 'AllProjects[TProjectKey]'.
Type 'TAppType' cannot be used to index type 'AllProjects[TProjectKey]["apps"]'.
Type "secrets" cannot be used to index type 'AllProjects[TProjectKey]["apps"][TAppType]'.

我的目标是让配置对象实现强类型化:必填secret必须提供,可选secret可省略,同时希望无必填secret时相关配置项非必填。以下是我的尝试代码:

enum ProjectKey {
    Project1 = "projectOne",
    Project2 = "projectTwo",
}

enum AppType {
  API = "api",
  UI = "ui",
}

type Project<TProjectKey extends ProjectKey> = {
    key: TProjectKey;
    name: string;
    apps: Partial<{ [ TAppType in AppType ]: App<TAppType> }>;
}

type App<TAppKey extends AppType = AppType, TSecretKeys extends string = never> = {
    type: TAppKey;
    name: string;
    secrets: Secrets<TSecretKeys>;
}

type OptionalSecret = {
  defaultValue?: string;
};

type RequiredSecret = {
  required: true;
};

type Secret = OptionalSecret | RequiredSecret;

type Secrets<TSecretKeys extends string> = { [ K in TSecretKeys ]: Secret };

// Define a project.

const Project1: Project<ProjectKey.Project1> = {
    key: ProjectKey.Project1,
    name: "Project One",
    apps: {
        api: {
            type: AppType.API,
            name: "Project One API",
            secrets: {
                "SECRET_1": { required: true },
                "SECRET_2": { defaultValue: "abc" },
            },
        },
    },
};


// Roll up all projects into a mapped type.

type AllProjects = {
    [ ProjectKey.Project1 ]: typeof Project1;
};

// Define a configuration which describes all of the projects.

type Config = {
    [ TProjectKey in ProjectKey ]?: ProjectConfigProps<TProjectKey>;
};

type ProjectConfigProps<TProjectKey extends ProjectKey> = {
  apps: { [ TAppType in AppType ]: AppConfigProps<TProjectKey, TAppType> };
};

// Error occurs below.
type AppConfigProps<TProjectKey extends ProjectKey, TAppType extends AppType> = {
  secrets?: {
    [ TSecretKey in keyof AllProjects[ TProjectKey ][ "apps" ][ TAppType ][ "secrets" ] ]:
        AllProjects[ TProjectKey ][ "apps" ][ TAppType ][ "secrets" ][ TSecretKey ] typeof RequiredSecret
        ? { value: string }
        : { value?: string }
    };
};


// Usage -- the goal is to strongly type the configuration object so that each required secret must be provided, and each optional one may or may not.

const config: Config = {
    "projectOne": {
        apps: {
            api: {
                secrets: {
                    SECRET_1: { value: "some_required_value" },
                    SECRET_2: { value: "some_default_value" },
                    // Or SECRET_2 can just not be supplied.
                }
            },

            // How to make this not required if there are no required secrets?
            ui: {
                secrets: undefined, 
            },
        },
    },
};

内容的提问来源于stack exchange,提问作者Josh M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:24:55