后端程序员写TypeScript,被言中...

写在前面

作为一个写php和go的后端程序员,虽然也写过js、微信小程序、uniapp,但是对于ts还是比较陌生的,曾经就有一个同事,嘲讽我写不来ts,最终还是被他言中了。甚至有同事说 周围写ts的,没有一个不骂的

在这里插入图片描述

接触ts

最近公司的项目使用vue-element-plus-admin,ts技术栈,前面的简单功能,写写表格啥的,复制一下demo和同事的代码,其实还好,有个功能要用Echart搞拆线图。本来想着这个功能也不难,以前又不是没写过,对着官网一顿ctrl c ctrl v, 然后 npm run dev运行得好好的,图表显示完全正常。最后想git commit死活过不了npm run ts:check,报错像小作文一样长,一个文件,90多个error,给我整懵了。。。

src/views/Monitor/Realtime.vue:47:78 - error TS18046: 'value' is of type'unknown'.

47

src/views/Monitor/Realtime.vue:51:31 - error TS2339: Property 'energy' does not exist on type'{}'.

51

src/views/Monitor/Realtime.vue:54:78 - error TS18046: 'value' is of type'unknown'.

54

src/views/Monitor/Realtime.vue:58:24 - error TS18046: 'value' is of type'unknown'.

58

src/views/Monitor/Realtime.vue:65:7 - error TS6133: 'getLatestDataList' is declared but its value is never read.

65

src/views/Monitor/Realtime.vue:18:11 - error TS2322: Type '{ [x: string]: unknown; dataset?: { mainType?: "dataset" | undefined; seriesLayoutBy?: SeriesLayoutBy | undefined; sourceHeader?: OptionSourceHeader | undefined; ... 8 more ...; dimensions?: (string | ... 1 more ... | undefined)[] | undefined; } | { ...; }[] | undefined; ... 41 more ...; colorLayer?: (string | ... 3...' is not assignable to type'EChartsOption'.

18

最痛苦的是,npm run ts:check一次要好久,简直浪费时间。

与AI的失败尝试

看到这一堆报错,咱立马将它复制到ds里面,然后ds就一顿输出给了答案,其中像error TS6133这样的我自己都能解决,对于error TS18046这样的ds解决起来也很简单,主要是error TS2322不管是ds还是gpt,都不行,只会在错误的路上越来越远。。。

ds和gpt给的错误答案,如下:

// 尝试1
const option = {} as EChartsOption;

// 尝试2
const option = ref<EChartsOption>({});

// 尝试3
const option = reactive<EChartsOption>({});

// 尝试4
option.value = {
      ...option.value,
      legend: {
        data: res.data.legend
      },
      xAxis: [
        {
          type: 'category',
          boundaryGap: false,
          data: res.data.category
        }
      ],
      series: res.data.series.map((item: any) => ({
        name: item.title,
        type: 'line',
        data: item.data
      })) as SeriesOption[]
    }

// 尝试5
option.value = Object.assign({}, option.value, {
      legend: {
        data: res.data.legend,
      },
      xAxis: [
        {
          type: "category",
          boundaryGap: false,
          data: res.data.category,
        },
      ],
      series: res.data.series.map((item: any) => ({
        name: item.title,
        type: "line",
        data: item.data,
      })) as SeriesOption[],
    });
  });

// 尝试6
const seriesData: SeriesOption[] = res.data.series.map((item: any) => ({
  name: item.title,
  type: "line",
  data: item.data
}));

// 尝试7
option.value = {
  ...option.value,
  series: seriesData
};

// 尝试8
function isEChartsOption(obj: any): obj is EChartsOption {
  return true; // 这里应该写实际判断逻辑
}

查源码

各种调试都不行之后,就开始看源码,通过对比,发现的一点规律,用官方demo, 就可以通过npm run ts:check检查,但是只要想动态赋值,就会报错。但不可能不用后端接口数据。
在这里插入图片描述

问同事

查了源码也不行,只剩下最后一个办法,就是问前端同事,结果他看了一眼,轻描淡写地说: “用any吧。”

const option = ref<any>({
  backgroundColor: '#ffffff',
  title: {
    text: ''
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: []
  },
  grid: {
    left: '3%',
    right: '3%',
    bottom: '6%',
    containLabel: false
  },
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: []
    }
  ],
  yAxis: [
    {
      type: 'value',
      name: '(数量)',
      nameLocation: 'end'
    }
  ],
  series: [] as SeriesOption[]
})

简直不可思议,就如此简单,困扰我几天的问题一下子解决了。any就像ts的"免检通行证",让ts:check直接过了。

后续

为此我特意查了一下any, 结果如下

类型安全的"逃生舱"

在ts的世界里,any类型就像一个特殊的逃生舱门。当你在严格的类型检查中感到窒息时,它为你提供了一条"生路"。这个看似简单的类型,实际上是TypeScript类型系统中最为复杂和争议的存在。

any的起源可以追溯到TypeScript最早期的设计阶段。当时团队面临一个关键决策:如何让JavaScript开发者平滑过渡到TypeScript?答案是any——它允许开发者逐步采用类型检查,而不是全有或全无的选择。这个设计决策虽然看似简单,却极大地降低了TypeScript的采用门槛,成为它成功的关键因素之一。

any的典型使用场景

在实际开发中,any有几个合理的应用场景:

  1. 渐进式迁移:将JavaScript项目迁移到TypeScript时,any可以作为临时解决方案
  2. 处理动态内容:如第三方API响应、用户输入等无法预知结构的数据
  3. 快速原型开发:在验证概念阶段,避免被类型系统拖慢速度
  4. 与无类型库交互:当使用纯JavaScript编写的库时

以ECharts为例,这个强大的图表库在TypeScript中使用时经常会遇到any的身影。考虑以下场景:

typescript

复制

const chart = echarts.init(document.getElementById('chart'));
const option: any = {
  // 复杂的配置项
  series: [{
    type: 'pie',
    data: [
      { value: 1048, name: 'Search Engine' },
      { value: 735, name: 'Direct' }
    ]
  }]
};
chart.setOption(option);

在这个例子中,ECharts的配置对象极为复杂且嵌套深,完整定义其类型可能得不偿失。此时使用any可以快速实现功能,但同时也埋下了隐患。

真相:EChartsOption 的类型设计问题

深入查了一下,发现 ECharts 的 EChartsOption 类型定义得非常严格,但 ECharts 运行时却非常宽松。

    1. ECharts 的 option 允许很多动态字段,但 EChartsOption 没有完全涵盖这些可能性。
    1. TS 类型定义基于文档,而 ECharts 运行时可以接受更多参数
    1. 部分字段使用了 unknown 类型,导致 TS 无法自动推导兼容性

换句话说,ECharts 本身能正常跑,但 TypeScript 认为它“不够安全” 。这就是 npm run dev 没问题,npm run ts:check 却报错的原因。

综上

在这里插入图片描述

大家都说any大法好,能用就用,千万不要自己卷自己。

– end –

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值