TypeScript报错TS(7061):映射类型无法声明属性的解决咨询
问题:TypeScript映射类型与普通属性混合触发TS(7061)错误
在定义DashboardData类型时,result.rejected和result.returned中同时使用映射类型(如[key in RejectionType])和meta属性,触发错误TS(7061): A mapped type may not declare properties or methods。
模拟数据结构
const dashboard: DashboardData = { result: { rejected: { meta: { total_count: randFloat(), }, external_validation_failed: { count: randFloat(), percentage: randFloat() }, missing_capability: { count: randFloat(), percentage: randFloat() }, payment_request_cancelled: { count: randFloat(), percentage: randFloat() }, validation_schema_failed: { count: randFloat(), percentage: randFloat() } }, returned: { meta: { total_count: randFloat() }, payment_returned: { count: randFloat(), percentage: randFloat() } } } };
原类型定义(触发错误)
export interface VirtualAccount { "currency_code": string; "currency_name": string; "number": number; "balance": number; } export interface Rejection { "count": number; "percentage": number; } export interface Returns { "count": number; "percentage": number; } export type RejectionType = | 'external_validation_failed' | 'missing_capability' | 'payment_request_cancelled' | 'validation_schema_failed'; export type ReturnsType = 'payment_returned'; export interface VirtualAccountData { "virtual_accounts": VirtualAccount[]; } export interface DashboardData { "result": { "rejected": { [key in RejectionType]: Rejection; "meta": { "total_count": number; }, }; "returned": { [key in ReturnsType]: Returns; "meta": { "total_count": number; }, }; }; }
错误原因
TypeScript中,映射类型是一种动态生成属性集合的语法,它本质上是独立的类型构造器。编译器不允许在同一个对象类型字面量中,同时使用映射类型语法和直接声明普通属性(如meta),二者语法规则冲突,因此触发TS(7061)错误。
解决方法
通过**交叉类型(&)**将映射类型和包含meta属性的类型合并,这是TypeScript实现“映射类型+固定属性”的标准方式。
修改后的类型定义
export interface VirtualAccount { "currency_code": string; "currency_name": string; "number": number; "balance": number; } export interface Rejection { "count": number; "percentage": number; } export interface Returns { "count": number; "percentage": number; } export type RejectionType = | 'external_validation_failed' | 'missing_capability' | 'payment_request_cancelled' | 'validation_schema_failed'; export type ReturnsType = 'payment_returned'; export interface VirtualAccountData { "virtual_accounts": VirtualAccount[]; } // 先定义映射类型部分 type RejectedItems = { [key in RejectionType]: Rejection; }; type ReturnedItems = { [key in ReturnsType]: Returns; }; // 用交叉类型合并固定的meta属性 export interface DashboardData { "result": { "rejected": RejectedItems & { "meta": { "total_count": number; }; }; "returned": ReturnedItems & { "meta": { "total_count": number; }; }; }; }
也可以直接在DashboardData内使用交叉类型,无需单独定义中间类型:
export interface DashboardData { "result": { "rejected": { [key in RejectionType]: Rejection } & { "meta": { "total_count": number }; }; "returned": { [key in ReturnsType]: Returns } & { "meta": { "total_count": number }; }; }; }
修改后,rejected和returned类型既包含映射生成的所有状态属性,也包含固定的meta属性,完全匹配模拟数据结构,同时解决了TS(7061)错误。
内容的提问来源于stack exchange,提问作者user19625670
相关产品推荐
相关产品推荐

