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

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

github与好文

前言

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

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

在Pinia中使用

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

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

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

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

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

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

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

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

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

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

ts 复制代码
export type AnyObj = {
    [o: string]: any;
};

在vueuse中使用

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

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

            return { options };
        },
    },
})

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

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

            return { options };
        },
    },
};

此时,beforeFetch的参数类型丢失

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

ts 复制代码
Required<Parameters<typeof createFetch>>[0]

总结

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

相关推荐
YuShiYue2 小时前
pnpm monoreop 打包时 node_modules 内部包 typescript 不能推导出类型报错
javascript·vue.js·typescript·pnpm
一个专注写代码的程序媛2 小时前
为什么vue的key值,不用index?
前端·javascript·vue.js
vvilkim2 小时前
React 与 Vue:两大前端框架的深度对比
vue.js·react.js·前端框架
장숙혜2 小时前
ElementUi的Dropdown下拉菜单的详细介绍及使用
前端·javascript·vue.js
BillKu2 小时前
Vue3父子组件数据双向同步实现方法
前端·javascript·vue.js
猿究院_xyz3 小时前
跟着尚硅谷学vue-day5
前端·javascript·vue.js·前端框架·html
醋醋4 小时前
vue2源码记录4
前端·vue.js
前端大白话4 小时前
震惊!90%前端工程师都踩过的坑!computed属性vs methods到底该怎么选?一文揭秘高效开发密码
前端·vue.js·设计模式
HuaHua的世界5 小时前
说说Vue 模板是如何编译的?
vue.js·面试
Jet_closer_burning5 小时前
axios封装
前端·javascript·vue.js·react.js·ajax