使用这段代码:
else if (event.target.id == 'filter') {
this.setState({ [event.target.id]: event.target.value });
我得到这个 typescript 错误: TS2345 TypeScript (TS) 类型的参数 '{ [x: number]: any; }' 不可分配给类型为 '{ id: number; 的参数重定向: bool 值;过滤器:字符串;玩家:玩家; } | ((prevState: Reado...'.' ...
但如果我改为这样做:
else if (event.target.id == 'filter') {
this.setState({ filter: event.target.value });
没有错误。尽管有错误,代码运行正常。我认为这是从 TypeScript 2.9 开始的。我意识到我可以只使用第二个示例,但我还有其他代码,例如:
handleChange(event) {
if (event.target.type == 'checkbox') {
this.setState({ [event.target.id]: event.target.checked });
} else {
this.setState({ [event.target.id]: event.target.value });
}
}
这很有用。在 TypeScript 2.9 中有没有更好的方法来做到这一点?
更新:也相关:
type PlayerListState = {
id: number,
redirect: boolean,
filter: string,
player: GamePlayer
};
class PlayerListComponent extends React.Component<PlayerListProps, PlayerListState> {
以及来自 React 的 SetState 的类型定义:
setState<K extends keyof S>(
state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
callback?: () => void
): void;
最佳答案
当我的元素类型有可能不是我所期望的那样时,我倾向于束手无策。
这是一个改编自 this blog post on narrowing types 的例子.
function isInputElement(target: EventTarget | any): target is HTMLInputElement {
if (!target) {
return false;
}
return (target.tagName && target.tagName === 'INPUT')
}
// Note: Arbitrary element selection to make the demo complete :)
document.getElementById('filter').onload = (e) => {
const target = e.target;
if (!isInputElement(target)) {
return;
}
if (target.id == 'filter') {
this.setState({ [target.id]: target.value });
}
}
在类型保护中,当事件目标实际上不是 INPUT 元素时,您可以抛出异常、记录消息或采取任何需要的操作。
关于动态分配的 Typescript 2.9 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50721250/