如何使用TypeScript创建可传递状态设置函数的React Context
报错原因及解决方案
报错原因
你在定义MoviesContext的类型时,指定setSelectedMovie的类型是(value: number) => void,但创建Context的默认值时传入了null,两者类型不匹配所以触发TypeScript报错。
解决方案(按推荐度排序)
方案1(最推荐):使用占位空函数作为默认值
实际业务中所有消费MoviesContext的组件都会被MoviesContext.Provider包裹,默认值几乎不会被触发,直接给一个匹配类型的空函数即可:
// context.tsx 修改后代码 import React from "react"; import { Movie } from "./movies.service"; export const MoviesContext = React.createContext<{ movies: Movie[]; selectedMovie: number; setSelectedMovie: (value: number) => void; }>({ movies: [], selectedMovie: 0, setSelectedMovie: () => {}, // 替换null为匹配类型的空函数 });
方案2:修改类型允许null值
如果你确实需要保留null作为默认值,可以调整Context的类型定义,把setSelectedMovie设为可空类型:
// 调整类型定义 export const MoviesContext = React.createContext<{ movies: Movie[]; selectedMovie: number; setSelectedMovie: ((value: number) => void) | null; // 新增null类型 }>({ movies: [], selectedMovie: 0, setSelectedMovie: null, });
注意修改类型后,消费Context时需要先做非空判断再调用,避免运行时报错:
const { setSelectedMovie } = useContext(MoviesContext); // 可选链调用 setSelectedMovie?.(123); // 或者确定非空的情况下加非空断言 setSelectedMovie!(123);
方案3(不推荐):使用类型断言跳过检查
如果你确定默认值永远不会被用到,可以用类型断言强制把null匹配为函数类型,绕过TypeScript校验:
setSelectedMovie: null as unknown as (value: number) => void
该方案会跳过类型检查,存在运行时调用出错的风险,不推荐优先使用。
内容的提问来源于stack exchange,提问作者rumon
相关产品推荐
相关产品推荐

