Seb*_*ald 8 generics components typescript reactjs
最新的@types/react(v15.0.6)使用TypeScript 2.1中添加的功能setState,即Pick<S, K>.这是一件好事,因为现在打字是正确的,因为在更新打字之前"不知道" setState正在合并this.state,而不是替换它.
此外,使用Pick使得setState功能在允许输入方面非常严格.不再可以向state组件定义中未定义的属性添加属性(第二个通用属性)React.Component.
但是定义动态更新处理程序也更难.例如:
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
该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; }'.
Run Code Online (Sandbox Code Playgroud)
即使类型key是"name" | "age".
我无法找到一个解决方案,比拥有一个单独的其他updateName和updateAge功能.有谁知道如何使用Pick动态键值?
Seb*_*ald 11
因此,在做了更多的研究后,我可以提供更多关于上述代码中发生的事情的背景.
当你这样做const name = 'Bob'的变量的类型name是'Bob' 不是字符串.但是,如果const用a 替换let(let name = 'Bob'),变量name将是类型string.
这个概念被称为"拓宽".基本上,这意味着类型系统试图尽可能明确.因为const无法重新分配TypeScript可以推断出确切的类型.let语句可以重新分配.因此,TypeScript将推断string(在上面的例子中)作为类型name.
同样的事情正在发生const key = e.currentTarget.name as keyof Person.key将是(联合)类型"name"|"age",这正是我们想要的.但是在表达式this.setState({ [key]: value });变量key中(错误地)扩展为a string.
TL;博士; 似乎TypeScript中存在一个错误.我将问题发布到Github repo,TypeScript团队正在研究这个问题.:)
作为临时解决方法,您可以:
this.setState({ [key as any]: value });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3429 次 |
| 最近记录: |