• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Typescript中的对象多可能类型推导的解决办法

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

我们在渲染复杂对象,比如树组件的树对象,有嵌套对象/数组结构的时候,js的弱类型让我们一把梭,几乎没遇到什么问题(只是写的时候编译没问题把。233。。),结合TS后,对树状数据的递归访问会是一个问题:

比如数据源的数据声明为:

export interface VoiceSkillResponse {
  data: {
    isExistUpdate: number;
    isNewProduct: number;
    streamList: {
      streamId: string;
      streamName: string;
      intentList: {
        id: number;
        intent: string;
        isSelect: number;
      }[];
    }[];
  };
}

export interface VoiceSkill {
  streamId: string;
  streamName: string;
  intentList: Array<Intent>;
}

export interface Intent {
  id: number;
  intent: string;
  isSelect: number;
}

我们想根据这样的数据渲染一个树组件

  function renderNode(dataList: Array<VoiceSkill | Intent>) {
    dataList.map((v, k) => {
      if (v.intentList) {
        return (
          <Tree name={v.streamName} key={v.streamName}>
            {renderNode(v.intentList)}
          </Tree>
        );
      } 
      return <Tree name={v.intent} key={v.id} />;
    });
  }

| 的写法并不能让TS自动推导出v的类型和是否有访问属性,所以直接在编译层报错。

查阅TS文档:文档链接

我们可知至少两种解决方法:

as暴力

缺点,写很多as吧

  function renderNode(voiceSkillList: Array<VoiceSkill | Intent>) {
    voiceSkillList.map((v, k) => {
      if ((v as VoiceSkillList).intentList) {
        return (
          <Tree name={(v as VoiceSkillList).streamName} key={(v as VoiceSkillList).streamName}>
            {renderNode((v as VoiceSkillList).intentList)}
          </Tree>
        );
      }
      return <Tree name={(v as IntentList).intent} key={(v as IntentList).id} />;
    });
  }

写一个函数类型保护

个人认为目前最适合的方式?也是官方文档给的一种方式

  function isVoiceSkill(item: VoiceSkill | Intent): item is VoiceSkill {
    return (item as VoiceSkill).intentList !== undefined;
  }
  function renderNode(dataList: Array<VoiceSkill | Intent>) {
    dataList.map((v, k) => {
      if (isVoiceSkill(v)) {
        return (
          <Tree name={v.streamName} key={v.streamName}>
            {renderNode(v.intentList)}
          </Tree>
        );
      } else {
        return <Tree name={v.intent} key={v.id} />;
      }
    });
  }

函数重载

大佬说的一种,但是这样的话相当于参数在函数里还是any吧, 失去了类型检查...?重载主要是在调用的时候做类型检查用的,存疑。。。

  function renderNode(dataList: VoiceSkill[]): Array<React.ReactElement<any>>;
  function renderNode(dataList: Intent[]): Array<React.ReactElement<any>>;
  function renderNode(dataList: any[]): Array<React.ReactElement<any>> {
    return dataList.map((v, k) => {
      if (v.intentList) {
        return (
          <Tree name={v.streamName} key={v.streamName}>
            {renderNode(v.intentList)}
          </Tree>
        );
      }
      return <Tree name={v.intent} key={v.id} />;
    });
  }

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
【学习笔记】TypeScripttypeof操作符发布时间:2022-07-18
下一篇:
TypeScript获取类名发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap