首页 > 解决方案 > 推断采用可区分联合的函数的返回类型?

问题描述

我有一个函数,它接收一个使用可区分联合的对象,该联合基于该属性返回不同的结构。

虽然我可以编写一个断言isLicenseTypefn,但我想知道是否有一种方法可以根据提供给 fn 的类型参数(可能带有断言签名)来推断这一点?

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: DynamicReferenceType) {
    if (args.type === 'LICENSE') {
        return licenseTypeMap[args.licenseName];
    }
    return siteIdMap[args.siteId];
}

const schema = getDynamicSchema({ type: 'license', licenseName: 'abc' })
// schema is of LicenseOptions | SiteIdOptions

标签: typescript

解决方案


遇到了一个与我想得到的一样接近的解决方案。TS 无法缩小泛型参数的类型,因此需要进行一些转换,但是:

const licenseTypeMap: Record<string, LicenseOptions> = { abc: { ... } }
const siteIdMap: Record<number, SiteIdOptions> = { 12: { ... } }

type DynamicReferenceType =
    | { type: 'LICENSE'; licenseName?: string; }
    | { type: 'SITE_ID'; siteId?: number; };

type ReturnTypeLookup = {
    LICENSE: LicenseOptions;
    SITE_ID: SiteIdOptions;
};

type SchemaFor<T extends DynamicReferenceType> = ReturnTypeLookup[T['type']];

export function getDynamicComponent<T extends DynamicReferenceType>(args: T): SchemaFor<T> {
    if (args.type === 'LICENSE') {
        return licenseTypeMap[args.licenseName] as SchemaFor<T>;
    }
    return siteIdMap[args.siteId] as SchemaFor<T>;
}

推荐阅读