项目中使用TypeScript的TodoList实例详解

 更新时间:2023年1月6日 14:47  点击:802 作者:FE情报局

为什么用todolist

现代的框架教程目前再也不是写个hello world那么简单了,而是需要有一定基础能力能够做到数据绑定、遍历、条件判断等各种逻辑,而能完成这一系列内容的,todolist就是个很好的实现,比如react的教程、solijs教程都是以todolist为例

当然,你如果想看各种框架实现todolist的话,你可以访问TodoMVC 这里面展示了各种框…

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的一些基本类型给大家做了一个简要的说明

参考:ts.chibicode.com/todo/

以上就是项目中使用TypeScript的TodoList实例详解的详细内容,更多关于TypeScript TodoList使用的资料请关注猪先飞其它相关文章!

原文出处:https://juejin.cn/post/7184403027611090981

[!--infotagslink--]

相关文章

  • 浅谈TypeScript 索引签名的理解

    这篇文章主要给大家分享的是TypeScript 索引签名的理解,索引签名由方括号中的索引名称及其类型组成,后面是冒号和值类型:{ [indexName: KeyType]: ValueType }, KeyType 可以是一个 string、number 或 symbol,而ValueType 可以是任何类型,下面就俩简单了解一下吧...2021-10-15
  • vue cli4.0项目引入typescript的方法

    这篇文章主要介绍了vue cli4.0项目引入typescript的方法,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-17
  • 使用TS来编写express服务器的方法步骤

    这篇文章主要介绍了使用TS来编写express服务器的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-30
  • 详解Vue3.0 + TypeScript + Vite初体验

    这篇文章主要介绍了详解Vue3.0 + TypeScript + Vite初体验,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-22
  • TypeScript魔法堂之枚举的超实用手册

    这篇文章主要介绍了TypeScript魔法堂之枚举的超实用手册,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-29
  • 你不知道的 TypeScript 高级类型(小结)

    这篇文章主要介绍了你不知道的 TypeScript 高级类型(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-29
  • 如何在Vue项目中应用TypeScript类

    与如何在React项目中应用TypeScript类类似在VUE项目中应用typescript,我们需要引入一个库vue-property-decorator,需要的小伙伴可续看下文具体介绍...2021-09-15
  • CocosCreator入门教程之用TS制作第一个游戏

    这篇文章主要介绍了CocosCreator入门教程之用TS制作第一个游戏,对TypeScript感兴趣的同学,一定要看一下...2021-04-16
  • TypeScript中条件类型精读与实践记录

    这篇文章主要给大家介绍了关于TypeScript中条件类型精读与实践的相关资料,,条件类型就是在初始状态并不直接确定具体类型,而是通过一定的类型运算得到最终的变量类型,需要的朋友可以参考下...2021-10-05
  • webpack搭建脚手架打包TypeScript代码

    本文主要介绍了webpack搭建脚手架打包TypeScript代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-21
  • TypeScript中正确使用interface和type的方法实例

    在ts中定义类型由两种方式:接口(interface)和类型别名(type alias),interface只能定义对象类型,下面这篇文章主要给大家介绍了关于TypeScript中正确使用interface和type的相关资料,需要的朋友可以参考下...2021-09-15
  • 利用vue3+ts实现管理后台(增删改查)

    这篇文章主要介绍了利用vue3+ts实现管理后台(增删改查),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-30
  • TypeScript前端上传文件到MinIO示例详解

    这篇文章主要为大家介绍了TypeScript前端上传文件到MinIO示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...2022-10-12
  • 详解Typescript里的This的使用方法

    这篇文章主要介绍了详解Typescript里的This的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-08
  • 深入理解typescript中的infer关键字的使用

    infer 这个关键字,整理记录一下,避免后面忘记了。具有一定的参考价值,需要的朋友们下面随着小编来一起学习学习吧...2021-06-27
  • 使用TypeScript开发微信小程序的方法

    TypeScript是C#之父Anders Hejlsberg的又一力作,很多喜欢c#语法的朋友对typescript都爱不释手,今天小编给大家介绍下TypeScript开发微信小程序的方法,感兴趣的朋友一起看看吧...2020-06-25
  • TypeScript中枚举类型的理解与应用场景

    如 TypeScript 官方文档所说,枚举类型是对 JavaScript 标准数据类型集的扩充,所以下面这篇文章主要给大家介绍了关于TypeScript中枚举类型的理解与应用场景的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2021-09-03
  • TypeScript如何开启严格空值检查

    这篇文章主要介绍了TypeScript如何开启严格空值检查,文章围绕TypeScript的相关资料展开详情内容,需要的小伙伴可以参考一下...2022-03-30
  • vue3+TypeScript+vue-router的使用方法

    本文详细讲解了vue3+TypeScript+vue-router的使用方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2022-01-05
  • TypeScript接口介绍

    这篇文章主要介绍了TypeScript接口,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。下面我们一起进入文章看看TypeScript接口得具体定义吧,需要的朋友也可以参考一下...2021-12-10