vue3 setup script+Typescript实战用法(一)——type、interface、泛型

3,690 阅读3分钟

不讲基础,讲深入。

type

用type来声明数据

已有的基础类型是string,number,array等等,但是这些类型不满足你的要求的话,你可以自己声明一种myType的类型。比如一个你想要一个变量可以是number或者是string或者是某个具体值,除了直接声明,还可以用type来声明。

和数学中的换元法差不多。

type myType = number | string | '127.0.0.1'
type goodsData = {
    name: string
    price: number
}

type扩展

如果你请求商品数据时,会用到goodsData的类型,但是请求宠物数据时,只是多了一个雌雄的数据类型,那么定义animalsData类型的时候,代码就会重复写了,此时只要扩展这个数据类型就行了

type animalsData = goodsData & {
    sex: string
}

//等价于,代码更加简洁
type animalsData = {
    name: string
    price: number
    sex: string
}

interface

在ts中,我感觉interface和泛型是用得比较多的。

interface是用来定义对象和class类的。

interface Inter {
    name: string
    say(): void
}

var obj: Inter
obj = {
    name: 'x',
    say() {
        console.log(1)
    },
}

class Father implements Inter {
    name: string
    constructor(name: string) {
        this.name = name
    }

    say() {
        console.log(1)
    }
}

extends继承

和type一样,interface也可以进行继承另一个已经定义好的类型

interface Father {
    name: string
    age: number
}

interface son extends Father {
    friends: string[]
}

type和interface之间的不同

既然type能做到,为什么还要interface?

因为interface也有type不能做到的。

声明方式不同

type是跟“=”赋值,而interface是直接声明。

type myType = {
    name: string
}

interface myType {
    name: string
}

重复声明

interface是可以重复声明,并且最终是合并在一起的,而type只能声明一次。

当你拿到一个类型,想扩展类型,里面的数据类型太复杂,并且你又不能随随便便替换成其他数据类型时,你就可以使用interface对该数据类型做一个扩展。在vue中,经常用的就是,添加一个全局属性,然后再用interface扩展数据类型,使ts编译通过。

interface ComponentCustomProperties {
    $store: Store<State>
}

interface ComponentCustomProperties {
    $filters: filters
}

什么时候用type?什么时候用interface?

type可以声明任意类型,但是在类和对象方面,可扩展性较差。interface只能声明类和对象,其他基础类型不能声明。interface更像是type在类和对象上的一个升级版。

所以我建议:基础数据类型用type,类和对象用interface

泛型

泛型也是我认为在ts中用得比较多的,不过之前我只用到了一层嵌套,直到我看到二层,甚至三层嵌套,有点小懵,然后赶紧深入学习一下。

在不明确输入的是什么数据类型,就可以用泛型

function fn<T>(params: T) {
    return params
}
fn<number>(1)
fn<string>('xxx')

但是这只是最简单的写法,如果你请求一个数据,goods和lists,返回的数据都有code,meta,data。只是如果是goods,data里面就是一个具体的对象,如果是lists,data里面就是一个animal的对象数组。

那么写数据类型的时候,可以定义goods类型和lists类型。但是有很多地方都是相同的,只有一部分是不同的,这样就会写很多重复的代码,这时就可以把相同的地方抽离出来,不同的地方传入一个泛型代替。

实际上相当于数学中的提取公因数。

import axios from 'axios'

//这里传入了一个泛型,表示数据是不确定的
interface Data<T> {
    code: number
    meta: string
    data: T
}

interface goods {
    price: number
    name: string
}

interface animal extends goods {
    sex: string
}

type lists = animal[]

//axios也支持传入一个泛型来得到数据结构
async function fn() {
    const result1 = await axios.get<Data<goods>>('http')
    console.log(result1.data.data.price)

    const result2 = await axios.get<Data<lists>>('http')
    console.log(result2.data.data[0].sex)
}

这样在请求数据,如果知道自己返回的是什么数据结构,就可以传入一个指定的泛型,然后就会有很好的代码提示了。