likes
comments
collection
share

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

作者站长头像
站长
· 阅读数 18

大家好,我是苏先生,一名热爱钻研、乐于分享的前端工程师,跟大家分享一句我很喜欢的话:人活着,其实就是一种心态,你若觉得快乐,幸福便无处不在

github与好文

前言

最近在开发新的h5项目,也没来得及更新TypeScript类型体操系列

就简单分享下在这个项目中使用到的TypeScript的地方

在Pinia中使用

基础的数据类型是可以被自动推导出来的,比如下边这种

const useStore = defineStore('test', {
    state() {
        return {
            loading: false,
        };
    },
    actions: {
        updateLoading(loading: boolean) {
            this.loading = loading;
        },
    },
    persist: {
        paths: ['answers'],
    },
});

对于loading属性而言,其类型是string也好,number也好,boolean也罢,都是可以在页面中直接被推断使用的

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

但如果你和我一样,需要定义一个由对象组成的数组类型时,就会有问题了,如下,我需要存一个answers数据,它记录了每一个步骤下用户的选中信息

const useStore = defineStore('test', {
    state() {
        return {
            answers: [],
        };
    },
    actions: {
        updateLoading(answer: { id: string; name: string }) {
            this.answers.push(answer);
        },
    },
});

此时this.answers.push(answer)会报错

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

为此,我们需要显示的为其指定类型,对于Pinia的defineStore函数,它提供了对应的泛型参数。如下,利用第二个泛型参数指定answers的具体类型即可

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

但此时又会产生新的问题,即actions.updateLoading丢失

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

为此,还需要为updateLoading显示的指定类型

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

在上述的例子中的第三个泛型参数,是笔者设置到公共的辅助类型,如下

export type AnyObj = {
    [o: string]: any;
};

在vueuse中使用

相信大家一般都不会直接使用useFetch,用它的createFetch自己简单封一层才是较为明智的选择

createFetch({
    baseUrl: 'https://www.jianshu.com',
    options: {
        async beforeFetch({ options }) {
            options.headers = {
                ...options.headers,
                ...
            };

            return { options };
        },
    },
})

如果只是这样的话,是没啥子问题的,因为ts会自动帮我们推断出正确的类型。但经常我们需要根据环境变量做些特定的事情,比如删除或新增某个属性,这就导致我们没法直接在函数内传递参数,而是需要将参数提取出来

const config = {
    baseUrl: 'https://www.jianshu.com',
    options: {
        async beforeFetch({ options }) {
            options.headers = {
                ...options.headers,
                Accept: 'application/json',
            };

            return { options };
        },
    },
};

此时,beforeFetch的参数类型丢失

TypeScript类型实战--解决Pinia和vueuse使用过程中的类型丢失问题

为了解决这个问题,我们需要取到createFetch的参数类型,相信看过笔者之前文章的同学已经知道该用谁了,没错,就是Parameters,由于函数的参数是一个数组类型,所以我们取到后,取数组的第一个,另外,这个参数也是可选的,为了避免使用可选链影响美观,咱们使用Required再强制转换下就好啦。(关于这两个工具类型的实现原理,可以看笔者之前的文章哦🥰)

Required<Parameters<typeof createFetch>>[0]

总结

本文,笔者简单总结了在vue+ts+pinia+vueUse项目中使用ts解决类型丢失的问题。其实除了这些还有别的,比如使用的vant组件库类型缺失的问题。有知道如何解决的小伙伴评论区留言哦,这个比较简单,笔者就不花篇幅介绍啦