React+TypeScript环境下Octokit使用报错及类型定义问题
React+TypeScript中使用Octokit的问题解决及类型定义获取
一、模块解析错误的解决
你遇到的Module parse failed: Cannot use 'arguments' in class field initializer错误,是因为@octokit/rest@20.x的构建产物使用了Create React App 5.x默认Babel配置不支持的语法,提供两种解决方式:
方案1:降级@octokit/rest版本
修改package.json中的依赖版本:
"@octokit/rest": "^19.0.7"
重新安装依赖:
npm install # 或 yarn install
方案2:改用@octokit/core(轻量替代)
如果不需要@octokit/rest的全量功能,可切换到更基础的@octokit/core:
npm install @octokit/core # 或 yarn add @octokit/core
代码中替换导入语句:
import { Octokit } from "@octokit/core";
二、获取接口响应的正确类型定义
针对GET /users/{owner}/repos接口,响应是仓库对象数组,通过@octokit/openapi-types获取类型的步骤:
- 导入openapi类型:
import { components, operations } from '@octokit/openapi-types';
- 定义对应类型:
// 单个GitHub仓库的类型 type GitHubRepository = components["schemas"]["repository"]; // GET /users/{owner}/repos接口的响应类型(数组) type GetUserReposResponse = operations["rest/repos/list-for-user"]["responses"]["200"]["content"]["application/json"];
三、修正后的完整代码
import React from 'react'; import { Grid } from '@mui/material'; import { Octokit } from '@octokit/rest'; // 或替换为@octokit/core import { components, operations } from '@octokit/openapi-types'; // 定义正确的类型 type GitHubRepository = components["schemas"]["repository"]; type GetUserReposResponse = operations["rest/repos/list-for-user"]["responses"]["200"]["content"]["application/json"]; const octokit = new Octokit(); export const ProjectCardList: React.FC = () => { // 给state指定明确类型 const [projects, setProjects] = React.useState<GitHubRepository[]>([]); React.useEffect(() => { // 内部定义async函数,避免useEffect直接返回Promise const fetchRepos = async () => { try { const result = await octokit.request('GET /users/{owner}/repos', { owner: 'mojombo' }); // octokit响应的data字段才是接口返回的实际数据 const filteredRepos = result.data.filter(repo => repo.owner.login === 'mojombo'); setProjects(filteredRepos); } catch (err) { console.error('获取仓库失败:', err); } }; fetchRepos(); }, []); React.useEffect(() => { console.log(projects) }, [projects]); return ( <div style={{padding: '2em' }}> <Grid container spacing={6} justifyContent="space-evenly" sx={{overflowX: 'hidden'}} > {/* 可在此渲染仓库列表,示例: {projects.map(repo => ( <Grid item key={repo.id}> <div>{repo.name}</div> </Grid> ))} */} </Grid> </div> ) } export default ProjectCardList;
额外注意事项
useEffect的回调不能直接是async函数,因为async函数返回Promise,而useEffect要求回调返回清理函数或undefined,需在内部定义async函数并调用。- Octokit的
request方法返回的对象中,data属性才是接口的实际响应数据,不要直接对result调用filter。 - 若使用原生fetch,类型定义同样适用:
const fetchRepos = async () => { const res = await fetch('https://api.github.com/users/mojombo/repos'); const resultJSON: GetUserReposResponse = await res.json(); setProjects(resultJSON.filter(repo => repo.owner.login === 'mojombo')); };
内容的提问来源于stack exchange,提问作者CodeoftheWarrior
相关产品推荐
相关产品推荐

