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

如何指定接口特定类型?TypeScript类型收窄问题求助

TypeScript类型收窄问题:区分EmptyElement与Annonce/Annonce2

问题场景与错误

我有一个Carousel组件,有数据时渲染带数据的卡片,无数据时渲染骨架屏。当前遇到TypeScript类型错误:

Type 'EmptyElement' is not assignable to type 'Annonce | Annonce2'.
Type 'EmptyElement' is missing the following properties from type 'Annonce2': ....

业务代码

if (biens.length) {
    return (
      <Carousel
        data={data}
        renderElement={(bien) => {
          if (bien.id === 'isEmptyMock') return <SkeletonCardDernierBien isEmptyMock />;

          return (
            <Component
              key={bien.id}
              annonce={bien}
            />
          );
        }}
      />
    );
  }

接口定义

import { Annonce } from '.../Annonce/Annonce';
import { Annonce2 } from '.../Annonce2';

export type EmptyElement = {
  id: string;
};

export interface MyProps {
  biens: (Annonce | Annonce2 | EmptyElement)[];
}

需求:让TypeScript识别当if (bien.id === 'isEmptyMock')时,bien的类型为EmptyElement,其余情况为Annonce或Annonce2。

解决方案

1. 修改EmptyElement的id为字面量类型

TypeScript需要明确的类型区分特征,把EmptyElement的id从泛型string改为固定字面量,让类型系统能直接通过id值区分类型:

export type EmptyElement = {
  id: 'isEmptyMock'; // 固定为特定值,而非任意string
};

2. 约束Annonce/Annonce2的id范围(可选)

如果能修改Annonce和Annonce2的接口,可以给它们的id添加约束,明确排除'isEmptyMock':

// 修改Annonce接口
interface Annonce {
  id: Exclude<string, 'isEmptyMock'>;
  // 原有其他属性...
}

// 修改Annonce2接口
interface Annonce2 {
  id: Exclude<string, 'isEmptyMock'>;
  // 原有其他属性...
}

3. 自定义类型守卫函数

如果没法修改原有接口,写一个类型守卫函数来帮TypeScript做类型判断:

// 定义类型守卫
function isEmptyElement(bien: Annonce | Annonce2 | EmptyElement): bien is EmptyElement {
  return bien.id === 'isEmptyMock';
}

// 在renderElement中使用
renderElement={(bien) => {
  if (isEmptyElement(bien)) return <SkeletonCardDernierBien isEmptyMock />;

  // 此时TypeScript会自动推断bien为Annonce | Annonce2
  return (
    <Component
      key={bien.id}
      annonce={bien}
    />
  );
}}

4. 临时方案:类型断言(不推荐)

如果以上方法都无法实施,可临时用类型断言跳过检查,但这会失去TypeScript的类型保护,不建议长期使用:

return (
  <Component
    key={bien.id}
    annonce={bien as Annonce | Annonce2}
  />
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:05:43