选择< S,K>使用动态/计算键键入 [英] Pick<S, K> type with dynamic/computed keys

查看:77
本文介绍了选择< S,K>使用动态/计算键键入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最新的 @ types / react v15.0.6 )利用TypeScript 2.1中为 setState ,即 Pick< S,K> 。这是一件好事,因为现在的输入是正确的,因为在更新之前不知道 setState 正在合并 this.state。 ,而不是替换它。

The latest @types/react (v15.0.6) make use of features added in TypeScript 2.1 for setState, namely Pick<S, K>. Which is a good thing, because now the typings are correct, because before the update typings "didn't know" that setState is merging this.state, rather than replacing it.

此外,使用 Pick 可以使 setState 函数在允许输入方面非常严格。无法再将未在组件定义中定义的属性添加到状态 React.Component

Also, using Pick makes the setState function very strict in terms of allowed input. It is no longer possible to add properties to the state that aren't defined in the component definition (second generic of React.Component.

但是定义动态更新处理程序也比较困难,例如:

But it is also harder to define a dynamic update handler. For example:

import * as React from 'react';


interface Person {
  name: string;
  age: number|undefined;
}


export default class PersonComponent extends React.Component<void, Person> {
  constructor(props:any) {
    super(props);

    this.state = { 
      name: '',
      age: undefined
    };
    this.handleUpdate = this.handleUpdate.bind(this);
  }

  handleUpdate (e:React.SyntheticEvent<HTMLInputElement>) {
    const key = e.currentTarget.name as keyof Person;
    const value = e.currentTarget.value;
    this.setState({ [key]: value });
  }

  render() {
    return (
      <form>
        <input type="text" name="name" value={this.state.name} onChange={this.handleUpdate} />
        <input type="text" name="age" value={this.state.age} onChange={this.handleUpdate} />
      </form>
    );
  }
}

setState 函数将引发以下错误

[ts] Argument of type '{ [x: string]: string; }' is not assignable 
     to parameter of type 'Pick<Person, "name" | "age">'.
       Property 'name' is missing in type '{ [x: string]: string; }'.

即使的类型为名称 | 年龄

除了单独的 updateName updateAge 函数。有人知道如何将 Pick 与动态键值一起使用吗?

I can not find a solution for this, other than having a separate updateName and updateAge function. Does anyone know how to use Pick with dynamic key values?

推荐答案

因此,在进行了更多研究之后,我可以提供上面代码中发生的情况的更多上下文。

So after doing more research I can provide a little more context on what is happening in the above code.

当您执行 const name = 'Bob'变量 name 的类型为'Bob' 字符串。但是,如果将 const 替换为 let let name ='Bob')变量 name 的类型为 string

When you do something like const name = 'Bob' the type of the variable name is 'Bob' not string. However, if you replace the const with a let (let name = 'Bob') the variable name will be of type string.

这个概念称为扩大。基本上,这意味着类型系统尝试尽可能明确。因为不能重新分配 const ,所以TypeScript可以推断出确切的类型。可以重新分配 let 语句。因此,TypeScript将 string (在上面的示例中)推断为 name 的类型。

This concept is called "widening". Basically, it means that the type system tries to be as explicit as possible. Because const can not be reassigned TypeScript can infer the exact type. let statements can be reassigned. Thus, TypeScript will infer string (in the above example) as the type of name.

const key = e.currentTarget.name作为Person 的情况也是如此。 的类型(联盟)为 name | age ,这正是我们想要的是。 但是在表达式 this.setState({[key]:value}); 变量 key (错误地)扩展为字符串

The same is happening with const key = e.currentTarget.name as keyof Person. key will be of (union) type "name"|"age", which is exactly what we want it to be. But in the expression this.setState({ [key]: value }); variable key is (incorrectly) widened to a string.

tl; dr; 似乎TypeScript中存在错误。我将问题发布到了Github仓库,TypeScript团队正在调查问题。 :)

tl;dr; It seems like there is a bug in TypeScript. I posted the issue to the Github repo and the TypeScript team is investigating the problem. :)

作为临时解决方法,您可以执行以下操作:

As a temporary workaround you can do:

this.setState({ [key as any]: value });

这篇关于选择&lt; S,K&gt;使用动态/计算键键入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆