TypeScript中如何推断接收可辨识联合参数的函数返回值类型?
问题说明
你需要实现可辨识联合入参到对应返回值的自动类型推断,该需求不需要使用断言签名即可实现,断言签名主要用于布尔返回值的类型收窄场景,不适合做入参和返回值的类型映射。以下是两种可行方案:
方案1:函数重载(最直观,适合联合成员少的场景)
先修正你原有代码的小问题:调用时传入的type: 'license'为小写,和类型定义的'LICENSE'大写不匹配,先统一后编写重载:
// 假设已有两个业务类型定义 interface LicenseOptions { // 你的业务属性 } interface SiteIdOptions { // 你的业务属性 } const licenseTypeMap: Record<string, LicenseOptions> = { abc: { /* 业务配置 */ } } const siteIdMap: Record<number, SiteIdOptions> = { 12: { /* 业务配置 */ } } type DynamicReferenceType = | { type: 'LICENSE'; licenseName?: string; } | { type: 'SITE_ID'; siteId?: number; }; // 定义两个重载签名,对应不同入参的返回类型 export function getDynamicSchema(args: { type: 'LICENSE'; licenseName?: string }): LicenseOptions export function getDynamicSchema(args: { type: 'SITE_ID'; siteId?: number }): SiteIdOptions // 实现签名不需要对外暴露,保持原有逻辑即可 export function getDynamicSchema(args: DynamicReferenceType) { if (args.type === 'LICENSE') { // 可选字段加兜底逻辑,避免索引空值 return licenseTypeMap[args.licenseName ?? 'default']; } return siteIdMap[args.siteId ?? 0]; } // 调用时自动推断返回类型 const licenseSchema = getDynamicSchema({ type: 'LICENSE', licenseName: 'abc' }) // licenseSchema 类型自动推导为 LicenseOptions ✅ const siteSchema = getDynamicSchema({ type: 'SITE_ID', siteId: 12 }) // siteSchema 类型自动推导为 SiteIdOptions ✅
方案2:泛型+条件类型(适合联合成员多的场景,减少重复重载代码)
如果后续可辨识联合的类型会增加,可以用泛型做通用映射,不用每次加重载:
// 定义类型映射规则 type SchemaResult<T extends DynamicReferenceType['type']> = T extends 'LICENSE' ? LicenseOptions : T extends 'SITE_ID' ? SiteIdOptions : never // 泛型函数实现 export function getDynamicSchema<T extends DynamicReferenceType['type']>( args: Extract<DynamicReferenceType, { type: T }> ): SchemaResult<T> { if (args.type === 'LICENSE') { return licenseTypeMap[args.licenseName ?? 'default'] as SchemaResult<T>; } return siteIdMap[args.siteId ?? 0] as SchemaResult<T>; }
调用效果和重载方案完全一致。
关于断言签名的补充说明
你提到的断言签名(格式如function isType(val: unknown): val is X或者function assert(val: unknown): asserts val is X)仅适用于收窄变量类型的场景,无法实现入参属性和返回值类型的绑定映射,因此不适合该需求。
内容的提问来源于stack exchange,提问作者joshuaaron
相关产品推荐
相关产品推荐

