拥抱TS(typescript)吧,面对疾风吧!!!
前言
自从搭建了VUE和TS版本后,已经深深的爱上了这个TS啦,有着Java这中强势类型声明,
还能起到注释的作用,当我们看到一函数后我们立马就能知道这个函数的用法,需要传什么值,
返回值是什么类型一目了然,对大型项目的维护性有很大的提升。
呜呜
面对疾风吧!!!
先来看下基础 哈哈
当然官网也是可以看的 下面是链接 https://www.tslang.cn/
基础总结
数据类型
- boolean 、number、string、null、 undefined、 Symbol
- undefined 和null 类型的数据只能被赋值undefined 和null, 但是这个类型是所有类型的子类型
- void 空类型
// undefined和null是所有类型子类型,都可以赋值 let num: Symbol = undefined; let num: number = undefined; // undefined类型, 只能给undefined let u: undefined = undefined; let n: null = null
其实基本类型都是 :+它的类型 来定义 是不是更加吊了
any和类型推断
// 在ts中,变量在声明的时候,如果没有定义其类型,会被识成默认类型 let str; str = 'I am strgting'; str = 1024; // 未定义类型,直接赋值 let num= 124; // 等同于 let num:number = 124, 在后面代码如果赋予num一个string会被报错
多个可能属性
//只能访问可能属性的共有属性 function getLength(param: string| number) { return param.length; } // 会报错, 因为 length不是 sting和number类型的共有属性 // 技巧--》 使用类型别名 type possibleType = string | number; function getLength(param: possibleType) { return param.length; }
接口的概念
- 在ts中,interface包括对行为的抽象,由类去实现(implements)
- 也包括对对象轮廓的描述
对象interface -》动态属性
必选参数和可选参数的类型是动态属性类型的子集,所有在动态属性类型设置的时候要设置上所有类型
interface userinfo { "memberId": number, "uName": string, "employeeId": string, "datetime": string, "platformList"?: Array<platform>, [propName: string]: string | number | Array<platform> | undefined }
只读属性的约束力
注意点: 只读属性的约束力在于第一次给对象赋值的时候,
而不是给属性赋值的时候 readonly和 const的区别: const是变量, readonly是属性
接口-》抽象方法的实现
export interface ISRequest { fetch(url: string, arg?: Object, callback?: Function): Promise<Object>; } export class SafeRequest implements ISRequest { public async fetch(url: string, arg, callback?: Function): Promise<Object> { return new Promise((resolve, reject) => { }) }
用接口表示数组
interface NumberArray {
[index: any]: number
}
let numArr: NumberArray = [1, 2, 3]
函数的类型
- 可选参数, 必须在必选参数后面
- 参数默认值
function buildName(firstName: string, lastName?: string) { }
类型断言
一共2种写法:尖括号<>和 as
:
let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length; let strLength: number = (someValue as string).length;
类型断言的用法如上,在需要断言的变量前加上 <Type> 即可。
类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的:
function toBoolean(something: string | number): boolean { return <boolean>something; }
枚举--》 数据的双向映射
枚举按照枚举成员的类型可归为两大类:数字枚举类型和字符串枚举类型;
// 枚举使用 enum 关键词来声明一个枚举,数字枚举和字符串枚举的区别 // 就是枚举成员是常数还是字符串;还是以十二生肖为例: // 01-数字枚举,声明了一个枚举成员均不带初始化器的枚举, // 该枚举的成员值从 0 开始,依次递增 enum NumChineseZodiac { rat, cattle, tiger, rabbit, dragon } // 02-字符串枚举 enum StrChineseZodiac { rat = 'rat', cattle = 'cattle', tiger = 'tiger', rabbit = 'rabbit', dragon = 'dragon' }
泛型: Generics
软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用。
支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性。
在 C#
和 Java
中,可以使用"泛型"来创建可复用的组件,并且组件可支持多种数据类型。这样便可以让用户根据自己的数据类型来使用组件
1. 泛型方法
在TypeScript里, 声明泛型方法 有以下两种方式:
function gen_func1<T>(arg: T): T { return arg; } // 或者 let gen_func2: <T>(arg: T) => T = function (arg) { return arg; }
调用方式也有两种:
gen_func1<string>('Hello world'); gen_func2('Hello world'); // 第二种调用方式可省略类型参数,因为编译器会根据传入参数来自动识别对应的类型。
2. 泛型与 Any
Ts
的特殊类型 Any
在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然:
// 方法一:带有any参数的方法 function any_func(arg: any): any { console.log(arg.length); return arg; } // 方法二:Array泛型方法 function array_func<T>(arg: Array<T>): Array<T> { console.log(arg.length); return arg; }
方法一,打印了 arg
参数的 length
属性。因为 any
可以代替任意类型,所以该方法在传入参数不是数组或者带有 length
属性对象时,会抛出异常。
方法二,定义了参数类型是 Array
的泛型类型,肯定会有 length
属性,所以不会抛出异常。
3. 泛型类型
泛型接口:
interface Generics_interface<T> { (arg: T): T; } function func_demo<T>(arg: T): T { return arg; } let func1: Generics_interface<number> = func_demo; func1(123); // 正确类型的实际参数 func1('123'); // 错误类型的实际参数
Vue in Typescript
三大利器
- vue-component-class
- 方法可以直接声明为类成员方法。
- 可以将计算属性声明为类属性访问器。
- 默认data被当作类属性
- data , render 和vue的生命周期的钩子直接是类成员的方法,保留这些命名,不要冲突
- 对于其他的配置项,例如prop、componets等传递给装饰器函数
- vue-property-decorator(依赖vue-component-class提供了更多了装饰器,代码更加显示 ) - @Emit - @Inject - @Prop - @Provide - @Watch - vuex-class(连接了vue和vuex)
从 vue2.5 之后,vue 对 ts 有更好的支持。比较喜欢下面这个写法
import { Component, Vue, Prop } from 'vue-property-decorator' @Component export default class Test extends Vue { @Prop({ type: Object }) private test: { value: string }
在这里列举几个常用的@Prop/@Watch/@Component
, 更多信息,详见官方文档
import { Component, Emit, Inject, Model, Prop, Provide, Vue, Watch } from 'vue-property-decorator' @Component export class MyComponent extends Vue { @Prop() propA: number = 1 @Prop({ default: 'default value' }) propB: string @Prop([String, Boolean]) propC: string | boolean @Prop({ type: null }) propD: any @Watch('child') onChildChanged(val: string, oldVal: string) { } }
上面的代码相当于:
export default { props: { checked: Boolean, propA: Number, propB: { type: String, default: 'default value' }, propC: [String, Boolean], propD: { type: null } } methods: { onChildChanged(val, oldVal) { } }, watch: { 'child': { handler: 'onChildChanged', immediate: false, deep: false } } }
这些就是一些简单的基础,还是需要多多练习,我也就举例了常用的那种,
我准备把我写的demo 上传到 GitHub上,
加油啊 骚年 哈哈