首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在TypeScript中扩展React组件

在TypeScript中扩展React组件
EN

Stack Overflow用户
提问于 2015-09-30 20:47:49
回答 2查看 11.4K关注 0票数 26

我在TypeScript中使用React.js。有没有办法创建从其他组件继承而来的React组件,但又有一些额外的属性/状态?

我试图实现的东西是这样的:

代码语言:javascript
复制
interface BaseStates {
    a: number;
}

class GenericBase<S extends BaseStates> extends React.Component<void, S> {
    protected getBaseInitialState(): BaseStates {
        return { a: 3 };
    }
}

class Base extends GenericBase<BaseStates> {
    getInitialState(): BaseStates {
        return super.getBaseInitialState();
    }
}

interface DerivedStates extends BaseStates {
    b: number;
}

class Derived extends GenericBase<DerivedStates> {
    getInitialState(): DerivedStates {
        var initialStates = super.getBaseInitialState() as DerivedStates; // unsafe??
        initialStates.b = 4;
        return initialStates
    }
}

然而,如果我在Derived中调用this.setState,这将失败,我得到一个TypeScript错误( DerivedStates类型的参数不能赋值给S类型)。我认为这不是特定于TypeScript的事情,而是将继承与泛型(?)混合在一起的一般限制。有没有什么类型安全的解决方法呢?

更新

我确定的解决方案(基于David Sherret的答案):

代码语言:javascript
复制
interface BaseStates {
    a: number;
}

class GenericBase<S extends BaseStates> extends React.Component<void, S> {
    constructor() {
        super();
        this.state = this.getInitialState();
    }

    getInitialState(): S {
        return { a: 3 } as S;
    }

    update() {
        this.setState({ a: 7 } as S);
    }
}

interface DerivedStates extends BaseStates {
    b: number;
}

class Derived extends GenericBase<DerivedStates> {
    getInitialState(): DerivedStates {
        var initialStates = super.getInitialState();
        initialStates.b = 4;
        return initialStates;
    }

    update() {
        this.setState({ a: 7, b: 4 });
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-30 22:21:31

通过使用类型断言,您只能在Derived中一次设置状态的几个属性:

代码语言:javascript
复制
this.setState({ b: 4 } as DerivedStates); // do this
this.setState({ a: 7 } as DerivedStates); // or this
this.setState({ a: 7, b: 4 });            // or this

顺便说一句,getInitialState不需要有不同的名字...你可以这样做:

代码语言:javascript
复制
class GenericBase<S extends BaseStates> extends React.Component<void, S> {
    constructor() {
        super();        
        this.state = this.getInitialState();
    }

    protected getInitialState() {
        return { a: 3 } as BaseStates as S;
    }
}

class Derived extends GenericBase<DerivedStates> {
    getInitialState() {
        var initialStates = super.getInitialState();
        initialStates.b = 4;
        return initialStates;
    }
}
票数 13
EN

Stack Overflow用户

发布于 2020-09-07 02:58:29

代码语言:javascript
复制
import { Component } from 'react'


abstract class TestComponent<P = {}, S = {}, SS = any> extends Component<P, S, SS> {
  abstract test(): string
}


type Props = {
  first: string,
  last: string,
}

type State = {
  fullName: string,
}

class MyTest extends TestComponent<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      fullName: `${props.first} ${props.last}`
    }
  }

  test() {
    const { fullName } = this.state
    return fullName
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32866534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档