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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 02:39:03