前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript 在 Vue2 中的类型声明问题

TypeScript 在 Vue2 中的类型声明问题

原创
作者头像
一介程序员
发布2022-02-25 11:16:38
4.4K0
发布2022-02-25 11:16:38
举报

0x00 hello world

最近在一个新项目中,尝试了vue2+typescript的组合,碰到一个问题,在data属性中,我怎么声明一个变量的类型。

代码语言:html
复制
<script lang="ts">
import Vue from "vue";

interface Foo {
  a: string;
  b: string;
}

export default Vue.extend({
  data: function () {
    return {
      bar: {}, //怎么优雅的告诉编译器他的类型
      bars: [],
    };
  },
});
</script>

在上面的代码里面, barbars的类型分别是:

1.PNG
1.PNG

0x01 应急方案

代码语言:html
复制
<script lang="ts">
import Vue from "vue";

interface Foo {
  a: string;
  b: string;
}

export default Vue.extend({
  data: function () {
    return {
      bar: {}, //怎么优雅的告诉编译器他的类型
      bars: [],
    };
  },
  methods: {
    abc: function () {
      (this.bar as Foo).a = "";
      (this.bars as Foo[]).push({ a: "", b: "" });
    },
  },
});
</script>

一开始,我能想到的方法就是简单粗暴的强制类型转换,但是随着项目中代码越来越多,我发现这一点也不优雅,非常容易出错。我必须得想个更好更优雅的方法。

0x02 数组类型

如果变量是一个数组类型,很容易就想到这么写:

代码语言:html
复制
<script lang="ts">
import Vue from "vue";

interface Foo {
  a: string;
  b: string;
}

export default Vue.extend({
  data: function () {
    return {
      bar: {}, //怎么优雅的告诉编译器他的类型
      bars: new Array<Foo>(),
    };
  },
});
</script>

事实上,这确实很好,很优雅,可是非数据类型就没办法了。

0x03 非数组类型

代码语言:html
复制
<script lang="ts">
import Vue from "vue";

interface Foo {
  a: string;
  b: string;
}

export default Vue.extend({
  data: function () {
    return {
      bar: undefined as Foo | undefined, 
      bars: new Array<Foo>(),
    };
  },
  methods: {
    abc: function () {
      if (this.bar) {
        this.bar.a = "";
      }
    },
  },
});
</script>

这样,只要在函数里面,把所有用到的变量都放在一个if里面,保证他不是undefined就可以正常使用了。

0x04 统一写法

代码语言:html
复制
<script lang="ts">
import Vue from "vue";

interface Foo {
  a: string;
  b: string;
}

export default Vue.extend({
  data: function () {
    return {
      bar: undefined as Foo | undefined, 
      bars: [] as Foo[],
    };
  },
  methods: {
    abc: function () {
      if (this.bar) {
        this.bar.a = "";
      }
    },
  },
});
</script>

数组类型也通过[] as Foo[]的写法,使得数组和非数组在写法上统一了,更优雅了一点。

0x05 类型扩展

还有个常见的问题,一般来说,Foo类型是接口那边定义的类型,定义了接口返回的数据类型,但是在编码过程中,对接口返回的数据进行处理后,需要保存处理后的信息到变量中,如何在不修改Foo类型的定义的前提下,对Foo类型进行扩展呢?

代码语言:html
复制
<script lang="ts">
import Vue from "vue";

interface Foo {
  a: string;
  b: string;
}

interface FooEx extends Foo {
  ab: string;//a+b
}

export default Vue.extend({
  data: function () {
    return {
      bar: undefined as FooEx | undefined,
      bars: [] as FooEx[],
    };
  },
  methods: {
    abc: function () {
      if (this.bar) {
        const foo = { a: "", b: "" }; //假设这个数据是接口返回的
        const foos = [foo]; //假设这个数据是接口返回的

        this.bar = { ...foo, ab: foo.a + foo.b };
        this.bars = foos.map((item) => {
          return { ...item, ab: item.a + item.b };
        });
      }
    },
  },
});
</script>

最后

后来我在网上搜索了下这个问题的解决方案,好像也是这么搞的,看来是我孤陋寡闻了,像个憨憨一样花了一晚上时间重构代码。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 hello world
  • 0x01 应急方案
  • 0x02 数组类型
  • 0x03 非数组类型
  • 0x04 统一写法
  • 0x05 类型扩展
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档