TypeScript自定义类型中可选属性被标记为必填的问题排查
问题背景
我定义了以下类型:
class CachedLegalEntityNameCheckResult { constructor( readonly code: number, readonly status: 'verified' | 'unverified', readonly message?: string | ListOfErrors ) {} } class BusinessInfo<TPersonInfo, TCompany = Company<TPersonInfo>> { legalEntityName?: string businessName?: string business?: Business<TPersonInfo, TCompany> businessAddress?: Address businessPhone?: string serviceDescription?: string businessCodes?: BusinessCodes numberOfEmployees?: number rangeOfEmployees?: RangeOfEmployees isLegalEntityNameVerified?: boolean legalEntityNameDetails?: CachedLegalEntityNameCheckResult }
基于上述类型,我创建了新类型:
type BusinessInfoPage = Omit< Required<BusinessInfo<UnsafePersonInfo>>, 'business' | 'legalEntityNameCheckDetails' > & { business: FrontBusiness } & { isGovt: boolean } & { legalEntityNameCheckDetails?: CachedLegalEntityNameCheckResult }
问题是:新类型BusinessInfoPage中的legalEntityNameCheckDetails属性被标记为必填,但我需要将其设为可选。我尝试过Pick等多种方法,但该属性要么是必填,要么完全不存在。请问我哪里出错了?该如何修复?
错误原因
核心问题是属性名拼写错误:
- 原
BusinessInfo类中的目标属性名为legalEntityNameDetails,但你在Omit操作中写的是legalEntityNameCheckDetails——这个属性在原类型中根本不存在,所以Omit对它完全无效。 - 由于没正确移除原类型中被
Required转为必填的legalEntityNameDetails,当前BusinessInfoPage中同时存在两个属性:- 必填的
legalEntityNameDetails(来自未被处理的Required<BusinessInfo<...>>) - 你新增的可选
legalEntityNameCheckDetails
你大概率是混淆了属性名,误以为自己处理的是legalEntityNameCheckDetails,但实际需要调整的是原属性legalEntityNameDetails,或是想替换为新属性名。
- 必填的
修复方案
根据你的需求分两种情况处理:
情况1:保留原属性名,改为可选
如果你只是想把原属性从改回可选,只需在Omit中移除legalEntityNameDetails,再以可选形式加回:
type BusinessInfoPage = Omit< Required<BusinessInfo<UnsafePersonInfo>>, 'business' | 'legalEntityNameDetails' > & { business: FrontBusiness } & { isGovt: boolean } & { legalEntityNameDetails?: CachedLegalEntityNameCheckResult }
情况2:替换为新属性名(可选)
如果你确实要改用legalEntityNameCheckDetails作为属性名,需确保Omit掉原属性,再添加新的可选属性:
type BusinessInfoPage = Omit< Required<BusinessInfo<UnsafePersonInfo>>, 'business' | 'legalEntityNameDetails' > & { business: FrontBusiness } & { isGovt: boolean } & { legalEntityNameCheckDetails?: CachedLegalEntityNameCheckResult }
验证效果
调整后:
- 原
Required生成的必填属性legalEntityNameDetails被移除 - 目标属性(无论是原属性名还是新属性名)会被标记为可选
- 其他属性保持
Required后的必填状态,自定义的business和isGovt属性也能正常生效
内容的提问来源于stack exchange,提问作者Igor Shmukler
相关产品推荐
相关产品推荐

