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

如何在TypeScript中基于类型参数实现接口的条件属性?

解决方案

要实现你需要的效果,核心是让items属性仅在泛型参数T满足T extends IdData时存在,而非通过undefined或可选属性来处理。可以通过以下两种方式实现:

方法一:交叉类型 + 条件类型

interface IdData {
  id: string;
}

type WizardContext<T = undefined> = {
  step: number;
} & (T extends IdData ? { items: T[] } : {});

使用验证

  • 默认泛型(T=undefined):无需声明items,编译正常
    const defaultCtx: WizardContext = { step: 1 }; // 合法
    
  • 传入满足IdData的泛型:必须声明items,类型严格匹配T[]
    type User = IdData & { name: string };
    const userCtx: WizardContext<User> = {
      step: 2,
      items: [{ id: "1", name: "Alice" }] // 必填且类型正确
    };
    // 省略items会直接报错,符合预期
    
  • 传入不满足IdData的泛型:无需声明items
    const stringCtx: WizardContext<string> = { step: 3 }; // 合法
    

方法二:条件接口选择

通过拆分基础接口和带items的接口,用条件类型选择最终结构:

interface IdData {
  id: string;
}

interface WizardBase {
  step: number;
}

interface WizardWithItems<T extends IdData> extends WizardBase {
  items: T[];
}

type WizardContext<T = undefined> = T extends IdData ? WizardWithItems<T> : WizardBase;

该方案效果与方法一完全一致,写法更偏向接口继承风格。

原方案问题分析

你之前的接口定义中,items是强制存在的属性,仅类型随T变化(T[]或undefined)。这导致即使T不满足条件,也必须显式赋值items: undefined才能通过编译。而上述两种方案仅在T符合要求时才将items加入类型结构,彻底解决了这个问题。

同时,items在需要时是必填的非undefined类型,使用时不会出现“对象可能为undefined”的警告;不需要时该属性不存在,也不会有访问undefined的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:07:25