React+TypeScript使用createContext出现TS2339错误的技术求助
问题场景
用Vite开发React+TypeScript简易计算器,首次接触React+TypeScript,对ContextAPI用法不熟悉。执行yarn build时出现类型错误:
src/components/Screen.tsx:5:11 - error TS2339: Property 'showOnScreen' does not exist on type '{}'.
const { showOnScreen, onDeleteButton } = useContext(AppContext);
相关文件代码如下:
AppContext.tsx
import { createContext } from 'react'; export const AppContext = createContext({});
ContextProvider.tsx
import { useState } from 'react'; import { AppContext } from './'; type Props = { children: React.ReactNode; }; export const ContextProvider: React.FC<Props> = ({ children }) => { const [showOnScreen, setShowOnScreen] = useState('0'); const [isLastAResult, setIsLastAResult] = useState(false); const onDeleteButton = () => { if (showOnScreen.length === 1 || isLastAResult) { setShowOnScreen('0'); setIsLastAResult(false); return; } setShowOnScreen(showOnScreen.substring(0, showOnScreen.length - 1)); }; return ( <AppContext.Provider value={{ onDeleteButton, showOnScreen, }} > {children} </AppContext.Provider> ); };
Screen.tsx
import { useContext } from 'react'; import { AppContext } from '../context'; export const Screen = () => { const { showOnScreen, onDeleteButton } = useContext(AppContext); return ( <div className='row bg-white rounded-4'> <div className='col-12 pe-0 d-flex justify-content-between align-items-center'> <span className='py-2 fs-4'>{showOnScreen}</span> <button className='text-danger rounded-start btn rounded-4 h-100 fs-5' onClick={onDeleteButton} > DEL </button> </div> </div> ); };
解决方法
错误根源是Context创建时未定义正确的类型,TypeScript无法推断AppContext的value结构,默认将其识别为空对象{},因此解构showOnScreen和onDeleteButton时触发类型错误。
步骤1:定义Context值的类型接口
修改AppContext.tsx,先声明Context值的类型,再基于该类型创建Context并提供符合类型的默认值(避免组件未被Provider包裹时出现异常):
import { createContext } from 'react'; // 定义Context值的类型 type AppContextType = { showOnScreen: string; onDeleteButton: () => void; }; // 用指定类型创建Context export const AppContext = createContext<AppContextType>({ showOnScreen: '0', onDeleteButton: () => {} });
步骤2:验证Provider的value匹配类型
此时ContextProvider.tsx中的value会自动匹配AppContextType,后续如果修改value结构,TypeScript会自动提示类型错误,避免属性遗漏。
步骤3:确保根组件被ContextProvider包裹
确认根组件(如App.tsx)已被ContextProvider包裹,否则useContext会拿到默认值,导致功能异常:
import { ContextProvider } from './context/ContextProvider'; import { Screen } from './components/Screen'; function App() { return ( <ContextProvider> <Screen /> {/* 其他计算器组件 */} </ContextProvider> ); } export default App;
完成以上修改后,TypeScript即可正确识别Context中的属性,yarn build将不再报类型错误。
内容的提问来源于stack exchange,提问作者LugpDev2022

