TypeScript报错:new表达式缺构造签名、参数不匹配问题求助
解决TypeScript reducer中throw new Error的类型错误
报错信息
在reducer函数的default分支执行throw new Error('Action unknown');时,出现两个TypeScript报错:
'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.ts(7009)Expected 0 arguments, but got 1.ts(2554)
问题代码
import { useEffect, useReducer } from 'react'; import Header from './Header'; import MainContent from './MainContent'; import Loader from './Loader'; import Error from './Error'; import StartScreen from './StartScreen'; import Question from './Question'; interface Question { question: string; options: string[]; correctOption: number; points: number; } type State = { questions: Question[]; status: 'ready' | 'error' | 'loading' | 'active' | 'finished'; index: number; }; export type Action = | { type: 'dataReceived'; payload: Question[]; } | { type: 'dataFailed'; } | { type: 'unknown'; } | { type: 'start'; }; const initialState: State = { questions: [], // "loading", "error", "ready", "active", "finished" status: 'loading', index: 0, }; function reducer(state: State, action: Action): State { switch (action.type) { case 'dataReceived': return { ...state, questions: action.payload, status: 'ready', }; case 'dataFailed': return { ...state, status: 'error', }; case 'start': return { ...state, status: 'active', }; default: throw new Error('Action unknown'); } } function App() { const [{ questions, status, index }, dispatch] = useReducer( reducer, initialState ); const numQuestions: number = questions.length; useEffect(function () { fetch('http://localhost:8000/questions') .then(res => res.json()) .then(data => dispatch({ type: 'dataReceived', payload: data })) // eslint-disable-next-line @typescript-eslint/no-unused-vars .catch(_err => dispatch({ type: 'dataFailed' })); }, []); return ( <div className="app"> <Header /> <MainContent> {status === 'loading' && <Loader />} {status === 'error' && <Error />} {status === 'ready' && ( <StartScreen numQuestions={numQuestions} dispatch={dispatch} /> )} {status === 'active' && <Question question={questions[index]} />} </MainContent> </div> ); } export default App;
错误原因
核心问题是命名冲突:你导入了自定义的React组件Error(import Error from './Error';),这个组件名直接覆盖了全局的原生Error构造函数。当你在reducer里执行new Error('Action unknown')时,TypeScript会把这里的Error识别为你导入的自定义组件,而非原生Error类:
- 自定义
Error组件是React组件,没有构造签名(不能用new关键字实例化),触发第一个报错; - 自定义组件的渲染逻辑不需要传入字符串参数,你传入了
'Action unknown',触发第二个报错。
解决方案
给自定义的Error组件重命名,避免和全局Error构造函数冲突:
- 修改导入语句,给组件起别名:
import ErrorComponent from './Error';
- 在JSX渲染中使用别名:
{status === 'error' && <ErrorComponent />}
修改后,new Error('Action unknown')会正确指向原生Error构造函数,两个报错都会消失。
内容的提问来源于stack exchange,提问作者Markewycz
相关产品推荐
相关产品推荐

