javascript - reactjs + typescript 出现错误:类型“字符串”不可分配给类型“从不”
问题描述
在完成 axios 请求后,我正在尝试使用 componentDidMount 设置状态,但出现错误Type 'string' is not assignable to type 'never'.
下面是代码
import * as React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import axios from 'axios';
import {
updateFilterByCategory,
UpdateFilterRequest,
} from 'ducks/search/filters/reducer';
import { GlobalState } from 'ducks/rootReducer';
import { APPLY_BTN_TEXT } from '../constants';
interface OwnProps {
categoryId: string;
}
interface StateFromProps {
value: string;
}
interface DispatchFromProps {
updateFilter: (
categoryId: string,
value: string | undefined,
) => UpdateFilterRequest;
}
export type InputFilterProps = StateFromProps & DispatchFromProps & OwnProps;
export interface InputFilterState {
value: string;
dropDownValue: {};
}
export class InputFilter extends React.Component<
InputFilterProps,
InputFilterState
> {
constructor(props) {
super(props);
this.state = {
value: props.value,
dropDownValue: {dept: [],
items: [],
emp: [],
}
};
}
componentDidMount = (prevProps: StateFromProps) => {
axios.get("/api/data")
.then(response=>{
Object.keys(response["result"]).map((key, value)=>{
this.setState(prevState => {
let dropDownValue = {...prevState.dropDownValue};
dropDownValue[key] = value
return {dropDownValue}
})
})
})
.catch(error=>{
console.log(error)
})
};
componentDidUpdate = (prevProps: StateFromProps) => {
const newValue = this.props.value;
if (prevProps.value !== newValue) {
this.setState({ value: newValue || '' });
}
};
onApplyChanges = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (this.state.value) {
this.props.updateFilter(this.props.categoryId, this.state.value);
} else {
this.props.updateFilter(this.props.categoryId, undefined);
}
};
onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ value: e.target.value });
};
render = () => {
const { categoryId } = this.props;
return (
<form
className="input-section-content form-group"
onSubmit={this.onApplyChanges}
>
<input
list={categoryId}
className="form-control dropdown-input"
name={categoryId}
id={categoryId}
onChange={this.onInputChange}
value={this.state.value}
/>
<button name={categoryId} className="btn btn-default" type="submit">
{APPLY_BTN_TEXT}
</button>
</form>
);
};
}
export const mapStateToProps = (state: GlobalState, ownProps: OwnProps) => {
const filterState = state.search.filters;
const value = filterState[state.search.resource]
? filterState[state.search.resource][ownProps.categoryId]
: '';
return {
value: value || '',
};
};
export const mapDispatchToProps = (dispatch: any) =>
bindActionCreators(
{
updateFilter: (categoryId: string, value: string | undefined) =>
updateFilterByCategory({ categoryId, value }),
},
dispatch
);
export default connect<StateFromProps, DispatchFromProps, OwnProps>(
mapStateToProps,
mapDispatchToProps
)(InputFilter);
错误日志
#23 59.03 ERROR in /app/static/js/pages/SearchPage/SearchFilter/FilterSection/index.tsx
#23 59.03 ./js/pages/SearchPage/SearchFilter/FilterSection/index.tsx
#23 59.03 [tsl] ERROR in /app/static/js/pages/SearchPage/SearchFilter/FilterSection/index.tsx(48,15)
#23 59.03 TS2322: Type '{ categoryId: string; }' is not assignable to type 'Readonly<Omit<never, "value" | "updateFilter"> & OwnProps>'.
#23 59.03 Property 'categoryId' is incompatible with index signature.
#23 59.03 Type 'string' is not assignable to type 'never'.
#23 59.03 @ ./js/pages/SearchPage/SearchFilter/index.tsx 5:0-44 15:40-53
#23 59.03 @ ./js/pages/SearchPage/index.tsx 11:0-42 88:36-48
#23 59.03 @ ./js/index.tsx 21:0-44 48:69-79
#23 59.03
#23 59.03 ERROR in /app/static/js/pages/SearchPage/SearchFilter/InputFilter/index.spec.tsx
#23 59.03 [tsl] ERROR in /app/static/js/pages/SearchPage/SearchFilter/InputFilter/index.spec.tsx(31,43)
#23 59.03 TS2786: 'InputFilter' cannot be used as a JSX component.
#23 59.03 Its instance type 'InputFilter' is not a valid JSX element.
#23 59.03 Types of property 'componentDidMount' are incompatible.
#23 59.03 Type '(prevProps: StateFromProps) => void' is not assignable to type '() => void'.
#23 59.03
#23 59.03 ERROR in /app/static/js/pages/SearchPage/SearchFilter/InputFilter/index.tsx
#23 59.03 ./js/pages/SearchPage/SearchFilter/InputFilter/index.tsx
#23 59.03 [tsl] ERROR in /app/static/js/pages/SearchPage/SearchFilter/InputFilter/index.tsx(54,3)
#23 59.03 TS2416: Property 'componentDidMount' in type 'InputFilter' is not assignable to the same property in base type 'Component<InputFilterProps, InputFilterState, any>'.
#23 59.03 Type '(prevProps: StateFromProps) => void' is not assignable to type '() => void'.
#23 59.03 @ ./js/pages/SearchPage/SearchFilter/FilterSection/index.tsx 9:0-41 19:43-54
#23 59.03 @ ./js/pages/SearchPage/SearchFilter/index.tsx 5:0-44 15:40-53
#23 59.03 @ ./js/pages/SearchPage/index.tsx 11:0-42 88:36-48
#23 59.03 @ ./js/index.tsx 21:0-44 48:69-79
#23 59.03
#23 59.03 ERROR in /app/static/js/pages/SearchPage/SearchFilter/InputFilter/index.tsx
#23 59.03 ./js/pages/SearchPage/SearchFilter/InputFilter/index.tsx
#23 59.03 [tsl] ERROR in /app/static/js/pages/SearchPage/SearchFilter/InputFilter/index.tsx(138,3)
#23 59.03 TS2345: Argument of type 'typeof InputFilter' is not assignable to parameter of type 'ComponentType<never>'.
#23 59.03 Type 'typeof InputFilter' is not assignable to type 'ComponentClass<never, any>'.
#23 59.03 Construct signature return types 'InputFilter' and 'Component<never, any, any>' are incompatible.
#23 59.03 The types of 'props' are incompatible between these types.
#23 59.03 Type 'Readonly<InputFilterProps> & Readonly<{ children?: ReactNode; }>' is not assignable to type 'never'.
#23 59.03 @ ./js/pages/SearchPage/SearchFilter/FilterSection/index.tsx 9:0-41 19:43-54
#23 59.03 @ ./js/pages/SearchPage/SearchFilter/index.tsx 5:0-44 15:40-53
#23 59.03 @ ./js/pages/SearchPage/index.tsx 11:0-42 88:36-48
#23 59.03 @ ./js/index.tsx 21:0-44 48:69-79
#23 59.03
#23 59.03 webpack 5.6.0 compiled with 4 errors in 53077 ms
#23 59.38 npm ERR! code ELIFECYCLE
#23 59.38 npm ERR! errno 2
#23 59.38 npm ERR! static@1.0.0 build: `cross-env TS_NODE_PROJECT='tsconfig.webpack.json' webpack --progress --config webpack.prod.ts`
#23 59.38 npm ERR! Exit status 2
#23 59.38 npm ERR!
#23 59.38 npm ERR! Failed at the static@1.0.0 build script.
#23 59.38 npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
#23 59.39
#23 59.39 npm ERR! A complete log of this run can be found in:
#23 59.39 npm ERR! /root/.npm/_logs/2021-07-13T07_55_35_192Z-debug.log
尝试在“任何”类型的参数中寻找答案不可分配给“从不”类型
由于我是新来的反应和打字稿,尽管在互联网上寻找答案,但无法解决它。
我观察到,如果我删除 componentDidMount,它构建得很好,没有错误。prevProps: StateFromProps
如果我从中删除componentDidMount = (prevProps: StateFromProps)
并保留,componentDidMount = ()
那么它也可以正常工作。
我究竟做错了什么?
提前致谢!
解决方案
无论您的问题如何,您的代码中都有很多问题。
其中之一是axios
错误地使用响应。
axios.get("/api/data")
.then(response=>{
Object.keys(response["result"]).map((key, value)=>{
您似乎正在尝试result
从 request访问body
。为此,您应该通过response.data.result
;
除此之外,出现问题的根源在于您interface
错误地声明了您的状态。
export interface InputFilterState {
value: string;
dropDownValue: {};
}
断言{}
type fordropDownValue
意味着该键只能包含 EMPTY OBJECT ( never
)。您正在尝试dropDownValue
使用string
基于密钥 ( dropDownValue[key]
) 来访问某些属性。因此,TypeScript 抱怨您无法从声明为空对象的对象中检索带有字符串键的值。
为了相应地声明它,您可以dropDownValue
在界面中声明正确的类型。
export interface InputFilterState {
value: string;
dropDownValue: {
value: props.value,
dropDownValue: {
dept: [],
items: [],
emp: [],
}
};
}
推荐阅读
- javascript - 来自谷歌地图的自动填写表单地址
- php - 如何使用 php-di 正确注入可重用的控制器注入
- powershell - 名为 C 的驱动器不存在
- reactjs - 如何在 Redux 表单字段中显示动态值并处理 onChange 事件
- objective-c - 在 UITableViewCell 中设置 UISwitch 会触发其他 UISwitch
- python - 如何使用 python 从 https://www.bayut.com/index/sale-prices-2-bed-apartments-al-raha-beach.html 获取图形数据
- testing - TestCafe:具有动态 ID 的 Web 应用程序(XAF 应用程序)
- typescript - TypeScript generics: how to define type T which is structurally the same as other type S
- python - 具有张量流概率的贝叶斯线性回归
- c# - 如何覆盖 HashSet 的 + 运算符
在c#中