项目中使用ts的一些技巧

2023-05-16

  项目上使用ts一年多了,一边写,一边看,总结了一些小技巧,写了一些分享给大家,如果对你有所帮助就转评赞三连来一个,那么我们开始今天的正题;

(1)、type联合类型简化

  我们先看下面一个联合类型案例:

// 大北京疫情,家中蔬菜总量类目
const vegetablesNum = {
  tomatoes: 12,
  radishs: 10,
  cabbages: 1
};
// 定义单类目
type Vegetables = | 
{
  tomatoes: number
} | {
  radishs: number
} | {
  cabbages: number
};
// 今天我们只吃其中一种或多种,
const cookie: Vegetables = {
  tomatoes: 10,
}

  上面的type + |方式实现了一个不为空{}任意key组合的对象,也许很多人在想是否可以通过interface + ?可选属性方式实现,答案是不可以的,因为这样处理总会出现{}或者固定key的情况;

  然而上述方案有个致命问题,如果vegetablesNum里面新增的其他的蔬菜,我们的type Vegetables就需要跟着改动,这样Vegetables这个类型定义就显得很笨;所以我们需要优化这个Vegetables类型,让他适配更多的情况,具体如下:

// 大北京疫情,家中蔬菜总量类目
const vegetablesNum = {
  tomatoes: 12,
  radishs: 10,
  cabbages: 1
};

type NewVegetables = {
  [K in keyof typeof vegetablesNum]: {
    [K2 in K]: typeof vegetablesNum[K2]
  }
}[keyof typeof vegetablesNum]

const cookie2: NewSingleVegetable = {
  tomatoes: 123,
  cabbages: 123
}

  上面实现的NewVegetables可以随时满足vegetablesNum数据结构的变化,已经很nice了,可是如果有一天隔壁工位老王,说你这个类型很nice,我要用,开始c + v? 好像无聊的代码又增加了一份,因此我们考虑一下泛型思维解决重复劳动?看一看具体办法吧:

// 大北京疫情,家中蔬菜总量类目
const vegetablesNum = {
  tomatoes: 12,
  radishs: 10,
  cabbages: 1
};

const animals = {
  pig: 20,
  monkey: 50,
}

type SingleRecord<T = Record<string, any>> = {
  [K in keyof T]: {
    [R in K]: T[R]
  }
}[keyof T]

const cookie3: SingleRecord<typeof vegetablesNum> = {
  tomatoes: 123
}
                            
const monkeys: SingleRecord<typeof animals> = {
  monkey: 50                            
}

  这样老王就可以开心使用摸鱼技巧了;

(2)、extends与泛型优化你的函数

  在实际情况中,我们写一些通用方法,为了通用性放宽类型限制,虽然方便了,但是问题在与ts对于他的语法检测也会随之放宽,有一些意想不到的错误出现,如下代码所示:

let obj = {
  name: 'kanade',
  age: 20
}

function getInfo(obj: Record<string, any>, key: string) {
  return obj[key]
}

getInfo(obj, 'age1')

  getInfo传入非obj的key值错误,会有意想不到undefined取值出现,遇到这样的问题,怎么能让我们函数看起来匹配不同类型数据,还有良好的语法纠错提示呢?(不要在乎示例,你可能会说直接obj.name,放过他吧,他还只是一个example~~)
下面有请我们的extends和泛型同学登场,来改造我们的函数

let obj = {
  name: 'kanade',
  age: 20
}

function getInfoNew<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}

getInfoNew(obj, 'age')

  效果图,这么良好的提示你们爱了么
image.png

(3)、as类型断言 + keyof 让遍历更加友好

  我们看一看蔬菜大礼包的例子

const vegetables = {
  tomatoes: 12,
  radishs: 10,
  cabbages: 1
}

Object.keys(vegetables).forEach((key) => {
  console.log(`${key}-数量-${vegetables[key]}`)
})

  显然获取蔬菜数量vegetables[key]ts语法检测报错,原因很简单,Object.keys(obj)返回的是一个string[]类型,然而vegetables里面 的key值是"tomatoes" | "radishs" | "cabbages"string[] > "tomatoes" | "radishs" | "cabbages",类型定义的超出了他的可使用范围,所以最合适的办法就是,我们全局定义一个通用的获取Object.key的方法,让他返回对象key值的联合类型的数组,具体如下:

const vegetables = {
  tomatoes: 12,
  radishs: 10,
  cabbages: 1
}

export const getObjectKey = <T>(obj: T): (keyof T)[] => {
  return Object.keys(obj) as (keyof T)[]
}

getObjectKey(vegetables).forEach((key) => {
  console.log(`${key}-数量-${vegetables[key]}`)
})

  看看实际效果,很清爽的提示~
image.png

(4)、Pick 让类型可以复用

  在实际项目中,我们有时候后需要从一个已知的类型中生成一个子集内容来使用,如下所示:

interface Info {
  name: string
  age: number
  addr: string
  phoneNum: number
  hobby: string
}
// 如果我们仅仅需要个人名字 +  爱好
interface PersonHobby {
  name: string
  hobby: string
}

  这种写法当然是没有问题的,当然不是最高明的写法,我们可以通过ts提供的Pick类型函数进行改造,具体如下:

interface Info {
  name: string
  age: number
  addr: string
  phoneNum: number
  hobby: string
}
// 如果我们仅仅需要个人名字 +  爱好
interface PersonHobby {
  name: string
  hobby: string
}
// 类型函数
type NewPersonHobby = Pick<Info, 'name' | 'hobby'>

  对比一下,用一行代码解决了四行代码做的事儿,是不是显得你很帅~

(5)、关于react中的组件类型获取办法

  react项目,我们使用antd组件库,定义组件方法是不是经常command进去查阅类型定义,然后复制引入一些类型定义复杂的方式,最后满足了类型校验,最后一看代码一坨~

import React from 'react'

import { Table, TablePaginationConfig } from 'antd'
import { FilterValue, SorterResult, TableCurrentDataSource } from 'antd/lib/table/interface'


const Demo: React.FC = () => {
  const onTableChange = (
    pagination: TablePaginationConfig,
    filters: Record<string, FilterValue | null>,
    sorter: SorterResult<any> | SorterResult<any>[],
    extra: TableCurrentDataSource<any>
  ) => {
    console.log(pagination, filters, sorter, extra)
  }

  return <Table dataSource={[]} onChange={onTableChange}></Table>
}

  那么我们又什么简单方法么?当然有,之前我也是按照这样的笨方法去做的,直到有一天发现了React.ComponentProps这个工具函数,翻生码农把歌唱~,走一波

import React from 'react'

import { Table } from 'antd'


const Demo: React.FC = () => {
  // const onTableChange = (
  //   pagination: TablePaginationConfig,
  //   filters: Record<string, FilterValue | null>,
  //   sorter: SorterResult<any> | SorterResult<any>[],
  //   extra: TableCurrentDataSource<any>
  // ) => {
  //   console.log(pagination, filters, sorter, extra)
  // }

  const onTableChange: React.ComponentProps<typeof Table>['onChange'] = (pagination, filters, sorter, extra) => {
    console.log(pagination, sorter, filters, extra)
  }

  return <Table dataSource={[]} onChange={onTableChange}></Table>
}

  通过这样的方式是不是简单很多,也无需balabala引入一堆东西来去做~~

  本期我就先写这些项目上常使用的一些ts类型技巧,喜欢的朋友们,可以点赞、收藏、关注三连走一波,感谢感谢~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

项目中使用ts的一些技巧 的相关文章

  • c++pthread多线程消费者问题

    分布式选修课上讲了多线程编程 xff0c 布置了一个生产者消费者的作业 xff0c 觉得挺有意思 xff0c 并且网络上的消费者问题多使用c语言编写 xff0c 故在此记录c 43 43 解决方法 由于是消费者线程各自计数 xff0c 故使
  • 红包动画

    lt DOCTYPE html gt lt html lang 61 34 en 34 data dpr 61 34 1 34 style 61 34 font size 32px 34 gt lt head gt lt meta char
  • Android中<xliff:g></xliff:g>的用法

    在查阅修改Android源码的过程中经常能在字符串资源中看到类似下面的标签 xff1a span class hljs tag lt span class hljs title resources span span class hljs
  • vue单文件组件的格式规范

    lt template gt lt template gt lt script gt export default name 39 39 mixins components props data return computed watch
  • Linux命令行安装weblogic12c

    Linux命令行安装weblogic12c 一 安装jdk 若已安装可跳过 1 Oracle官网下载jdk linux安装包 2 卸载linux系统中自带的jdk 使用rpm qa grep java查询出系统自带的jdk xff1b 使用
  • Ubuntu 远程免密码登录设置

    我们正常使用 ssh 远程登录服务器进行操作 xff0c 需要输入用户名 服务器ip以及密码 xff0c 当我们需要同时管理多个服务器的时候 xff0c 每次都需要重复输入这些东西会显得特别麻烦和浪费时间 xff0c 因此我们可以通过配置密
  • Mybatis resultMap启动时报错:Could not resolve type alias userResultMap Cannot find class: userResultMap

    MyBatis中在查询进行select映射的时候 xff0c 返回类型可以用resultType xff0c 也可以用resultMap xff0c resultType是直接 表示返回类型的 xff0c 而resultMap则是对外部Re
  • synchronized-锁总结

    目录 一 相关知识点 1 1 对象头 1 2 锁相关概念 1 3 查看对象头工具 二 锁流程 2 1 加锁 xff1a monitorenter 2 2 释放锁 xff1a monitorexit 一 相关知识点 在 JDK1 6 之前 x
  • 软件工程师校招面试救急包

    LeetCode牛人总结 xff08 手撕代码前看看 xff0c 抱佛脚 xff09 https github com labuladong fucking algorithm blob master README md 剑指offer x
  • 微信SDK中含有的支付功能怎么去掉?

    一 说在前面的话 这两天遇到一个特别让我DT的问题 xff0c 估计大家通过标题就能知道问题了 没错 xff0c 就是在应用中集成了微信SDK后 xff0c 它自动支持了微信分享 登录 收藏 支付等功能 这一点没啥 xff0c TM的关键点
  • Android中图片的镂空效果(不规则图形的镂空)

    一 说在前面的话 我们在做新手引导时 xff0c 经常会遇到凸显某一块功能时需求 xff0c 类似于下图 xff1a 看到这个功能点可能会有点头大 xff0c 不过好在Android为我们提供一个美好的工具 xff1a PorterDuff

随机推荐

  • 利用三层交换机实现VLAN间路由

    原理概述 xff1a VLAN将一个物理的LAN在逻辑上划分成多个广播域 VLAN内的主机间可以直接通信 xff0c 而VLAN间不能直接互通 在现实网络中 xff0c 经常会遇到需要跨VLAN相互访问的情况 xff0c 工程师通常会选择一
  • Failed to resolve attribute at index 6: TypedValue{t=0x2/d=0x7f0400cd a=7 r=0x7f06006e}

    今天在开发时 xff0c 遇到一个程序的Bug xff0c 记录一下 在Dialog中展示一个布局 xff0c 布局中包含了TextView报了下面的错误 xff0c 最开始还以为是颜色设置的问题 xff0c 反复核对了一下颜色设置并没有问
  • TextView的TextColor中使用selector的问题

    在TextView中如果设置选中 点击 获取焦点时 xff0c 文字颜色发生改变时 xff0c 一般我们会通过代码中设置 不过Android给我们提供了一个更简洁的方式 xff0c 就是通过selector去改变 只需要在Res目录下创建一
  • 彻底理解Java中堆和栈的区别

    1 概述 在Java中 xff0c 内存分为两部分 xff0c 一种是堆内存 xff0c 另一种就是栈内存 2 Java中变量在内存中的分配 1 类变量 static修饰的变量 xff1a 在程序加载时系统就为它在堆中开辟了内存 xff0c
  • 深入了解多线程的原理

    说在前面的话 使用多线程的目的 在多个CPU核心下 xff0c 多线程的好处是显而易见的 xff0c 不然多个CPU核心只跑一个线程其他的核心就都浪费了即便不考虑多核心 xff0c 在单核下 xff0c 多线程也是有意义的 xff0c 因为
  • An operation is not implemented: not implemented被坑之路[Kotlin]

    吐槽一下 xff0c 程序猿的辛酸史 今天在开发新项目时 xff0c 首次使用了Kotlin语言 xff0c 对于之前只在纸上谈兵 xff0c 未在项目中使用过的码农 xff0c 很是一脸懵逼 但是迫于公司的要求 xff0c 只能硬头皮冲吧
  • 开发Android Camera—使用Kotlin语言,完成第一个自定义相机

    对于首次使用Kotlin语言开发 xff0c 在网上苦于寻找不到Kotlin语言编写的相机代码 xff0c 故写下这篇博客 好了 xff0c 咱们进入主题 在Android 5 0 xff08 SDK 21 xff09 中 xff0c Go
  • Android ConstraintLayout性能分析

    这篇文件是讲述ConstraintLayout性能的分析 xff0c 如果对于使用ConstraintLayout不是很了解的情况下 xff0c 请查看Android ConstraintLayout完全解析和性能分析 xff08 章节一
  • 针对drawableStart(Top、End、Bottom)边距的设置-Android布局技巧

    作为Android程序猿 xff0c 在开发布局的过程中 xff0c 我们的宗旨是能用一个View完成的效果 xff0c 绝不会用两个View或者嵌套View来完成 至于它的好处 xff0c 就不言而喻了吧 不懂的自行到网上看 xff0c
  • markdown基本语法

    转载自 Cmd 技术渲染的沙箱页面 xff0c 点击此处编写自己的文档 Cmd Markdown 简明语法手册 标签 xff1a Cmd Markdown 1 斜体和粗体 使用 和 表示斜体和粗体 示例 xff1a 这是 斜体 xff0c
  • unix环境高级编程——UNIX体系架构

    本期主题 xff1a unix环境高级编程 UNIX体系架构 文件IO 0 初始UNIX1 系统调用2 库函数2 1 C语言的运行库 3 shell 0 初始UNIX 这里略过unix的历史不讲 xff0c 网上有比较详细的资料 我们可以将
  • HTML基础<1>

    一 图片标签与超链接 lt br gt 是空格 lt hr gt 是横线 lt img src 61 34 34 width 61 34 34 height 61 34 34 gt lt a href 61 34 https www bai
  • Android Lottie动画

    Android Lottie动画 在Android中 xff0c 往往UI会让写一些动画效果 xff0c 比如启动页心形跳动 xff0c 返回效果等 一般我们在项目中常用的动画无非是以下几种 xff1a 普通动画帧动画属性动画通过改变Lay
  • 我与人工智能的故事

    本文作者 xff1a 诸葛越 前 言 人工智能的三次浪潮 2018年年初 xff0c 招聘季正如火如荼地进行 xff0c 而 数据科学家 和 算法工程师 绝对算得上热门职业 人工智能 机器学习 深度学习 建模 卷积神经网络 等关键词 xff
  • GitHub安装和使用

    GitHub安装和使用 GitHub是一个基于git的代码托管平台 xff0c 付费用户可以建私人仓库 xff0c 一般的免费用户只能使用公共仓库 xff0c 也就是代码要公开 Github 由Chris Wanstrath PJ Hyet
  • Linux系统java安装

    1 下载 进入Oracle官网进行JDK下载 2 创建目录 span class token function mkdir span usr java span class token function cd span usr java 3
  • 过年之抢红包算法

    前言 昨天是大年初一 xff0c 怎么说呢 xff0c 因为在读大学 xff0c 没有出来工作 xff0c 所以昨晚也是陆陆续续有收到一些红包 然后想起自己对算法感兴趣 xff0c 以前也看过一些公众号有讲过抢红包算法 xff0c 今天就更
  • DL基本知识(七)FTRL优化器

    契机 最近工作方向为缩减模型规模 xff0c 切入点为L1正则化 xff0c 选择该切入点的理由如下 xff0c 众所周知 xff0c L1正则化能令权重矩阵更稀疏 在推荐系统中特征多为embedding xff0c 权重矩阵稀疏意味着一些
  • 生产者消费者问题的C语言实现

    实验六 生产者 消费者问题实验 一 实验目的 掌握Linux下生产者 消费者问题算法的实现 二 实验原理 1 clone系统调用 xff1a 功能 xff1a 创建一个轻进程或线程 用法 xff1a intclone int fn void
  • 项目中使用ts的一些技巧

    项目上使用ts一年多了 xff0c 一边写 xff0c 一边看 xff0c 总结了一些小技巧 xff0c 写了一些分享给大家 xff0c 如果对你有所帮助就转评赞三连来一个 xff0c 那么我们开始今天的正题 xff1b 1 type联合类