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

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

问题描述

最新的 @types/react (v15.0.6) 利用 TypeScript 2.1 中为 setState 添加的功能,即 选择<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 函数在允许输入方面非常严格.不再可能向 state 添加未在组件定义中定义的属性(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; }'.

即使 key 的类型是 "name" |年龄".

除了拥有单独的 updateNameupdateAge 函数外,我找不到解决方案.有谁知道如何将 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' not 字符串.但是,如果您将 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 as keyof Person 也是如此.key 将是(联合)类型 "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天全站免登陆