谈谈在专栏【React+TS前台项目实战】项目中用到的Typescript定义方式

文章目录

  • 前言
      • [1. interface和type差别](#1. interface和type差别)
      • [2. omit剔除](#2. omit剔除)
      • [3. 联合类型和交叉类型使用](#3. 联合类型和交叉类型使用)
      • [4. 使用命名空间暴露类型声明](#4. 使用命名空间暴露类型声明)
      • [5. 使用ForwardedRef传递ref](#5. 使用ForwardedRef传递ref)
      • [6. 函数返回](#6. 函数返回)
      • 7.Record
      • 8.泛型使用
      • [9. 继承](#9. 继承)
      • [10. 定义函数返回类型为promise](#10. 定义函数返回类型为promise)
      • [11. 返回reactNode](#11. 返回reactNode)
  • 总结

前言

今天不讲实战,来讲一下我们专栏【 React+TS前台项目实战 】中用到的Typescript用法,比起网上那些直接概念式地讲,通过实战我们更能加深对Typescript方面相关知识的理解。


1. interface和type差别

这两种定义类型声明的主要区别在于interface定义的是对象,而type可以定义不限于对象的基本数据类型,联合类型,交叉类型等。

2. omit剔除

在项目封装input组件时,会使用到Omit去剔除声明中某个属性,再联合自己额外定义的属性,如下展示的是部分代码

c 复制代码
type Props = Omit<ComponentPropsWithoutRef<"input">, "size"> & {
  // 按下回车的回调
  onEnter?: () => void;
  // 清除输入框的回调
  onClear?: () => void;
  // 是否显示加载状态
  loading?: boolean;
  // 输入框大小
  size?: "default" | "small" | "large" | undefined;
  // 输入框前缀
  hasPrefix?: boolean;
};

3. 联合类型和交叉类型使用

这里把联合和或一起举例,在Link链接组件中运用到了交叉类型的使用,组合自己定义的声明;在Search组件封装时,运用到了联合类型的使用,由于搜索结果类型不同,展示的数据结构不一样,这时候就可以用或把不同类型声明区分开来

c 复制代码
// 交叉类型的使用
type LinkProps = Omit<RouterLinkProps, "ref"> & {
  ref?: ForwardedRef<HTMLAnchorElement>;
  to?: string;
  className?: string;
  children?: ReactNode;
};
import { Response } from '@/request/types'
import { Block } from '@/models/Block'
import { Transaction } from '@/models/Transaction'
export enum SearchResultType {
  Block = 'block',
  Transaction = 'ckb_transaction',
}
// 联合类型的使用
export type SearchResult =
  | Response.Wrapper<Block, SearchResultType.Block>
  | Response.Wrapper<Transaction, SearchResultType.Transaction>

4. 使用命名空间暴露类型声明

在请求封装中,使用到一系列类型声明,我们将他包装在了Response命名空间里面

c 复制代码
export namespace Response {
  export interface Response<T> {
    data: T
    meta?: Meta
    error?: Error[]
  }

  export interface Error {
    id: string
    code: number
    status: number
    title: string
    detail: string
    href: string
  }

  export interface Meta {
    total: number
    pageSize: number
  }

  export interface Wrapper<A, T = string> {
    id: number
    type: T
    attributes: A
  }
}

5. 使用ForwardedRef传递ref

这里同样举例Link组件封装,做到了传递ref的功能

c 复制代码
type LinkProps = Omit<RouterLinkProps, "ref"> & {
  ref?: ForwardedRef<HTMLAnchorElement>;
  to?: string;
  className?: string;
  children?: ReactNode;
};
const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
  // ...
});

6. 函数返回

在弹窗组件Dialog的封装中,我们定义声明类型为返回void。

c 复制代码
void  onClose: () => void;

7.Record

简单讲,其实Record就是定义一个对象的一些key键名,然后定义键值的类型,在Searh组件的封装中,我们使用了它来定义搜索结果的数据类型声明。

c 复制代码
export enum SearchResultType {
  Block = 'block',
  Transaction = 'ckb_transaction'
}
export type SearchResult =
  | Response.Wrapper<Block, SearchResultType.Block>
  | Response.Wrapper<Transaction, SearchResultType.Transaction>
Record<SearchResultType, SearchResult[]>

8.泛型使用

泛型是一个通用的数据类型参数,可代替任何类型,达到复用的效果。这里同样举了请求类型声明的定义上。

c 复制代码
// 定义
export namespace Response {
 export interface Wrapper<A, T = string> {
    id: number
    type: T
    attributes: A
  }
 }
// 使用
type SearchResult =
  | Response.Wrapper<Block, SearchResultType.Block>

9. 继承

这里定义了一个Props的类型声明,同时引用了ComponentProps类型声明,继承了其中div属性的类型声明

c 复制代码
import { ComponentProps, ReactNode } from 'react'
interface Props<T> extends ComponentProps<'div'> {
  data: T[]
}

10. 定义函数返回类型为promise

函数返回类型为promise,这个在Button组件的封装中使用了。

c 复制代码
  beforeChange?: (() => Promise<void>) | undefined;

11. 返回reactNode

这个类型通常用于函数组件的返回值,以便能够接受不同类型的内容,包括React元素、文本、数组或者null。这个在Modal组件的封装中使用了。

c 复制代码
 type Props = {
  // 模态框内容
  children: React.ReactNode;
};

总结

上面就是专栏【 React+TS前台项目实战 】目前为止主要用到的类型声明定义的方式,接下来会继续这个专栏文章的发布,还会继续用到其他方式进行类型声明定义,请持续关注。

相关推荐
叫我阿柒啊11 小时前
从Java全栈到前端框架:一场真实的技术面试对话
java·vue.js·spring boot·微服务·typescript·前端开发·后端开发
Blossom.11813 小时前
多模态大模型LoRA微调实战:从零构建企业级图文检索系统
人工智能·python·深度学习·学习·react.js·django·transformer
xhxxx13 小时前
从样式到结构:TailwindCss + Fragment 如何让 React 代码更干净、更高效
前端·css·react.js
老前端的功夫16 小时前
TypeScript 类型守卫:从编译原理到高级模式
前端·javascript·架构·typescript
ttod_qzstudio17 小时前
备忘录之事件监听器绑定陷阱:为什么 .bind(this) 会移除失败?
javascript·typescript·内存泄漏·事件监听
ohyeah17 小时前
React 中的跨层级通信:使用 Context 实现主题切换功能
前端·react.js
Dragon Wu18 小时前
前端项目架构 项目格式化规范篇
前端·javascript·react.js·前端框架
RedHeartWWW21 小时前
nextjs中,关于Layout组件和Page组件的认知
前端·react.js
大明二代21 小时前
基于 Microsoft Graph API 与 React Email 构建现代化邮件发送系统
前端·react.js·microsoft
风止何安啊21 小时前
那些让你 debug 到凌晨的陷阱,我帮你踩平了:React Hooks 避坑指南
前端·react.js·面试