在打字稿中向模板类型添加构造函数

Adding a constructor to a template type in typescript

代码:

import { Expose, Type } from "class-transformer";
import { IsDefined, ValidateNested } from "class-validator";
interface A{
    ...
}

class B{
    ...
}
class Document<T extends A> {
    @IsDefined()
    @ValidateNested()
    @Type(()=>B)
    @Expose()
    b: B;

    @IsDefined()
    @ValidateNested()
    @Type(()=>T) //Compile error: 'T' only refers to a type, but is being used as a value here.
    @Expose()
    a: T;
    
    constructor(b: B, a: T){
        this.b = b;
        this.a = a;
    }
}
  1. 这会在@Type(()=>T) 的行中给出错误('T' 仅指类型,但在此处用作值。)。问题似乎是 T 只是一种类型,没有构造函数。那么,如何在定义中的模板中添加一个构造函数以便它编译?
  2. 我可以去掉 Document 的构造函数而不导致错误吗? (因为我要使用 'class-transformer' 中的 'plainToClass' 来创建对象)

要创建对象,您应该使用构造函数。没有别的办法

Class B 即使没有直接定义,也有自己的构造函数。接口 T 只是 Typescript 中的一个签名。您可以创建两个不同的 classes,他们 实现 相同的接口 T.

您应该以某种方式将构造函数传递给您的 Document class。我看到 2 种方式

使用工厂

const documentFactory = <T>(getT: () => T) => {
    class Document<T> {
        @Type(getT)
        @Expose()
        a: T;
    }
    return Document;
}

用私有注入构造函数属性

example 库 repo

中有花药,可能更优雅的方式

如您所见,@Type() 装饰器使用 TypeHelpOptions 类型的一个参数获取回调。它有未记录的 属性 newObject 引用 class 实例。因此,您可以将 T 构造函数作为 Document 构造函数的参数传递,并在 @Type() 回调中使用它