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>
在上面的代码里面, bar
和bars
的类型分别是:
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>
最后
后来我在网上搜索了下这个问题的解决方案,好像也是这么搞的,看来是我孤陋寡闻了,像个憨憨一样花了一晚上时间重构代码。