[英]Argument of type 'File' is not assignable to parameter of type 'never'. React with TypeScript
[英]React TypeScript: Argument is not assignable to parameter of type 'never'
我的路由器有一个useReducer
并且 initialState 有错误Argument of type 'StateInterface' is not assignable to parameter of type 'never'.
这仅在我在 globalState.tsx 的减速器中使用action.value
时才开始发生
(Router.tsx)
import React, { useReducer } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { Layout } from './components/layout';
import { Dispatch, Global, InitialState, Reducer } from './globalState';
import { Home } from './routes/home';
import { NotFound } from './routes/notFound';
const Router: React.FC = () => {
const [global, dispatch] = useReducer(Reducer, InitialState); //<==== Here is the error
return (
<Dispatch.Provider value={{ dispatch }}>
<Global.Provider value={{ global }}>
<BrowserRouter>
<Route
render={({ location }) => (
<Layout location={location}>
<Switch location={location}>
<Route exact path='/' component={Home} />
<Route component={NotFound} />
</Switch>
</Layout>
)}
/>
</BrowserRouter>
</Global.Provider>
</Dispatch.Provider>
);
};
export { Router };
然后全局状态看起来像
(globalState.tsx)
import { createContext } from 'react';
interface StateInterface {
warningMessage: string;
warningShow: boolean;
}
interface ActionInterface {
type: string;
value: string | boolean;
}
const Dispatch = createContext({
dispatch: (action: ActionInterface) => {
//
},
});
const InitialState: StateInterface = {
warningMessage: '',
warningShow: false,
};
const Global = createContext({
global: InitialState,
});
const WARNING_TOGGLE = 'WARNING_TOGGLE';
const WARNING_MESSAGE = 'WARNING_MESSAGE';
const Reducer = (state: StateInterface, action: ActionInterface) => { // <= if I change ActionInterface to any the probem goes away, but my linter then fires of with no any allowed
switch (action.type) {
case 'WARNING_TOGGLE':
return {
...state,
warningShow: action.value, // <== If I remove `action.value and set this to `true` the error goes away
};
case 'WARNING_MESSAGE':
return {
...state,
warningMessage: action.value, // <== If I remove `action.value and set this to `some string` the error goes away
};
default:
return state;
}
};
export { Reducer, InitialState, Dispatch, Global, WARNING_TOGGLE, WARNING_MESSAGE };
和家
(home.tsx)
import React, { useContext } from 'react';
import { Dispatch, Global, WARNING_MESSAGE, WARNING_TOGGLE} from '../globalState';
const Home: React.FC = () => {
const { global } = useContext(Global);
const { dispatch } = useContext(Dispatch);
const openWarning = () => {
dispatch({ type: WARNING_TOGGLE, value: true});
};
const closeWarning = () => {
dispatch({ type: WARNING_TOGGLE, value: false});
};
const warningMessageVerify = () => {
dispatch({ type: WARNING_MESSAGE, value: 'Please verify your email'});
};
const warningMessageOffine = () => {
dispatch({ type: WARNING_MESSAGE, value: 'You are now offline'});
};
return (
<section>
{global.warningShow && <div>Warning Open</div>}
{!global.warningShow && <div>Warning Closed</div>}
{global.warningMessage}
<br/>
<button onClick={openWarning}>Open Warning</button>
<button onClick={closeWarning}>Close Warning</button>
<button onClick={warningMessageVerify}>Verify Email</button>
<button onClick={warningMessageOffine}>Offline</button>
</section>
);
};
export { Home };
Typescript 无法从IActionInterface
value: string | boolean
确定安全类型转换value: string | boolean
value: string | boolean
到StateInterface
warningShow: boolean
,在此代码中 - warningShow: action.value
。 不能安全地假定value
将只包含一个布尔值。
有几种方法可以抑制这种情况,一个简单的方法是——
warningShow: action.value as boolean
warningMessage: action.value as string
as
关键字将断言value
的类型是boolean
或string
。
最好的做法是分别为动作创建者定义类型。
代替
interface ActionInterface {
type: string;
value: string | boolean;
}
使用两个接口并在此基础上定义类型
interface IActionInterface {
type: string;
}
interface IMessageActionInterface extends IActionInterface {
value: string;
}
interface IShowActionInterface extends IActionInterface {
value: boolean;
}
type ActionTypes = IMessageActionInterface | IShowActionInterface;
在减速机中
const Reducer = (state: StateInterface, action: ActionTypes) => { }
如果您没有从箭头函数中明确返回某些内容,这似乎很奇怪。 我相信这被解释为“从不”。 所以,对我来说,这似乎是个问题。 如果我错了,对不起。
const Dispatch = createContext({
dispatch: (action: ActionInterface) => {
//
},
});
该问题与您构造ActionInterface
类型并在减速器中使用它的方式有关。
您需要的是在将操作结构传递给 switch 语句时,让 TypeScript 有一种方法来区分动作结构。
解决这个问题的最好方法是简单地给 TypeScript 一个关于你的操作和你拥有的联合类型的提示。
在TypeScript playground看这个例子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.