第四章 TypeScript 类型声明文件与 React 运用

目录

一、类型声明文件(.d.ts)

二、使用已有的类型声明文件

[1. 内置类型声明](#1. 内置类型声明)

[2. 第三方库类型声明](#2. 第三方库类型声明)

三、创建自己的类型声明文件

[1. 项目内共享类型](#1. 项目内共享类型)

[2. 为已有 JS 文件提供类型声明](#2. 为已有 JS 文件提供类型声明)

[3. 使用 declare 声明全局变量](#3. 使用 declare 声明全局变量)

[四、在 React 中使用 TypeScript](#四、在 React 中使用 TypeScript)

[1. 创建支持 TypeScript 的 React 项目](#1. 创建支持 TypeScript 的 React 项目)

[2. 函数组件(Function Component)](#2. 函数组件(Function Component))

[3. 事件处理](#3. 事件处理)

[4. Class 组件](#4. Class 组件)

[5. React Hooks 类型](#5. React Hooks 类型)

[6. 自定义 Hooks 类型](#6. 自定义 Hooks 类型)

[7. 高阶组件(HOC)类型](#7. 高阶组件(HOC)类型)

[五、TypeScript 配置文件 tsconfig.json 常用配置](#五、TypeScript 配置文件 tsconfig.json 常用配置)


本文介绍了TypeScript中的类型声明文件(.d.ts)及其应用场景,包括为JavaScript库提供类型支持、使用内置和第三方类型声明。

重点讲解了在React项目中使用TypeScript的方法,包括函数组件、事件处理、Class组件和React Hooks的类型定义,以及自定义Hooks和高阶组件的类型处理。最后介绍了TypeScript配置文件tsconfig.json的常用配置选项。通过类型声明文件,开发者可以在项目中获得更好的类型提示和检查,提高代码质量和开发效率。

一、类型声明文件(.d.ts)

TypeScript 有两种文件类型:

  • .ts :包含类型和实现,编译后生成 .js

  • .d.ts:仅包含类型声明,不会生成 JS,用于提供类型信息

作用:为已有 JavaScript 库提供类型支持,让 TypeScript 项目能够使用这些库并获得类型提示。

二、使用已有的类型声明文件

1. 内置类型声明

TypeScript 自带了 DOM、BOM、ES 内置 API 的类型声明,如 lib.es5.d.tslib.dom.d.ts

2. 第三方库类型声明
  • 自带类型 :有些库(如 axios)在 npm 包中包含了 .d.ts 文件。

  • DefinitelyTyped :对于没有自带类型的库,可以安装 @types/库名 获取类型。

bash 复制代码
npm install @types/react @types/react-dom

三、创建自己的类型声明文件

1. 项目内共享类型

创建 types.d.ts

TypeScript 复制代码
export interface User {
  id: number;
  name: string;
}

.ts 文件中导入:

TypeScript 复制代码
import { User } from "./types";
2. 为已有 JS 文件提供类型声明

假设有一个 utils.js

javascript 复制代码
export function add(a, b) {
  return a + b;
}

创建 utils.d.ts

TypeScript 复制代码
export declare function add(a: number, b: number): number;
3. 使用 declare 声明全局变量
TypeScript 复制代码
// global.d.ts
declare const MY_GLOBAL: string;

四、在 React 中使用 TypeScript

前提说明:现在,基于 class 组件来讲解 React+TS 的使用(最新的 React Hooks,在后面讲解)。
在不使用 TS 时,可以使用 prop-types 库,为 React 组件提供类型检查 https://legacy.reactjs.org/docs/typechecking-with-proptypes.html
说明: TS 项目中,推荐使用 TypeScript 实现组件类型校验(代替 PropTypes) 。
不管是 React 还是 Vue,只要是支持 TS 的库,都提供了很多类型,来满足该库对类型的需求。
注意:

  1. React 项目是通过 @types/react、@types/react-dom 类型声明包,来提供类型的。
  2. 这些包 CRA 已帮我们安装好(react-app-env.d.ts),直接用即可。
    参考资料:
    https://legacy.reactjs.org/docs/static-type-checking.htmlhttps://github.com/typescript-cheatsheets/react
1. 创建支持 TypeScript 的 React 项目
TypeScript 复制代码
-- 创建react支持Typescript
npm create vite@latest my-app -- --template react-ts

-- 创建react默认使用并支持JavaScript
# 使用 npm
npm create vite@latest my-react-app -- --template react

# 或使用 yarn
yarn create vite my-react-app --template react

# 或使用 pnpm
pnpm create vite my-react-app --template react

主要变化

  • tsconfig.json:TS 编译配置

  • *.tsx:包含 JSX 的组件文件

  • react-app-env.d.ts:默认类型声明文件

2. 函数组件(Function Component)
TypeScript 复制代码
type Props = {
  name: string;
  age?: number;
};

const Hello: React.FC<Props> = ({ name, age = 18 }) => {
  return <div>你好,{name},你 {age} 岁</div>;
};

// 或者更简洁的写法
const Hello = ({ name, age = 18 }: Props) => {
  return <div>你好,{name},你 {age} 岁</div>;
};
3. 事件处理
TypeScript 复制代码
// 按钮点击
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
  console.log(e.currentTarget);
};

// 输入框变化
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  console.log(e.target.value);
};

// 表单提交
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();
};
4. Class 组件
TypeScript 复制代码
type Props = { name: string };
type State = { count: number };

class Counter extends React.Component<Props, State> {
  state: State = { count: 0 };

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        {this.props.name}: {this.state.count}
        <button onClick={this.increment}>+1</button>
      </div>
    );
  }
}
5. React Hooks 类型
  • useState
TypeScript 复制代码
const [count, setCount] = useState<number>(0);
// 或者依靠类型推断
const [count, setCount] = useState(0); // count 类型为 number
  • useReducer
TypeScript 复制代码
type State = { count: number };
type Action = { type: "increment" } | { type: "decrement" };

const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      return state;
  }
};

const [state, dispatch] = useReducer(reducer, { count: 0 });
  • useRef
TypeScript 复制代码
// 用于 DOM 元素
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
  inputRef.current?.focus();
}, []);

// 用于存储可变值
const intervalRef = useRef<number | null>(null);
  • useContext
TypeScript 复制代码
type Theme = "light" | "dark";
const ThemeContext = createContext<Theme>("light");

const Child = () => {
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
};
  • useMemo / useCallback
TypeScript 复制代码
const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const handleClick = useCallback(() => {
  console.log("clicked");
}, []);
6. 自定义 Hooks 类型
TypeScript 复制代码
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void] {
  const [storedValue, setStoredValue] = useState<T>(() => {
    const item = window.localStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  const setValue = (value: T) => {
    setStoredValue(value);
    window.localStorage.setItem(key, JSON.stringify(value));
  };

  return [storedValue, setValue];
}
7. 高阶组件(HOC)类型
TypeScript 复制代码
const withAuth = <P extends object>(Component: React.ComponentType<P>) => {
  return (props: P) => {
    const isLoggedIn = true;
    if (!isLoggedIn) return <div>请登录</div>;
    return <Component {...props} />;
  };
};

五、TypeScript 配置文件 tsconfig.json 常用配置

TypeScript 复制代码
{
  "compilerOptions": {
    "target": "es5",                 // 编译目标
    "lib": ["dom", "es2015"],        // 包含的类型库
    "jsx": "react",                  // JSX 编译方式
    "strict": true,                  // 启用所有严格类型检查
    "esModuleInterop": true,         // 支持 CommonJS 和 ES 模块互操作
    "skipLibCheck": true,            // 跳过库文件类型检查
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"]
}
相关推荐
大雷神3 小时前
HarmonyOS APP<玩转React>开源教程二十一:测验服务层实现
前端·react.js·开源·harmonyos
apcipot_rain3 小时前
事无巨细地解释一个vue前端网页
前端·javascript·vue.js
han_3 小时前
JavaScript设计模式(三):代理模式实现与应用
前端·javascript·设计模式
~欲买桂花同载酒~3 小时前
项目安装- React + TypeScript
前端·react.js·typescript
光辉GuangHui3 小时前
SDD 实践:OpenSpec + Superpowers 整合创建自定义工作流
前端·后端
ssshooter3 小时前
infer,TS 类型系统的手术刀
前端·面试·typescript
用户3167361303423 小时前
图片懒加载,我总结了三个方式
前端
灰太狼大大王3 小时前
2026 前端基石:HTML5 全景知识体系指南(从入门到架构师思维)
前端
米丘3 小时前
vue-router 5.x 文件式路由
前端·vue.js