为什么用todolist
古代的框架教程目前再也不是写个hello world那么简略了,而是须要有肯定根底能力可能做到数据绑定、遍历、条件判断等各种逻辑,而能实现这一系列内容的,todolist就是个很好的实现,比方react的教程、solijs教程都是以todolist为例
当然,你如果想看各种框架实现todolist的话,你能够拜访TodoMVC【https://todomvc.com/】,这外面展现了各种框架如何实现了todolist
todolist的ts化
然而对于ts教程来说,只有官网的一些实例,并没有一个很好的我的项目上的教程,也就是无关实战的局部,很多同学在学习了ts之后,只会一些根底的js类型的设置,放在我的项目中就不分明了,所以咱们就出了这个教程
当然在开始之前,咱们要理解这个教程不依赖任何的前端库,比方react,vue等,同时也为了节省时间,咱们仅仅是放出一些要害的ts代码,不须要将整个利用都展现进去,同样可能让你晓得ts的应用
数据到视图
一个tudolist对应的数据是怎么样的?就拿方才的视图来看的话,它应该是一个对象数组,数据应该是这样的
[ { id: 1, text: '待办事项1', done: false }, { id: 2, text: '待办事项2', done: false }, { id: 3, text: '待办事项3', done: false }]
其中id是每一个代办事项的惟一标识,text是事项名称,done示意是否实现
当咱们点击实现的时候,实际上就是每一项的done产生了变动,数据发生变化之后驱动咱们的视图做出对应的扭转
实现handleTodoItem
对应的上述的点击事件,咱们实现一下它的伪代码,当其点击的时候,须要解决对应的数据,先应用js实现
function handleTodoItem(todo){ // 点击的时候todo中的done的布尔值取反 return { ...todo, done: !todo.done }}
而后咱们应用ts进行优化
type Todo = { id: number; text: string; done: boolean;}// 如果某个变量是todo类型,能够这样const todoItem: Todo = { id: 1, text: '待办事项1', done: false}
这样ts类型就是失常的,如果相应的todoItem不匹配,则编译就会产生谬误,能够让谬误提前感知,并且如果我的项目中有配置的ts相干,vscode中就会给出对应的错误信息
对应到handleTodoItem这个办法中,应该怎么写呢?
function handleTodoItem(todo: Todo): Todo { // 逻辑实现}
readonly
对于handleTodoItem这个函数来说,函数应该是无副作用的,所以传进去的todo对象,不应该发生变化,而是返回一个新的对象
比方这种办法,尽管可能实现同样的内容,然而它是有副作用的,扭转了传入的参数,是不可取的
function handleTodoItem(todo: Todo):Todo { // 点击的时候todo中的done的布尔值取反 todo.done = !todo.done return todo}
然而这种的ts并不会报错,怎么办?那就须要借助咱们的ts进行类型校验,你能够这样
type Todo = { readonly id: number; readonly text: string; readonly done: boolean;}
当你尝试批改批改的话,就会产生ts谬误,不容许批改,因为Todo类型是只读的,当然你也能够这样设置对象中所有的属性为只读
type Todo = Readonly<{ id: number; text: string; done: boolean;}>
在ts中,这种Readonly的关键词还有很多,比方Required,Partial等,如有须要,大家可自行搜寻
分类
对于曾经实现的list,咱们须要将其进行分类筛选,比方咱们要筛选出所有曾经实现的我的项目,那么体现就是一个数组,并且done为true
[ { id: 1, text: '待办事项1', done: true }, { id: 2, text: '待办事项2', done: true }]
如何示意一个数组类内容呢?Todo[]
这种形式就能示意上述数据,同样的,函数的参数是不容许批改的,防止副作用,所以能够这样
function completeTodoList( todos: readonly Todo[]): Todo[] { // ...}
当然,因为Todo的type中的done为boolean,然而在completeTodoList中done的值为true,所以咱们须要从新定义一个类型
type CompletedTodo = Readonly<{ id: number; text: string; done: true;}>
所以上述的办法就会变成
function completeTodoList( todos: readonly Todo[]): CompletedTodo[] { // ...}
穿插类型
对于下面的Todo和CompletedTodo类型,其中这两个类型的id和text都是反复的,咱们能够删除反复的逻辑,应用穿插类型
举个例子
type A = {a: number}type B = {b: string}type AandB = A & B// 后果为// {// a: number// b: string// }
当两个类型key雷同时,第二个key会笼罩掉第一个的内容
type A = {key: number}type B = {key: string}type AandB = A & B// 后果为// {// key: string// }
那针对Todo和CompletedTodo类型,咱们想从Todo通过穿插类型失去CompletedTodo,该怎么做呢?
type CompletedTodo = Todo & { readonly done: true}
是不是很简洁,并且去除了一些反复代码
新增性能
如果在Todo的根底上,咱们新增了一个性能,对应的todo的优先级,应用priority这个字段示意
并且一共有三种优先级
- !!!
- !!
- !
你能够priority: 2
这样设置,展现为【!!】当然你也能够自定义,比方
{ priority: { custom: '紧急' }}
则展现为【紧急】,所以这时候数据变成了
[ { id: 1, text: '待办事项1', done: false, priority: 1 }, { id: 2, text: '待办事项2', done: false, priority: 2 }, { id: 3, text: '待办事项3', done: false, priority: { custom: '紧急' } }, { id: 4, text: '待办事项4', done: false },]
咱们曾经有了Todo类型,如何新增一个key呢?
联结类型
下面咱们之后穿插类型通过 &
连贯,那联结类型则是通过 |
连贯,同样的举个例子
type Foo = number | string;
这示意Foo类型能够是一个数字,也能够是一个string类型,所以咱们的priority类型能够这样设置
type Priority = 1 | 2 | 3 | { custom: string };
这个时候priority就是咱们想要的内容了,所以todo的类型能够变一下
type Todo = Readonly<{ id: number; text: string; done: boolean; priority: Priority;}>
可选属性
下面的priority这个属性目前是必填的,然而这个属性咱们能够不写,也就是todo能够没有优先级,针对这种状况,咱们能够应用可选属性
type Todo = Readonly<{ id: number; text: string; done: boolean; priority?: Priority;}>
在对应的中央增加一个?即可
数据转视图
那对应的priority的数据有了,如何把1,2,3这种的转成!!!的模式呢?
能够自定义一个函数,也就是priorityToString
priorityToString(1)// !priorityToString(2)// !!priorityToString(3)// !!!priorityToString({ custom: '紧急' })// 紧急
状况比拟少,可能你会这样写
function priorityToString(priority: Priority): string { if(priority === 1){ return '!' }else if(priority === 2){ return '!!' }else if(priority === 3){ return '!!!' }else{ return priority.custom }}
联结类型咱们通过if条件进行判断的时候,它会主动确认每个if条件下的参数类型,这也是联结类型的弱小之处
总结
基本上咱们我的项目中用到的一些知识点这里都概括了,通过一个简略的我的项目,将ts的一些根本类型给大家做了一个简要的阐明,如果你有更多疑难,或者我的项目中的问题,欢送关注公众号【FE情报局】留言,我会尽可能帮忙你解决问题
参考:https://ts.chibicode.com/todo/