2023-03-23 16:57:34    13    0    0

箭头函数在.tsx添加泛型报错

如:

  1. // a.tsx
  2. // 箭头函数添加泛型报错(Error: JSX element ‘T’ has no corresponding closing tag.ts(17008))
  3. const foo = <T>(props: T)=> void

原因: 因为泛型的语法与 JSX 的语法冲突,导致 TS 解析成 JSX 而产生 unexpected token 的问题

解决:
1. 不要写在 .tsx 文件里面就不会报错
2. 在后面加一个逗号就能正确解析了
3.

  1. const foo = <T,>(props: T)=> void
2023-03-21 17:04:57    4    0    0
2023-03-21 06:59:20    15    0    0

获得组件的props类型

React.ComponentProps<typeof Button>

TS内置类型

  1. ConstructorParameters :类构造函数参数类型的元组
  2. Exclude:将一个类型从另一个类型排除
  3. Extract:选择可分配给另一类型的子类型
  4. InstanceType:从一个新类构造函数中获得的实例类型
  5. NonNullable:从类型中排除空和未定义
  6. Parameters:函数的形参类型的元组
  7. Partial:使对象中的所有属性都是可选的
  8. Readonly:将对象中的所有属性设置为只读
  9. ReadonlyArray:创建给定类型的不可变数组
  10. Pick:对象类型的一种子类型,包含其键的子集
  11. Record:从键类型到值类型的映射
  12. Required:使对象中的所有属性都是必需的
  13. ReturnType:函数的返回类型
2023-03-20 16:58:27    8    0    0

any

当我们将某个变量定义为 any 类型后,TypeScript 将会跳过对这个变量的类型检查

unknown

TypeScript 在3.0版本引入了 unknown 类型,它可以理解为类型安全的 (type-safe)any

  • 任何类型都可以赋值给 unknown 类型的对象
  • unknown 类型的对象不可以直接赋值给其它非 unknownany 类型的对象,并且不可以访问上面的任何属性

never

never 就是 TypeScript 的底部类型

  • never 类型只接受 never 类型的对象, any 也不接受
  • never 会从联合类型中移除,类似于将零和其他数字相加时结果等于该数字。即 type Res = never | string // string
  • never 会覆盖交叉类型中的其他类型,类似于零乘其他数字时结果等于零。即 type Res = never & string // never

void

void 其实可以理解为 nullundefined 的联合类型,它表示空值

2023-03-06 18:48:29    9    0    0

父节点如果有回显的情况下

1.循环遍历出最深层子节点,存放在一个数组中
2.将后台返回的含有父节点的数组和第一步骤遍历的数组做比较
3.如果有相同值,将相同值取出来,push到一个新数组中
4.利用这个新的重组的数组给Tree组件selected赋值

  1. const deepArr = [] //deepArr存放所有子节点的数组
  2. //第一步骤:子节点放在一个数组中
  3. const requestList = (data) => {
  4. data && data.map(item => {
  5. if (item.children && item.children.length > 0) {
  6. requestList(item.children)
  7. } else {
  8. deepArr.push(item.id)
  9. }
  10. return null
  11. })
  12. return deepArr
  13. }
  14. //第2,3步骤的方法
  15. const uniqueTree = (uniqueArr, Arr) => {
  16. let uniqueChild = []
  17. for (var i in Arr) {
  18. for (var k in uniqueArr) {
  19. if (uniqueArr[k] === Arr[i]) {
  20. uniqueChild.push(uniqueArr[k])
  21. }
  22. }
  23. }
  24. return uniqueChild
  25. }
  26. //调用第2,3步骤的方法
  27. const getRoleInfo = () => {
  28. getData({ id: Id }).then(res => {
  29. const ids = res.data
  30. const uniqueChild = this.uniqueTree(ids, deepArr)
  31. setCheckedKeys(uniqueChild)
  32. })
  33. }
  34. <Tree
  35. checkable
  36. checkedKeys={checkedKeys}
  37. defaultExpandedKeys={checkedKeys}
  38. fieldNames={{
2023-02-15 09:27:48    15    0    0

git submodule
子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

比如我们想抽象出一个组件库供多个项目使用

git submodule add <子模块git地址> <存放的文件名>

会生成: .gitmodules 和 子模块文件夹

.gitmodules 文件保存了项目 URL 与已经拉取的本地目录之间的映射,这样就能知道子模块在哪获取。如果有多个子模块,该文件中就会有多条记录。

子模块文件夹只存子项目的commit id,就能指定到对于的git header上, 父项目的git并不会记录Submodule的文件变动,它是按照commitid指定Submodule的git header

当你不在那个目录中时,Git 并不会跟踪它的内容, 而是将它看作子模块仓库中的某个具体的提交。

注意的是,这两个文件也像 .gitignore 文件一样受到(通过)版本控制。 它会和该项目的其他部分一同被拉取推送。

克隆含有子模块的项目
克隆一个含有子模块的项目时,默认会包含该子模块目录,但其中还没有任何文件,是空目录。 必须运行:

git submodule init 用来初始化本地配置文件

git submodule update 则从该项目中抓取所有数据并检出父项目中列出的合适的提交。

合成一步就是: git submodule update --init

如果还要初始化、抓取并检出任何嵌套的子模块:git submodule update --init --recursive

或者在克隆的时候加上参数: git clone --recurse-submodules

它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块。

修改submodule
进入submodule目录里修改后add 、commit 、push到远程服务器,然后要回到父目录,提交submodule在父项目中的改动(submodule commit id 会更新),再push

坑:子模块的分支默认不是master,也不会切到任何branch

2023-02-11 19:06:59    47    0    0

在tsx下使用

默认情况下,我们不能在函数组件上使用 ref 属性,因为它们没有实例。

如果要在函数组件中使用 ref,可以使用 forwardRef 包裹组件函数使用(可与 useImperativeHandle 结合使用)。

被 forwardRef 包裹的组件函数除 props,还要多传入第二个参数:ref,即从外部传入的 ref。

useImperativeHandle 接收三个参数,第一个是 forwardRef 传入的 ref;第二个参数是 handle 函数,返回要向外暴露的值,通常是对象;第三个参数是依赖数组,根据依赖变化执行更新,非必需参数。

  1. import { useRef, forwardRef, Ref, useImperativeHandle, ElementRef, useEffect } from "react";
  2. // 组件,有两种定义类型的方式
  3. // 组件1,一种是使用 forwardRef 的泛型
  4. // forwardRef 泛型第一个参数是 Ref 类型,
  5. // 第二个参数是 props 类型,不传时默认类型为{},
  6. // 注意,forwardRef 泛型与内部包裹函数的参数顺序恰恰相反,易造成歧义
  7. const Component1 = forwardRef<HTMLInputElement, {}>((props, ref) => <input ref={ref} />);
  8. // 组件2,另一种是是在函数参数上直接定义类型, **该方式验证有效**
  9. // 注意,在函数参数上定义类型时,ref 参数类型需要使用Ref泛型包裹,而 forwardRef 泛型则不需要
  10. const type useImperativeHandle返回的类型 = React.Ref<{
  11. sayHello: () => void
  12. }>
  13. const Component2 = forwardRef(
  14. // ref 类型使用了 Ref 泛型包裹
  15. (props: {}, ref: useImperativeHandle返回的类型) => {
  16. // ref 为第一个参数,返回带有 sayHello 方法对象的函数为第二个参数
  17. us
2023-01-07 16:11:49    6    0    0

包含功能

  • typescript
  • stylelint
  • prettier
  • eslint
  • husky
    • git钩子
  • styled-components
  • react-app-rewired
    • 调整 create-react-app webpack 配置而不使用 'eject' 并且不创建 react-scripts 的分支。
    • 没有“无配置”限制的 create-react-app 的所有好处。您可以根据需要添加插件、加载程序。
  • customize-cra 依赖于react-app-rewired, 您需要安装它才能customize-cra工作, 增加babel-plugin-import配置动态引入Antd组件
  • babel-plugin-import
    • babel 模块化导入插件,兼容antdantd-mobilelodashmaterial-ui等。
  • antd
  • ahooks

安装create-react-app

  1. npx create-react-app my-app --template typescript

或者

  1. yarn create react-app my-app --template typescript

安装antd和定制化Create-React-App项目的两个包

  1. npm install antd --save
  2. npm install babel-plugin-import react-app-rewired customize-cra --save-dev

根目录创建config-overrides.js,用customized-cra来增加babel-plugin-import配置动态引入Antd组件

  1. const { override, fixBabelImports } = require('customize-cra');
  2. module.exports = override(fixBabelImports('import', {
  3. libraryName: 'antd',
  4. lib
2023-01-07 07:40:59    6    0    0
  1. // scanMixin.js
  2. export default {
  3. data() {
  4. return {
  5. code: '',
  6. lastTime: '',
  7. nextTime: '',
  8. lastCode: '',
  9. nextCode: '',
  10. dtmainId: '',
  11. };
  12. },
  13. activated() {
  14. window.addEventListener('keypress', this.scanEventHandler, false);
  15. },
  16. beforeDestroy() {
  17. window.removeEventListener('keypress', this.scanEventHandler, false);
  18. },
  19. deactivated() {
  20. window.removeEventListener('keypress', this.scanEventHandler, false);
  21. },
  22. methods: {
  23. scanEventHandler(e) {
  24. if (window.event) { // IE
  25. this.nextCode = e.keyCode;
  26. } else if (e.which) { // Netscape/Firefox/Opera
  27. this.nextCode = e.which;
  28. }
  29. if (e.which === 13) { // 键盘回车事件
  30. if (this.code.length < 3) return; // 扫码枪的速度很快,手动输入的时间不会让code的长度大于2,所以这里不会对扫码枪有效
  31. console.log('扫码结束。');
  32. console.log('条形码:', this.code);
  33. this.parseQRCode(this.code); // 获取到扫码枪输入的内容,做别的操作
  34. this.code = '';
  35. this.lastCode
2022-12-25 10:10:29    8    0    0

Type ‘undefined’ is not assignable to type ‘Function’.

nullundefined 是其它类型(包括 void)的子类型,可以赋值给其它类型(如:数字类型),赋值后的类型会变成 nullundefined
使用第三方/自己的代码声明里没有定义 null | undefined, 可强制转换值的类型

语法

  1. <类型>值

或者(tsx中只能使用这种方式)

  1. as 类型
2/18