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
相关产品推荐
相关产品推荐

