Aar*_*all 12 typescript reactjs
在React中,Component定义如下所示:
class Component<S> {
state:S;
setState(state:S):void;
}
Run Code Online (Sandbox Code Playgroud)
你定义一个这样的组件:
interface MyState {
name: string;
age: number;
}
class MyComponent extends Component<MyState> { }
Run Code Online (Sandbox Code Playgroud)
现在的问题是,在React API setState中应该使用部分状态对象调用,表示要更新的属性,如下所示:
setState({name: "Aaron"});
Run Code Online (Sandbox Code Playgroud)
请注意,age未声明.我遇到的问题是TypeScript不允许这样做,它给出了一个赋值错误Property 'age' is missing.根据我的理解,这个react.d.ts定义在这个意义上是错误的.但是有解决方案吗?
我试过这个:
setState({name: "Aaron"} as MyState);
Run Code Online (Sandbox Code Playgroud)
但是这会产生相同的错误,即使它在Playground中工作而不会出错.为什么它在游乐场有效?有任何想法吗?
Mat*_*ens 17
当前TypeScript中仍然缺少"部分类型",请参阅TypeScript问题#4889以及此相关问题.我担心还不能正确地进行这种类型检查.
您可能会将MyState界面的所有字段标记为可选(通过添加?修饰符),但这反过来会削弱类似检查Component.state(如果您希望设置所有字段).
编辑(2016年12月): TypeScript 2.1引入了映射类型,支持使用!来描述部分类型Partial<T>!现在,您可以使用以下类型定义Component:
class Component<S> {
state: S;
setState(state: Partial<S>) : void;
}
Run Code Online (Sandbox Code Playgroud)
该react.d.ts定义的确是错误的,不能固定到部分类型的支持。
问题是它setState需要一个部分状态,这是与正常状态不同的类型。您可以通过手动指定两种类型来解决此问题:
interface MyState {
name: string;
age: number;
}
interface PartialMyState {
name?: string;
age?: number;
}
Run Code Online (Sandbox Code Playgroud)
并手动声明MyComponent而不扩展提供的 ReactComponent类:
class MyComponent {
state: MyState;
setState(state:PartialMyState): void;
//...
}
Run Code Online (Sandbox Code Playgroud)
这意味着您必须为Component代码中的每个子类复制这些函数定义。您可以通过定义Component由附加类型的部分状态概括的正确类来避免这种情况:
class CorrectComponent<S,P> { // generalized over both state and partial state
state:S;
setState(state:P):void;
//...
}
class MyComponent extends CorrectComponent<MyState,PartialMyState> { }
Run Code Online (Sandbox Code Playgroud)
您仍然需要为您拥有的每个状态类型编写一个部分版本。
或者,您可以setState通过将其参数的类型更改为Object.
| 归档时间: |
|
| 查看次数: |
7545 次 |
| 最近记录: |