【问题标题】:Infer return type of function that takes a discriminated union?推断采用可区分联合的函数的返回类型?
【发布时间】:2021-10-05 12:27:00
【问题描述】:

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

虽然我可以写一个断言isLicenseType fn,但我想知道是否有一种方法可以根据提供给 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


    【解决方案1】:

    遇到了一个与我想得到的一样接近的解决方案。 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>;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-28
      • 2021-02-21
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2018-12-20
      相关资源
      最近更新 更多