【vue系列】 TypeScript 初体验

615 阅读4分钟

历史回顾:

背景

进入到新团队,需要快速了解新业务,在了解新业务的同时,项目就是郑重其中。新团队统一使用TS开发,我之前只看过一遍官网,缺乏实战经验。虽然假期之前在公司已经磕磕绊绊开发了几个页面,但是TS运用的并不熟练。工欲善其事必先利其器,刚好趁着假期把TS从头到尾在过一遍。

说实话,学习 TypeScript 也是大势所趋,刚发布的 Vue3 就是 TS 重写的,并且 Vue3 也推荐大家使用 TypeScript 开发。既然如此,我们就开始 TypeScript 的初体验吧。

编译环境准备

准备 TypeScript 的编译环境,全局安装 typescriptts-nodetsc *.ts 会将 *.ts 编译成 *.js。如果我们想将编译后的 *.js 在node环境下执行,可以使用 ts-node *.tstsc -init 生成 tsconfig.json 文件。

npm install -g typescript ts-node

静态类型

// 基础静态类型
const count: number = 1024;
const myCat: string = ‘heibao’

// 对象静态类型
const heiBao: {
    name: string,
    age: number
} = {
    name: '小黑',
    age: 3
} 

// 数组类型
const arrs: string [] = ['数组内部元素都是string类型'];

// 类类型
class Cat{}
const heiBao: Cat = new Cat()

// 函数表达式
const fnc: ()=>string = () => {
    return '这是一个函数,返回值必须是字符串'
}

// 函数定义和调用
function add({one, two}: {one: number, two: number}):number {
     return one + two
}
const total = add({one: 1, two: 2})

数组类型注解的方法

数组的常见定义方式,以及类型别名、class别名不同的写法。

const numberArr: number[] = [1,2,3];
const stringArr: string[] = ['a', 'b', 'c'];

// 数组中元素多种类型
const arr: (number | string | undefined)[] = [1, 'string', undefined]

// 数组中元素是对象类型
const xiaohei: {name: string, age: number}[] = [
    {
        name: 'xiaohei',
        age: 3
    },
    {
        name: 'xiaojiugui',
        age: 1.5
    }
]


// 数组 type类型别名 
type Cat = {
    name: string, // 注意用的是逗号间隔
    age: number
}

const cats: Cat[] = [
    {
        name: 'xiaohei',
        age: 3
    },
    {
        name: 'xiaojiugui',
        age: 1.5
    }
]

// 数组 class别名
class Cat2 {
    name: string;
    age: number; // 注意用的是分号
}
const cats: Cat2[] = [
    {
        name: 'xiaohei',
        age: 3
    },
    {
        name: 'xiaojiugui',
        age: 1.5
    }
];

元组的使用和类型约束

// 一元元组
const heihei: [string, string, number] = ['heibao', 'cat', 3]

// 二元元组
const xiaohei: [string, string, number][] = [
    ['heibao', 'cat', 3],
    ['heibao', 'cat', 3],
    ['heibao', 'cat', 3]
]

接口 interface

接口主要做开发环境中的一些约束,不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口,用 implements 关键字来实现。

interface Cat {
    name: string;
    age?: number; // ?代表可选值
    say(): string; // 方法,必须要有字符串类型的返回值
    [propname:string]: any; // 扩展属性可以加任意key value
}

class Xiaohei implements Cat {
    name: 'jiugui';
    say() {
        return "喵呜~"
    };
    eat() {
        console.log('猫粮 猫罐头')
    };
}

联合类型和类型包含(类型守护)

interface Cat() {
    say() {}
}

interface Dog() {
    jump() {}
}

// as
function judgeWho(animal: Cat | Dog) {
    if(animal.say) {
        (animal as Cat).say()
    } else {
        (animal as Dog).jump()
    }
}

// in
function judgeWho2(animal: Cat | Dog) {
    if('say' in animal) {
        (animal as Cat).say()
    } else {
        (animal as Dog).jump()
    }
}

// typeof
function add(first: string | number, second: string | number) {
    if(typeof first === 'string' || typeof second === 'string') {
        return `${first}${second}`
    }
    return first + second
}


// instanceof 用在类上
class NumberObj {
   count: number; 
}

function addObj(first: object | NumberObj, second: object | NumberObj) {
    if(first instanceof NumberObj && second instanceof NumberObj) {
        return first.count + second.count
    }
    return 0;
}

// as类型实战
props: {
    callback: {
      required: true,
      type: Function as PropType<(nums: number) => void>
    },
    message: {
      type: String,
      required: true
    }
}

枚举类型

eunm 就是map对象的形式,可以进行反查。

泛型

泛指的类型,支持类型推断。

// 泛型在数组的两种使用方式
function myFun<T>(params: Array<T>) {
    return params;
}
myFun<string>(['123', '456'])

function myFun2<T>(params: T[]) {
    return params;
}
myFun2<string>(['123', '456'])

// 泛型应用场景,改写
// 多种类型传参和多种类型的返回值
class SelectCat {
    constructor(private girls: string[] | number[]){}
    getCat(index: number): string | number {
        return this.girls[index];
    }
}

const SelectCat = new SelectCat(['英短', '美短', '暹罗'])
console.log(selectGirl.getCat(1))

// 以下用泛型改写
class SelectCat2<T> {
    constructor(private girls: T[]){}
    getGirl(index: number): T {
        return this.girls[index];
    }
}

const SelectCat2 = new SelectCat2(['英短', '美短', '暹罗'])
console.log(SelectCat2.getCat(1))

小结

复习了一遍 TypeScript,总体上还是比较简单的,基本上过一遍就可以满足基本开发了,不过像 泛型 的概念第一次接触确实优点懵,需要理解理解,在项目多实战才能更好的运用。

参考