Reactjs 拾取<;S、 K>;使用动态/计算键键入
最新的Reactjs 拾取<;S、 K>;使用动态/计算键键入,reactjs,generics,typescript,components,Reactjs,Generics,Typescript,Components,最新的@types/react(v15.0.6)利用了TypeScript 2.1中为setState添加的功能,即Pick。这是一件好事,因为现在打字是正确的,因为在更新之前,打字“不知道”setState正在合并this.state,而不是替换它 此外,使用Pick使得setState功能在允许输入方面非常严格。无法再向组件定义中未定义的状态添加属性(第二个React.component) 但定义动态更新处理程序也比较困难。例如: import * as React from 'react'
@types/react
(v15.0.6
)利用了TypeScript 2.1中为setState
添加的功能,即Pick
。这是一件好事,因为现在打字是正确的,因为在更新之前,打字“不知道”setState
正在合并this.state
,而不是替换它
此外,使用Pick
使得setState
功能在允许输入方面非常严格。无法再向组件定义中未定义的状态添加属性(第二个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>
);
}
}
即使键的类型是“name”|“age”
除了使用一个单独的updateName
和updateAge
函数之外,我找不到解决方案。有人知道如何使用Pick
和动态键值吗?因此,在做了更多的研究之后,我可以提供更多关于上述代码中发生了什么的上下文
当您执行类似于const name='Bob'
的操作时,变量name
的类型不是字符串。但是,如果将const
替换为let
(let name='Bob'
),变量name
的类型将是string
这个概念被称为“加宽”。基本上,它意味着类型系统试图尽可能明确。因为不能重新分配const
,TypeScript可以推断出确切的类型。let
语句可以重新分配。因此,TypeScript将推断字符串
(在上面的示例中)作为名称的类型
同样的情况也发生在const key=e.currentTarget.name as keyof Person
key
将是(联合)类型“name”|“age”
,这正是我们想要的。但是在表达式中,这个.setState({[key]:value})
变量key
被(错误地)加宽为字符串
tl;dr;似乎TypeScript中有一个bug。我将问题发布到Github repo和TypeScript团队。:)
作为临时解决方法,您可以执行以下操作:
this.setState({ [key as any]: value });
塞巴斯蒂安的回答不再适用于我(尽管在某个阶段确实如此)。我现在执行以下操作,直到它在Typescript core中得到解决(根据Sebastian答案中列出的问题):
handleUpdate(e:React.synthetic事件){
const newState={};
newState[e.currentTarget.name]=e.currentTarget.value;
this.setState(newState);
}
这很蹩脚,但很有效我想这可能会解决你的问题
type State = {
name: string,
age: number | undefined
};
type StateKeys = keyof State;
dynSetState(key: StateKeys, value: string) {
this.setState({
[key]: value
} as Pick<State, keyof State>)
}
类型状态={
名称:string,
年龄:数字|未定义
};
类型StateKeys=状态键;
dynSetState(键:状态键,值:字符串){
这是我的国家({
[键]:值
}作为选择)
}
如果该值不在可能的属性值类型集中,则仍然会相应地给出错误,但如果键不在可能的属性键集中,则不会给出错误
Ref:谢谢您的精彩解释。此问题是否已解决,或者是否有其他解决方法?
handleUpdate (e:React.SyntheticEvent<HTMLInputElement>) {
const newState = {};
newState[e.currentTarget.name] = e.currentTarget.value;
this.setState(newState);
}
type State = {
name: string,
age: number | undefined
};
type StateKeys = keyof State;
dynSetState(key: StateKeys, value: string) {
this.setState({
[key]: value
} as Pick<State, keyof State>)
}