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

如何根据属性类型在TypeScript中扩展接口?

在TypeScript中根据联合类型属性值动态扩展接口类型

完全可行,你可以通过**区分联合类型(Discriminated Union)**实现这个需求——以variant作为区分字段,为每个变体值绑定对应的HTML元素属性类型,让TypeScript能根据variant的值自动推断出该场景下允许的所有属性。

具体实现步骤

1. 提取公共属性

先把所有variant共享的属性抽离成单独的类型,避免重复定义:

// 保留原有ParentProps基础结构,抽离公共自定义属性
type TypographyCommonProps = ParentProps & {
  color?: keyof Theme["colors"];
  spacing?: Theme["spacing"];
  wrap?: boolean;
};

2. 为每个variant定义专属类型

针对每个variant值,将公共属性与对应HTML元素的内置属性合并:

// 每个变体绑定对应的JSX元素原生属性
type TypographyH1Props = TypographyCommonProps & {
  variant: "h1";
} & JSX.IntrinsicElements["h1"];

type TypographyH2Props = TypographyCommonProps & {
  variant: "h2";
} & JSX.IntrinsicElements["h2"];

type TypographyH3Props = TypographyCommonProps & {
  variant: "h3";
} & JSX.IntrinsicElements["h3"];

type TypographyPProps = TypographyCommonProps & {
  variant: "p";
} & JSX.IntrinsicElements["p"];

type TypographySpanProps = TypographyCommonProps & {
  variant: "span";
} & JSX.IntrinsicElements["span"];

3. 合并为最终的联合类型

把所有变体类型组合成一个联合类型,这就是最终的TypographyProps:

type TypographyProps = 
  | TypographyH1Props 
  | TypographyH2Props 
  | TypographyH3Props 
  | TypographyPProps 
  | TypographySpanProps;

4. 处理variant可选的场景

如果需要允许variant不传入(即可选),可以新增一个默认变体,比如默认绑定span的属性:

// 未指定variant时,默认使用span的原生属性
type TypographyDefaultProps = TypographyCommonProps & {
  variant?: never;
} & JSX.IntrinsicElements["span"];

// 更新联合类型,加入默认场景
type TypographyProps = 
  | TypographyH1Props 
  | TypographyH2Props 
  | TypographyH3Props 
  | TypographyPProps 
  | TypographySpanProps
  | TypographyDefaultProps;

使用示例

在组件中使用这个类型时,TypeScript会根据variant的值自动校验属性是否合法:

const Typography = (props: TypographyProps) => {
  const { variant, color, spacing, wrap, ...elementProps } = props;
  // 未指定variant时默认渲染span
  const Tag = variant || "span";
  return (
    <Tag 
      {...elementProps} 
      style={{
        color,
        margin: spacing,
        whiteSpace: wrap ? "normal" : "nowrap"
      }}
    />
  );
};

// 正确用法:variant为h2时,可传入h2专属属性(如align)
<Typography variant="h2" align="center" color="primary" />;

// 错误用法:variant为p时,传入h2的align属性会触发TypeScript报错
<Typography variant="p" align="center" />;

核心原理

区分联合类型通过一个共同的"区分字段"(这里是variant)让TypeScript精准识别当前类型分支,从而自动启用对应分支的属性约束。相比单一接口,这种方式能实现"不同变体对应不同属性集合"的动态约束效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:57:54