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

从多接口类型联合中推断单个接口的TypeScript优化问询

产品许可证查询系统类型推断优化方案

问题背景

我正在开发一款产品许可证查询系统,用户可搜索旗下各产品的许可证列表,查看许可证详情及对应授权功能(不同许可证的功能存在差异)。

目前已实现一套方案:定义了包含通用信息的BaseLicense接口,以及继承该接口的SingleLicense接口;LicenseType为Lic1至Lic5的接口联合类型,当前可将Result类型传入LicenseData的泛型参数实现功能,但希望优化——根据选中单个许可证时获取的字符串变量,自动推断features属性对应的LicenseType接口。

现有实现代码

// licenses.d.ts
export const product = { Lic1: "" };

type StringTupple = [string, string];
type StringNumberTupple = [string, number];
type LicenseType = Lic1 | Lic2 | Lic3 | Lic4 | Lic5;
type Product = typeof product;
type Result = Extract<LicenseType, { type: `${keyof Product}` }>;

interface BaseLicense {
    Created: Date;
    Id: string;
    ProductId: number;
    ProductName: string;
}

interface SingleLicense<T> extends BaseLicense {
    Data: LicenseData<T>;
    WorkOrder: string;
}

interface LicenseData<T> extends SingleLicense<T> {
    Features: T;
    LicenseId: string;
}

interface Lic1 { 
    readonly type: "Lic1";
    Endpoints: StringTupple[];
}

interface Lic2 { 
    readonly type: "Lic2";
    Ips: string;
    System: { Users: number, Computers: number };
}

interface Lic3 { 
    readonly type: "Lic3";
    Legacy: string;
    LegacyMode: number;
    Demo: number;
    Filter: { Max: number, Pooling: number, Databases: number };
}

interface Lic4 { 
    readonly type: "Lic4";
    State: number;
    Clients: number;
    Users: number;
}

interface Lic5 { 
    readonly type: "Lic5";
    Items: StringTupple[];
    Values: StringTupple[];
}

优化需求

  • LicenseType保持联合类型不变
  • 能够根据选中许可证时获取的字符串变量,自动推断features属性对应的具体Lic接口类型

优化方案

1. 修正循环引用问题

原代码中LicenseData<T>继承SingleLicense<T>,而SingleLicense<T>又包含Data: LicenseData<T>,造成类型循环引用。调整结构,让LicenseData直接继承BaseLicense:

interface SingleLicense<K extends keyof LicenseTypeMap> extends BaseLicense {
    Data: LicenseData<K>;
    WorkOrder: string;
}

interface LicenseData<K extends keyof LicenseTypeMap> extends BaseLicense {
    Features: LicenseTypeMap[K];
    LicenseId: string;
}

2. 创建许可证类型映射

建立字符串类型到具体许可证接口的映射,让TypeScript能通过字符串索引自动推断类型:

type LicenseTypeMap = {
    "Lic1": Lic1;
    "Lic2": Lic2;
    "Lic3": Lic3;
    "Lic4": Lic4;
    "Lic5": Lic5;
};

3. 基于字符串变量的自动推断

通过泛型约束,接收许可证类型字符串,自动关联对应的Features类型:

// 示例函数:根据许可证类型字符串获取详情
function fetchLicenseDetails<K extends keyof LicenseTypeMap>(licenseType: K): SingleLicense<K> {
    // 模拟数据获取逻辑
    return {} as SingleLicense<K>;
}

// 使用示例
const selectedType = "Lic2";
const licenseDetails = fetchLicenseDetails(selectedType);
// licenseDetails.Data.Features 会自动推断为Lic2类型,可直接访问Ips、System等属性

4. 保留LicenseType联合类型

原LicenseType联合类型可继续用于需要涵盖所有许可证类型的场景:

type LicenseType = Lic1 | Lic2 | Lic3 | Lic4 | Lic5;
// 等价于:type LicenseType = LicenseTypeMap[keyof LicenseTypeMap];

通过以上调整,既保留了原有的联合类型设计,又实现了基于字符串变量的自动类型推断,提升了类型安全性和开发体验。

内容的提问来源于stack exchange,提问作者JustBarnt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:15:44