You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<template><divclass="home"><HelloWorldref="helloRef"
msg="Welcome to Your Vue.js + TypeScript App"
/></div></template><scriptlang="ts">import{Options,Vue}from"vue-class-component";importHelloWorldfrom"@/components/HelloWorld.vue";// @ is an alias to /src
@Options({components: {
HelloWorld,},})exportdefaultclassHomeextendsVue{print(){consthelloRef=this.$refs.helloRef;console.log("helloRef.msg: ",helloRef.msg);}mounted(){this.print();}}</script>
因为 this.$refs.helloRef 是未知的类型,会报错误提示:
做个类型断言即可:
print(){// const helloRef = this.$refs.helloRef;consthelloRef=this.$refs.helloRefasany;console.log("helloRef.msg: ",helloRef.msg);// helloRef.msg: Welcome to Your Vue.js + TypeScript App}
但是类型断言为 any 时是不好的,如果知道具体的类型,写具体的类型才好,不然引入 TypeScript 冒似没什么意义了。
9. 显式泛型
$('button') 是个 DOM 元素选择器,可是返回值的类型是运行时才能确定的,除了返回 any ,还可以
function$<TextendsHTMLElement>(id: string): T {return(document.getElementById(id))asT;}
// 不确定 input 的类型
// const input = $('input');
// Tell me what element it is.
const input = $<HTMLInputElement>('input');
console.log('input.value: ', input.value);
typeDeepReadonly<T>={readonly[PinkeyofT]: DeepReadonly<T[P]>;}consta={foo: {bar: 22}}constb=aasDeepReadonly<typeofa>b.foo.bar=33// Cannot assign to 'bar' because it is a read-only property.ts(2540)
用了一年时间的 TypeScript 了,项目中用到的技术是 Vue + TypeScript 的,深感中大型项目中 TypeScript 的必要性,特别是生命周期比较长的大型项目中更应该使用 TypeScript。
以下是我在工作中总结到的经常会用到的 TypeScript 技巧。
1. 注释
通过
/** */
形式的注释可以给 TS 类型做标记提示,编辑器会有更好的提示:如果想给某个属性添加注释说明或者友好提示,这种是很好的方式了。
2. 接口继承
和类一样,接口也可以相互继承。
这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
一个接口可以继承多个接口,创建出多个接口的合成接口。
3. interface & type
TypeScript 中定义类型的两种方式:接口(interface)和 类型别名(type alias)。
比如下面的 Interface 和 Type alias 的例子中,除了语法,意思是一样的:
Interface
Type alias
而且两者都可以扩展,但是语法有所不同。此外,请注意,接口和类型别名不是互斥的。接口可以扩展类型别名,反之亦然。
Interface extends interface
Type alias extends type alias
Interface extends type alias
Type alias extends interface
它们的差别可以看下面这图或者看 TypeScript: Interfaces vs Types。
所以檙想巧用 interface & type 还是不简单的。
如果不知道用什么,记住:能用 interface 实现,就用 interface , 如果不能就用 type 。
4. typeof
typeof
操作符可以用来获取一个变量或对象的类型。我们一般先定义类型,再使用:
有时候可以反过来:
当一个 interface 总有一个字面量初始值时,可以考虑这种写法以减少重复代码,至少减少了两行代码是吧,哈哈~
5. keyof
TypeScript 允许我们遍历某种类型的属性,并通过 keyof 操作符提取其属性的名称。
keyof 操作符是在 TypeScript 2.1 版本引入的,该操作符可以用于获取某种类型的所有键,其返回类型是联合类型。
keyof
与Object.keys
略有相似,只不过keyof
取interface
的键。写一个方法获取对象里面的属性值时,一般人可能会这么写
但是会提示报错
因为 object 里面没有事先声明的 key。
当然如果把
o: object
修改为o: any
就不会报错了,但是获取到的值就没有类型了,也变成 any 了。这时可以使用
keyof
来加强get
函数的类型功能,有兴趣的同学可以看看_.get
的type
标记以及实现6. 查找类型
当需要使用 addr 的类型时,除了把类型提出来
还可以
比如:
有些场合后者会让代码更整洁、易读。
7. 查找类型 + 泛型 + keyof
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
8. 类型断言
Vue 组件里面经常会用到 ref 来获取子组件的属性或者方法,但是往往都推断不出来有啥属性与方法,还会报错。
子组件:
父组件:
因为
this.$refs.helloRef
是未知的类型,会报错误提示:做个类型断言即可:
但是类型断言为
any
时是不好的,如果知道具体的类型,写具体的类型才好,不然引入 TypeScript 冒似没什么意义了。9. 显式泛型
$('button') 是个 DOM 元素选择器,可是返回值的类型是运行时才能确定的,除了返回 any ,还可以
函数泛型不一定非得自动推导出类型,有时候显式指定类型就好。
10. DeepReadonly
被
readonly
标记的属性只能在声明时或类的构造函数中赋值。之后将不可改(即只读属性),否则会抛出 TS2540 错误。
与 ES6 中的
const
很相似,但readonly
只能用在类(TS 里也可以是接口)中的属性上,相当于一个只有getter
没有setter
的属性的语法糖。下面实现一个深度声明
readonly
的类型:最后
大佬们,觉得有用就赞一个呗。
挺久没写原创技术文章了,作为 2021 第一篇原创技术文章,质量应该还可以吧 😅
参考文章:
The text was updated successfully, but these errors were encountered: