当前位置: 首页 > Web前端 > JavaScript

用TodoList例子告诉你如何在项目中使用TypeScript

时间:2023-03-27 15:37:00 JavaScript

为什么使用todolist现代框架教程不再是写个helloworld那么简单,而是需要一定的基础能力,能够做数据绑定、遍历、条件判断等各种逻辑,才能完成这一系列的内容,todolist是一个很好的实现。比如react教程,solijs教程都是以todolist为例。当然,如果想看各种框架实现todolist,可以访问TodoMVC[https://todomvc.com/],这里展示了各种框架是如何实现todolisttodolist的tsization的。但是ts的教程,只有一些官方的例子,并没有很好的项目教程,就是实战部分。很多同学在学习ts之后,只有一些基本的js类型设置,在项目中不清楚,所以我们发布了这个教程。当然,在开始之前,我们需要明白,本教程不依赖任何前端库,如react、vue等,同时为了节省时间,我们只放出一些关键的ts代码,不做展示整个应用,还让你知道tsusagedata是怎么对应view中一个tudolist对应的数据的?拿刚才的视图,应该是一个对象数组,数据应该是这样的[{id:1,text:'to-doitem1',done:false},{id:2,text:'to-doTo-doitem2',done:false},{id:3,text:'To-doitem3',done:false}]其??中id是每个待办事项的唯一标识,text是item名称,done表示是否完成当我们点击完成时,其实每个item的done都变了。数据发生变化后,驱动我们的视图进行相应的变化,实现上述handleTodoItem对应的点击事件。让我们来实现它的伪代码。当它点击的时候,需要处理相应的数据,先用js实现functionhandleTodoItem(todo){//当点击的时候,将todo中done的布尔值取反return{...todo,done:!todo.done}}然后我们使用ts进行优化类型Todo={id:number;文本:字符串;完成:布尔值;}//如果变量是todo类型,可以使用consttodoItem:Todo={id:1,text:'todoitem1',done:false}这样ts类型就正常了。如果对应的todoItem不匹配,那么编译就会报错,可以提前感知错误,而如果项目中有ts相关配置,vscode会给出handleTodoItem方法对应的报错信息,应该怎么办被写?functionhandleTodoItem(todo:Todo):Todo{//逻辑实现}readonly对于handleTodoItem函数来说,该函数应该没有副作用,所以传入的todo对象应该不会改变,而是返回一个新的对象比如虽然这个方法可以实现相同的内容,它有副作用,改变了传入的参数,这是不可取的donereturntodo}但是这种ts不会报错,怎么办?然后我们需要使用我们的ts进行类型校验,可以输入Todo={readonlyid:number;只读文本:字符串;readonlydone:boolean;}尝试修改时会出现ts错误,不允许修改,因为Todo类型是只读的,当然你也可以将对象中的所有属性设置为只读输入Todo=Readonly<{id:number;文本:字符串;done:boolean;}>在ts中,thisReadonly的关键字有很多,比如Required,Partial等,有需要的可以自行搜索分类。对于完成的列表,我们需要对其进行分类过滤。比如我们要过滤掉所有已经完成的项目,那么performance是一个数组,done是true[{id:1,text:'Todo1',done:true},{id:2,text:'Todo2',done:true}]如何在数组类中表示a容量呢?Todo[]可以代表上面的数据。同样的,函数的参数也不允许修改,以免产生副作用,所以functioncompleteTodoList(todos:readonlyTodo[]):Todo[]{//...}当然,既然done在Todo类型是boolean,但是completeTodoList中done的值为true,所以我们需要重新定义一个类型typeCompletedTodo=Readonly<{id:number;文本:字符串;done:true;}>所以上面的方法会变成functioncompleteTodoList(todos:readonlyTodo[]):CompletedTodo[]{//...}Intersectiontype对于上面的Todo和CompletedTodo类型,这两个的id和text类型重复,我们可以去掉重复的逻辑,以交集类型为例typeA={a:number}typeB={b:string}typeAandB=A&B//结果为//{//a:number//b:string//}当两种key相同时,第二种key会覆盖第一种的内容A={key:number}typeB={key:string}typeAandB=A&B//结果是//{//key:string//}。对于Todo和CompletedTodo类型,我们希望通过交集类型从Todo中获取CompletedTodo。怎么做?typeCompletedTodo=Todo&{readonlydone:true}是不是很简洁,去掉一些重复的代码?如果我们在Todo的基础上增加一个新的功能,对应todo的优先级,使用priority字段表示一共有三个优先级!!!!!!可以设置优先级:2,显示为[!!]当然你也可以自定义,比如{priority:{custom:'urgent'}}会显示为[urgent],这样数据就变成了[{id:1,text:'Todo1',done:false,priority:1},{id:2,text:'Todo2',done:false,priority:2},{id:3,text:'Todo3',done:false,priority:{custom:'urgent'}},{id:4,text:'Todo4',done:false},]我们已经有了Todo类型,如何添加一个key?在上面的关节类型中,我们用&连接交集类型,关节类型用|连接。同样,例如,键入Foo=number|细绳;这意味着Foo类型可以是数字也可以是字符串类型,所以我们优先级类型可以这样设置typePriority=1|2|3|{自定义:字符串};这时候priority就是我们想要的,所以todo的类型可以改成typeTodo=Readonly<{id:number;文本:字符串;完成:布尔值;priority:Priority;}>optional属性上面的priority属性目前是必须的,但是我们可以不写这个属性,即todo可以没有priority。在这种情况下,我们可以使用可选属性类型Todo=Readonly<{id:number;文本:字符串;完成:布尔值;priority?:Priority;}>添加一个?如何将1、2、3转换成!!!表格呢?可以自定义一个函数,就是priorityToStringpriorityToString(1)//!priorityToString(2)//!!priorityToString(3)//!!!priorityToString({自定义:'紧急'})//紧急情况很少,也许你会写functionpriorityToString(priority:Priority):string{if(priority===1){return'!'}elseif(priority===2){返回'!!'}elseif(priority===3){返回'!!!'}else{returnpriority.custom}}当我们通过if条件判断关节类型时,它会自动确认每个if条件下的参数类型。这也是关节型的威力所在。总结我们项目中基本用到的一些知识点总结在这里。通过一个简单的项目,给大家简单介绍一下ts的一些基本类型。如果大家有更多的疑问,或者项目中遇到的问题,欢迎关注公众号【FE情报局】留言,我会尽力帮你解决问题参考:https://ts.chibicode.com/去做/