• 你要的react+ts最佳实践指南


    本文根据日常开发实践,参考优秀文章、文档,来说说 TypeScript 是如何较优雅的融入 React 项目的。

    温馨提示:日常开发中已全面拥抱函数式组件和 React Hooksclass 类组件的写法这里不提及。

    前沿

    • 以前有 JSX 语法,必须引入 React。React 17.0+ 不需要强制声明 React 了。
    import React, {
        useState } from 'react';
    
    // 以后将被替代成
    import {
        useState } from 'react';
    import * as React from 'react';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    基础介绍

    基本类型

    • 基础类型就没什么好说的了,以下都是比较常用的,一般比较好理解,也没什么问题。
    type BasicTypes = {
       
        message: string;
        count: number;
        disabled: boolean;
        names: string[]; // or Array
        id: string | number; // 联合类型
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    联合类型

    一般的联合类型,没什么好说的,这里提一下非常有用,但新手经常遗忘的写法 —— 字符字面量联合。

    • 例如:自定义 ajax 时,一般 method 就那么具体的几种:getpostput 等。
      大家都知道需要传入一个 string 型,你可能会这么写:
    type UnionsTypes = {
       
        method: string; // ❌ bad,可以传入任意字符串
    };
    
    • 1
    • 2
    • 3
    • 4
    • 使用字符字面量联合类型,第一、可以智能提示你可传入的字符常量;第二、防止拼写错误。后面会有更多的例子。
    type UnionsTypes = {
       
        method: 'get' | 'post'; // ✅ good 只允许 'get'、'post' 字面量
    };
    
    • 1
    • 2
    • 3
    • 4

    对象类型

    • 一般你知道确切的属性类型,这没什么好说的。
    type ObjectTypes = {
       
        obj3: {
       
            id: string;
            title: string;
        };
        objArr: {
       
            id: string;
            title: string;
        }[]; // 对象数组,or Array<{ id: string, title: string }>
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 但有时你只知道是个对象,而不确定具体有哪些属性时,你可能会这么用:
    type ObjectTypes = {
       
        obj: object; // ❌ bad,不推荐
        obj2: {
       }; // ❌ bad 几乎类似 object
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 一般编译器会提示你,不要这么使用,推荐使用 Record
    type ObjectTypes = {
       
        objBetter: Record<string, unknown>; // ✅ better,代替 obj: object
    
        // 对于 obj2: {}; 有三种情况:
        obj2Better1: Record<string, unknown>; // ✅ better 同上
        obj2Better2: unknown; // ✅ any value
        obj2Better3: Record<string, never>; // ✅ 空对象
    
        /** Record 更多用法 */
        dict1: {
       
            [key: string]: MyTypeHere;
        };
        dict2: Record<string, MyTypeHere>; // 等价于 dict1
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    参考React实战视频讲解:进入学习

    • Record 有什么好处呢,先看看实现:
    // 意思就是,泛型 K 的集合作为返回对象的属性,且值类型为 T
    type Record<K extends keyof any, T> = {
       
        [P in K]: T;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 官方的一个例子
    interface PageInfo {
       
        title: string;
    }
    
    type Page = 'home' | 'about' | 'contact';
    
    const nav: Record<Page, PageInfo> = {
       
        about: {
        title: 'about' },
        contact: {
        title: 'contact' },
        // TS2322: Type '{ about: { title: string; }; contact: { title: string; }; hoem: { title: string; }; }' 
        // is not assignable to type 'Record'. ...
        hoem: {
        title: 'home' },
    };
    
    nav.about;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    好处:

    1. 当你书写 home 值时,键入 h 常用的编辑器有智能补全提示;
    2. home 拼写错误成 hoem,会有错误提示,往往这类错误很隐蔽;
    3. 收窄接收的边界。

    函数类型

    • 函数类型不建议直接给 Function 类型,有明确的参数类型、个数与返回值类型最佳。
    type FunctionTypes = {
       
        onSomething: Function; // ❌ bad,不推荐。任何可调用的函数
        onClick: () => void; // ✅ better ,明确无参数无返回值的函数
        onChange: (id: number) => void; // ✅ better ,明确参数无返回值的函数
        onClick(event: React.MouseEvent<HTMLButtonElement>): void; // ✅ better
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可选属性

    • React props 可选的情况下,比较常用。
    type OptionalTypes = {
       
        optional?: OptionalType; // 可选属性
    };
    
    • 1
    • 2
    • 3
    • 4
    • 例子:封装一个第三方组件,对方可能并没有暴露一个 props 类型定义时,而你只想关注自己的上层定义。 nameage 是你新增的属性,age 可选,other 为第三方的属性集。
    type AppProps = {
       
        name: string;
        age?: number;
        [propName: string]: any;
    };
    const YourComponent = ({
        name, age, ...other }: AppProps) => (
        <div>
            {
       `Hello, my name is ${
         name}, ${
         age || 'unknown'}`<
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    remote: The project you were looking for could not be found
    嵌入式知识总结:交叉编译、ARM汇编、驱动开发
    教你用Python制作BMI计算器
    Day727.键值数据库的基本架构 -Redis 核心技术与实战
    YARN 应用提交过程
    pytorch基本操作:使用神经网络进行分类任务
    Debian12系统下LAMP环境中Nubuilder4.5的安装
    【Unity3D】反射和折射
    html解决浏览器记住密码输入框的问题
    flv格式怎么转换成mp4,一键快速转换视频格式
  • 原文地址:https://blog.csdn.net/xiaofeng123aazz/article/details/127782326