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

TypeScript类型映射报错:Type 'Key'无法索引类型求助

解决TypeScript类型映射中的「Type 'Key' cannot be used to index type」错误

在将给定的components和paths TypeScript类型转换为更易管理的PostPaths结构时,类型映射代码出现「Type 'Key' cannot be used to index type」错误,尽管实际使用该类型定义变量时功能正常。

相关定义代码如下:

interface components {
  schemas: {
    CheckPriceBooking: {
      EventId: number;
    };
    CheckPriceResult: {
      TotalPriceIncVat: number;
    };
    PostBooking: {
      EventId: number;
      Whatever: number;
    };
    BookingCreated: {
      BookingId: number;
    };
    ErrorResponse: {
      Message?: string | null;
      ErrorMessages?: string[] | null;
    };
  };
}

interface paths {
  '/v1/Booking/CheckPrice': {
    post: {
      requestBody?: {
        content: {
          'text/json': components['schemas']['CheckPriceBooking'];
          'application/*+json': components['schemas']['CheckPriceBooking'];
        }
      };
      responses: {
        200: {
          content: {
            'application/json': components['schemas']['CheckPriceResult'];
            'text/json': components['schemas']['CheckPriceResult'];
          };
        };
        400: {
          content: {
            "text/json": components["schemas"]["ErrorResponse"];
          };
        };
      }
    };
    get: {
      requestBody?: {
        content: {
          'text/json': components['schemas']['CheckPriceBooking'];
          'application/*+json': components['schemas']['CheckPriceBooking'];
        }
      };
      responses: {
        200: {
          content: {
            'application/json': components['schemas']['CheckPriceResult'];
            'text/json': components['schemas']['CheckPriceResult'];
          };
        };
      }
    }
  };
  "/v1/Booking": {
    post: {
      requestBody?: {
        content: {
          "text/json": components["schemas"]["PostBooking"];
          "application/*+json": components["schemas"]["PostBooking"];
        };
      };
      responses: {
        201: {
          content: {
            "text/json": components["schemas"]["BookingCreated"];
          };
        };
      };
    };
  };
}

报错的PostPaths类型定义:

type PostPaths<T extends paths = paths> = {
  [K in keyof T as T[K] extends { post: unknown } ? K : never]: {
    request: Required<T[K]['post']>['requestBody']['content']['text/json']; // <- 报错位置
  }
};

// 实际使用正常
const body: PostPaths['/v1/Booking']['request'] = {
  EventId: 1,
  Whatever: 2
};

解决方案

错误根源在于TypeScript在条件映射时,仅通过T[K] extends { post: unknown }判断存在post属性,但无法确定post对象内一定包含requestBody、content及text/json层级结构,导致索引访问时类型推断不充分。

可以通过细化类型约束让TypeScript明确这些属性的存在,修改后的PostPaths类型如下:

type PostPaths<T extends paths = paths> = {
  [K in keyof T as T[K] extends { 
    post: { requestBody?: { content: { 'text/json': unknown } } } 
  } ? K : never]: {
    request: Required<T[K]['post']>['requestBody']['content']['text/json'];
  }
};

或者通过提取工具类型提升可读性和复用性:

// 提取post请求的request body类型
type PostRequestBody<T> = T extends { 
  post: { 
    requestBody?: { 
      content: { 'text/json': infer RequestType } 
    } 
  } 
} ? RequestType : never;

type PostPaths<T extends paths = paths> = {
  [K in keyof T as T[K] extends { post: unknown } ? K : never]: {
    request: PostRequestBody<T[K]>;
  }
};

这两种方式都能让TypeScript准确推断出requestBody及后续层级的类型,消除索引错误,同时保留原有的类型功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:02:02