问题来源于 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的初始值作为函数的返回值,可以解决属性默认值的类型覆盖了父类对属性参数的定义。

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

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

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

  1. ReferenceError: Error #1069: 在 spark.components.RadioButtonGroup 上找不到属性 label,且没有默认值

    1.错误描写叙述 ReferenceError: Error #1069: 在 spark.components.RadioButtonGroup 上找不到属性 label,且没有默认值. at Ch ...

  2. Java 创建数组的方式, 以及各种类型数组元素的默认值

    ①创建数组的方式3种 ①第1种方法 public class MyTest { public static void main(String[] args){ //method 1 int[] arr ...

  3. MySql折腾小记二:text/blog类型不允许设置默认值,不允许存在两个CURRENT_TIMESTAMP

    From: http://www.cnblogs.com/cyq1162/archive/2011/05/17/2049055.html 在 CYQ.Data 数据框架的反向工程中,遇到MySQL的问 ...

  4. C++入门经典-例9.5-为具体类型的参数提供默认值

    1:默认模板参数是指类模板中由默认的数据类型作为参数的参数,在模板定义时,还可以为默认的数据类型声明,变量,并为变量赋值.代码如下: // 9.5.cpp : 定义控制台应用程序的入口点. #incl ...

  5. mysql5.7 date类型无法设置'0000-00-00'默认值

    现象: mysql5.7之后版本datetime默认值设置'0000-00-00',出现异常:Invalid default value for 'create_time' 原因: mysql5.7之 ...

  6. Swift学习之方法定义参数有默认值的时候

    func testParms(first fir:String, options opt:JSONSerialization.ReadingOptions = []) -> Bool { ret ...

  7. odoo开发笔记 -- 模型字段定义中设置默认值

    例如: company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env['res ...

  8. SpringMVC,Controller的返回页面类型以及路径设置默认值

    一般设置在spring-servlet.xml里面设置 <!-- 对转向页面的路径解析.prefix:前缀, suffix:后缀 --> <bean class="org. ...

  9. java字符串转换数值类型出现异常赋予默认值

    http://blog.csdn.net/w47_csdn/article/details/77855126 可以自定义工具方法,例如: public static int parseInt(Stri ...

随机推荐

  1. 根据文字动态计算Label高度或宽度

    //根据已知的label宽度计算文字高度 CGRect rect = [reson boundingRectWithSize:CGSizeMake(label_W, 0) options:NSStri ...

  2. express中cookie的使用

    一.Cookie 简介● cookie 是存储于访问者的计算机中的变量.可以让我们用同一个浏览器访问同一个域名的时候共享数据.● HTTP 是无状态协议.简单地说,当你浏览了一个页面,然后转到同一个网 ...

  3. Spring Boot 2 整合Swagger简单入门

    Swagger是一款RESTFUL接口的文档在线自动生成+功能测试功能软件. 1.pom.xml添加配置 可以到http://mvnrepository.com上搜索springfox,便可以看到Sp ...

  4. UVA1479 Graph and Queries

    思路 恶心人的题目 还是类似永无乡一题的Treap启发式合并思路 但是由于加边变成了删边 所以应该离线后倒序处理 数组要开够 代码 #include <cstdio> #include & ...

  5. MySQL之 视图,触发器,存储过程,函数,事物,数据库锁,数据库备份

    1.视图 视图: 是一个虚拟表,其内容由查询定义: 视图有如下特点;  1. 视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系.  2. 视图是由基本表(实表)产生的表(虚表).  3. ...

  6. 连接MySQL报错The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.

    MySQL time zone 时区错误 使用root用户登陆执行命令: ---> show variables like '%time_zone%'; 默认值system为美国时间:如下图: ...

  7. Java基础知识盘点(二)- 集合篇

    List和Set区别 List和Set都是继承Collection接口 List特点:元素有放入顺序,元素可重复 Set特点:元素无放入顺序,元素不可重复 Set和List对比: Set:检索元素效率 ...

  8. node使用ftp模块获取文件夹信息,中文乱码问题

    c.on('ready', function () { c.list(function (err, list) { if (err) throw err list.map(item => { i ...

  9. pdfmake导出页眉页脚问题

    最近做项目中遇到一个导出pdf的功能,我用的是pdfmake插件 pdf使用参考 https://blog.csdn.net/qq_24380167/article/details/78735642 ...

  10. 《图解Java多线程设计模式》读书笔记

    略读中...后面详读的时候,补充经典图片和文字说明