简体   繁体   English

TypeScript部分接口对象

[英]TypeScript partial interface object

In React, the Component definition looks something like this: 在React中, Component定义如下所示:

class Component<S> {
    state:S;
    setState(state:S):void;
}

And you define a component like this: 你定义一个这样的组件:

interface MyState {
    name: string;
    age: number;
}
class MyComponent extends Component<MyState> { }

Now the issue I have is that in the React API setState is supposed to be called with a partial state object, representing properties to be updated, like this: 现在的问题是,在React API中, setState应该使用部分状态对象调用,表示要更新的属性,如下所示:

setState({name: "Aaron"});

Note that age is not declared. 请注意,未声明age The problem I have is that TypeScript doesn't allow this, it gives an assignment error like Property 'age' is missing . 我遇到的问题是TypeScript不允许这样做,它会给出一个分配错误,比如Property 'age' is missing By my understanding, the react.d.ts definition is wrong in this sense. 根据我的理解, react.d.ts定义在这个意义上是错误的。 But is there a solution? 但是有解决方案吗?

I tried this: 我试过这个:

setState({name: "Aaron"} as MyState);

But this gives the same error, even though it works in the Playground without giving an error. 但是这会产生相同的错误,即使它在Playground中工作而不会出错。 Why does it work in the Playground? 为什么它在游乐场有效? Any ideas? 有任何想法吗?

"Partial types" are still missing in TypeScript currently, see TypeScript issue #4889 as well as this related question . 当前TypeScript中仍然缺少“部分类型”,请参阅 TypeScript问题#4889以及 此相关问题 I'm afraid it's not yet possible to make this type-check correctly. 我担心还不能正确地进行这种类型检查。

\n

You might get away with marking all fields of your MyState interface as optional (by adding ? modifiers), but that in turn weakens the type-checking for things like Component.state (where you want all fields to be set). 可能会将 MyState接口的所有字段都标记为可选(通过添加 ?修饰符),但这反过来会削弱对 Component.state (您希望设置 所有字段的位置)的类型检查。

EDIT (December 2016): TypeScript 2.1 introduces mapped types , which supports describing partial types using Partial<T> ! 编辑(2016年12月): TypeScript 2.1引入了映射类型 ,支持使用Partial<T>描述部分类型 Now you can use the following type definition for Component : 现在,您可以对Component使用以下类型定义:

class Component<S> {
    state: S;
    setState(state: Partial<S>) : void;
}

The react.d.ts definition is indeed wrong, and cannot be fixed until Partial Types are supported. react.d.ts定义确实是错误的,并且在支持部分类型之前无法修复。

The problem is that setState takes a partial state, which is a different type from normal state. 问题是setState采用部分状态,这是一种与正常状态不同的类型。 You can solve this by manually specifying both types: 您可以通过手动指定两种类型来解决此问题:

interface MyState {
    name: string;
    age: number;
}

interface PartialMyState {
    name?: string;
    age?: number;
}

And manually declaring MyComponent without extending the provided React Component class: 并手动声明MyComponent而不扩展提供的React Component类:

class MyComponent {
    state: MyState;
    setState(state:PartialMyState): void;
    //...
}

Which means you'll have to duplicate these function definitions for every subclass of Component in your code. 这意味着您必须为代码中的每个Component子类复制这些函数定义。 You may be able to avoid this by defining a correct Component class generalized by an additional type of partial state: 您可以通过定义由其他类型的部分状态推广的正确Component类来避免这种情况:

class CorrectComponent<S,P> { // generalized over both state and partial state
    state:S;
    setState(state:P):void;
    //...
}

class MyComponent extends CorrectComponent<MyState,PartialMyState> { }

You'll still have to write a partial version for every state type you have. 您仍然需要为您拥有的每种州类型编写部分版本。


Alternatively, you can make setState non-typesafe by changing its argument's type to Object . 或者,您可以通过将其参数的类型更改为Object来使setState非类型安全。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM