谈谈在专栏【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前台项目实战 】目前为止主要用到的类型声明定义的方式,接下来会继续这个专栏文章的发布,还会继续用到其他方式进行类型声明定义,请持续关注。

相关推荐
wakangda20 分钟前
React Native 集成原生Android功能
javascript·react native·react.js
j喬乔2 小时前
Node导入不了命名函数?记一次Bug的探索
typescript·node.js
秃头女孩y6 小时前
【React中最优雅的异步请求】
javascript·vue.js·react.js
前端小小王12 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发12 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
yg_小小程序员14 小时前
vue3中使用vuedraggable实现拖拽
typescript·vue
高山我梦口香糖15 小时前
[react 3种方法] 获取ant组件ref用ts如何定义?
typescript·react
不是鱼17 小时前
构建React基础及理解与Vue的区别
前端·vue.js·react.js
prall18 小时前
实战小技巧:下划线转驼峰篇
前端·typescript
飞翔的渴望20 小时前
antd3升级antd5总结
前端·react.js·ant design