打字稿:使用静态方法处理子类

乔纳森·舒尔巴赫

在TypeScript(我使用了Playground,版本4.13)中,当我从类继承时,父类thisstatic方法内部似乎引用了继承的类:

class Parent{
    static ID = 0
    public id: number

    static create(){
        return new this(this.ID)
    }

    constructor(id: number){
        this.id = id
    }
}

class Child extends Parent{
    static ID = 1
}

let child = Child.create()
console.log(child.id)  // 1

但是,当我想根据子类的类型定义某些行为时遇到问题:

class Parent{
    static create(data: object){
        let instance = new this
        for (let [key, value] of Object.entries(data)){
            this[key] = value
        }
        return instance
    }
}

class Child extends Parent{
    id: number | null = null
}

let child = Child.create({id: 1})
console.log(child.id)

这给我

元素隐式具有“ any”类型,因为类型为'string | 编号| 符号”不能用于索引类型“父类型”。在“ typeof Parent”类型上未找到带有“ string”类型参数的索引签名。

我试图通过类型转换key作为子类的键来解决这个问题

class Parent{
    static create(data: object){
        let instance = new this
        for (let [key, value] of Object.entries(data)){
            this[key as keyof this] = value
        }
        return instance
    }
}

class Child extends Parent{
    id: number | null = null
}

let child = Child.create({id: 1})
console.log(child.id)

但这是被禁止的。我懂了

“此”类型仅在类或接口的非静态成员中可用

另外,我得到(在所有情况下)

属性“ id”在“父母”类型上不存在。

我该如何解决我的问题-从对象中动态填充子类的属性(在现实情况下是从API接收的)?

阿鲁安·哈达德(Aluan Haddad)

您可以通过指定this与类本身相对应参数来完成此操作在静态方法中,this指的是类本身。

static create<T extends Parent>(this: new (...args: any[]) => T, data: object) {...} 

这里的意思是说this类型将引用包含该方法的对象,在这种情况下,无论create调用哪种类对象,该类型都可以返回该类的实例类型的子类型。这是通过type参数完成的T,并且类对象将具有返回a的构造签名的说明T,从而捕获了任何派生类的实例类型。

这是完整的工作代码:

class Parent {
    static create<T extends Parent>(this: new (...args: any[]) => T, data: object) {
        let instance = new this;
        for (let [key, value] of Object.entries(data)) {
            instance[key as keyof T] = value;
        }
        return instance;
    }
}

class Child extends Parent {
    id: number | null = null;
}

let child = Child.create({ id: 1 });
console.log(child.id);

游乐场链接

由于我们已通过捕获了派生的实例类型T,因此我们可以create通过如下调整create来进一步完善该方法以提高类型安全性:

static create<T extends Parent>(this: new (...args: any[]) => T, data: Partial<T>) {...}

这样可以防止我们通过,从而create在提供智能感知的同时将任意属性分配给由该方法创建的对象

完整代码:

class Parent {
    static create<T extends Parent>(this: new (...args: any[]) => T, data: Partial<T>) {
        let instance = new this;
        for (let [key, value] of Object.entries(data)) {
            const k = key as keyof T;
            instance[k] = value as T[typeof k];
        }
        return instance;
    }
}

class Child extends Parent {
    id: number | null = null;
}

let child = Child.create({ id: 1 });
console.log(child.id);

游乐场链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从子类的实例访问打字稿中的静态属性?

来自分类Dev

打字稿:静态方法返回值

来自分类Dev

使用类的静态成员打字稿

来自分类Dev

打字稿静态只读

来自分类Dev

使用localecompare打字稿处理null

来自分类Dev

从打字稿中的静态方法中检索类名称

来自分类Dev

打字稿:类外定义的静态方法与函数

来自分类Dev

打字稿中的静态数组

来自分类Dev

打字稿中的静态类

来自分类Dev

使用Jest作为打字稿中的方法

来自分类Dev

在导入中使用服务方法的打字稿

来自分类Dev

子类的打字稿定义作为参数

来自分类Dev

React.Component 的 typeof 子类打字稿

来自分类Dev

使用 rxjs 打字稿

来自分类Dev

导入静态函数打字稿

来自分类Dev

打字稿:自引用静态类成员

来自分类Dev

覆盖打字稿中孩子的静态字段

来自分类Dev

从打字稿中相同类的实例方法中简短引用静态函数

来自分类Dev

如何使用打字稿和敲除调用对象实例方法

来自分类Dev

使用类的方法在打字稿中创建联合类型

来自分类Dev

重载打字稿中的方法

来自分类Dev

打字稿-声明通用方法

来自分类Dev

打字稿方法未调用

来自分类Dev

打字稿中的绑定方法

来自分类Dev

通用方法的打字稿接口

来自分类Dev

使用打字稿进行条件打字

来自分类Dev

如何处理打字稿中的onChange

来自分类Dev

打字稿-推断函数是否被处理

来自分类Dev

打字稿处理程序,其中this [] = value