带有动态分配的 Typescript 2.9 错误

Posted

技术标签:

【中文标题】带有动态分配的 Typescript 2.9 错误【英文标题】:Typescript 2.9 error with dynamic assignment 【发布时间】: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。您确定该错误消息吗? 【参考方案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 似乎有一些粗糙的边缘。再次感谢...

以上是关于带有动态分配的 Typescript 2.9 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中为对象动态分配属性?

如何在 TypeScript 中为对象动态分配属性?

如何在 TypeScript 中为类属性动态分配值

带有接口的Typescript中的Json枚举?

带有约束的打字稿泛型不能分配给泛型接口

带有 Typescript 和 react-redux 的有状态组件:“typeof MyClass”类型的参数不可分配给 Component 类型的参数