【问题标题】:Typescript 2.9 error with dynamic assignment带有动态分配的 Typescript 2.9 错误
【发布时间】:2018-11-16 04:33:03
【问题描述】:

使用此代码:

else if (event.target.id == 'filter') {
            this.setState({ [event.target.id]: event.target.value });

我收到此打字稿错误: TS2345 TypeScript (TS) 类型参数 '{ [x: number]: any; }' 不能分配给 '{ id: number; 类型的参数;重定向:布尔值;过滤器:字符串;播放器:播放器; } | (((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;

【问题讨论】:

  • ...等等,id 不是 number 吗?它如何等于字符串"filter"
  • 这是 DOM 元素 ID。
  • 好吧,有道理
  • 不过,如果您的错误是 Argument of type '{[x: number]: any;}...,则意味着 TypeScript 认为 event.target.idnumber。您确定该错误消息吗?

标签: typescript


【解决方案1】:

当我的元素类型有可能不是我所期望的时,我倾向于束手无策。

这是一个改编自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 元素时,您可以抛出异常、记录消息或采取任何需要的操作。

【讨论】:

  • 感谢 Fenton,这真的很有帮助,还有博文。它使我前进,但我仍然遇到问题。状态是强类型的,现在它给了我: Argument of type '{ [x: string]: any; }' 不可分配给“PlayerListState ... 类型”类型的参数 { [x: string]: any; }' 不可分配给类型 'Pick' 我应该将具有这四个值之一的字符串传递给 React 组件状态,这是准确的。有没有办法让我输入类似于您已经向我展示的内容?
  • 我可能需要查看 PickPlayerListState 类型来回答那个问题。
  • 我已经用我希望有用的信息更新了这个问题@Fenton
  • 另外,Pick 被定义为 TypeScript 的一部分:medium.com/@curtistatewilkinson/…
  • 将此标记为已解决,因为您让我克服了最初的困难。我正在退回到 TypeScript 2.8,因为到目前为止,React 似乎有一些粗糙的边缘。再次感谢...
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多