• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

typescript关于class属性类型定义被属性默认值覆盖的问题及解决方式 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

问题来源于 React.component的第二个参数的类型定义问题,我构建了以下简化demo,方便描述问题:

class P<STATE> {
    public state: STATE;
}

interface Obj {
    arr: Obj[];
}

class Test1 extends P<Obj> {
    public state = {arr: []};

    func(obj: Obj) {
        this.state.arr.push(obj);// 这里ts在obj上抛错  Error:(51, 29) TS2345: Argument of type 'Obj' is not assignable to parameter of type 'never'.
    }
}

这里主要产生的问题是,我们认为 this.state.arr 应该是Obj[] 类型,所以可以往里面push进去Obj类型的数据,然而this.state.arr却被识别为never[]类型,所以push会抛错。

分析后,发现虽然Test1的state在设置默认值的时候可以使用父类 P 中state的类型定义,但是,在函数中 this.state的类型定义却是使用 默认值 {arr: []} 的类型推断。推断出的类型为{arr:never[]}。

所以产生以上问题。

于是,我们可以这样处理:

class Test2 extends P<Obj> {
    public state: Obj = {arr: []}; // 子类同时定义state类型为Obj

    func(obj: Obj) {
        this.state.arr.push(obj);
    }
}

但是这就导致Obj需要定义两次。

我们又注意到,在构造函数中直接赋值,也可以解决该问题:

class Test3 extends P<Obj> {
    constructor() {
        super();
        this.state = {arr: []}; // 直接在constructor中赋值
    }

    func(obj: Obj) {
        const str: string = this.state;
        this.state.arr.push(obj);
    }
}

但是写起来是比较麻烦的,每次都要写构造函数。

 

最后,我们按赋值的思想,考虑使用中间类方式:

// 中间类,继承P<T> 这里P类通常为第三方类,如React.Component
abstract class Middle<T> extends P<T> {
    protected constructor() {
        super();
        if (this.initState) {
            this.state = this.initState();
        }
    }

    abstract initState(): T;
}

class Test2 extends Middle<Obj> {
    initState() {// 通过方法来初始化state
        return {arr: []};
    }

    func(obj: Obj) {
        const str: string = this.state;
        this.state.arr.push(obj);
    }
}

我们在中间类中定义了构造函数来默认调用initState函数,然后让state的初始值作为函数的返回值,可以解决属性默认值的类型覆盖了父类对属性参数的定义。

引进来的代价是我们需要一个中间类。

不过,考虑中间类的引入,可以带来比较多的扩展性,权衡之下,还是可取的。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap