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组件库类型缺失的问题。有知道如何解决的小伙伴评论区留言哦,这个比较简单,笔者就不花篇幅介绍啦

相关推荐
浩星6 分钟前
iframe引入界面有el-date-picker日期框,点击出现闪退问题处理
前端·vue.js·elementui
萌萌哒草头将军1 小时前
🚀🚀🚀 Oxc 恶意扩展警告;Rolldown 放弃 CJS 支持;Vite 发布两个漏洞补丁版本;Rslib v0.13 支持 ts-go
前端·javascript·vue.js
接着奏乐接着舞。1 小时前
3D地球可视化教程 - 第1篇:基础地球渲染系统
前端·javascript·vue.js·3d·three.js
薄雾晚晴1 小时前
Rspack 实战:用 SWC Loader 搞定 JS 兼容(支持 IE 11 + 现代浏览器,兼顾构建速度)
前端·vue.js
薄雾晚晴2 小时前
Rspack 实战:用 image-minimizer-webpack-plugin 做图片压缩,优化打包体积
javascript·vue.js
niuhuahua2 小时前
大模型流式聊天,实时对话,快捷问题选项
vue.js
JIngJaneIL2 小时前
汽车租赁|基于Java+vue的汽车租赁系统(源码+数据库+文档)
java·vue.js·spring boot·汽车·论文·毕设·汽车租赁系统
Artea2 小时前
聊聊 Vue3 的泛型
vue.js
BYSJMG2 小时前
计算机毕业设计选题:基于Spark+Hadoop的健康饮食营养数据分析系统【源码+文档+调试】
大数据·vue.js·hadoop·分布式·spark·django·课程设计
古夕2 小时前
Vue3 + vue-query 的重复请求问题解决记录
前端·javascript·vue.js