ES6继承的函数在子类上调用时返回错误的类型

问题描述

一个函数被子类继承时,我希望返回类型就像该函数直接在子类上定义。

需要明确的是,代码在运行时运行良好。但是我想利用静态类型检查。我在VScode中出现了红色的波浪线,并从Google-Closure-Compiler得到了警告。我不确定这是我的ES6代码还是类型注释的问题。

我的简单示例ES6类:

// @ts-check
"use strict";

export class db_row {
    /**
     * @param {number} id 
     */
    constructor(id) {
        /** @type {number} */
        this.id = id;
    }
    clone() {
        return new db_row(this.id);
    }
}

export class Channel_row extends db_row {
    /**
     * Constructor
     * @param {*=} init
     * @param {string=} name
     * @param {string=} value
     */
    constructor(init,name,value = '') {
        let id = -1;
        if (typeof init == 'object') {
            id = init.id;
            name = init.name;
            value = init.value;
        } else if (typeof init == 'number') {
            id = init;
        }
        super(id);
        this.name = name;
        this.value = value;
    }
    clone() {
        return new Channel_row(this.id,this.name,this.value);
    }
}

export class db_table {
    /**
     * Constructor
     * @param {Array<db_row>} table 
     */
    constructor(table) {
        /**@type {Array<db_row>} */
        this.table = table;
    }
    /**
     */
    get_table_copy() { return this.table.map(item => item.clone()) }
    /**
     * @param {?number=} id 
     */
    get_row_by_id(id) {
        const row = this.table.filter(item => item.id === id)[0];
        if (row) return row.clone();
        return null;
    }
}

export class Channel_table extends db_table {
    constructor() {
        /**@type {Array<Channel_row>} */
        let table = [];
        super(table);
    }
}
// Test code below:
/**
 * 
 * @param {Channel_row} chan_row 
 */
function print_chan_row(chan_row) {
    console.log(chan_row.name);
}

let channel_table = new Channel_table();

let channel_row = channel_table.get_row_by_id(0); // hover reports that the type of channel_row is db_row,when it should be type Channel_row

print_chan_row(channel_row); // Red squiggly line error: Argument of type 'db_row' is not assignable to parameter of type 'Channel_row'.   Type 'db_row' is missing the following properties from type 'Channel_row': name,valuets(2345)

console.log(channel_row.name);  // Red squiggly line error: Property 'name' does not exist on type 'db_row'.ts(2339)

let channel_table_2 = channel_table.get_table_copy(); // hover reports that the type of channel_row is db_row[],when it should be type Channel_row[]

print_chan_row(channel_table_2[0]); // Red squiggly line error: Argument of type 'db_row' is not assignable to parameter of type 'Channel_row'.ts(2345)

现在,如果我将get_row_by_id()和get_table_copy()函数移动或复制到子类中,则类型错误会消失。但是我不想不必要地重复代码

如何在父类中声明函数,以便可以在子类中重用它们,但要保持静态类型检查?

作为奖励,我还可以泛化clone()函数,这样就不必在db_row的子类中重写它了吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)