首页 > 解决方案 > 将构造函数添加到打字稿中的模板类型

问题描述

代码:

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' 来创建对象)

标签: typescriptclass-validator

解决方案


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

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

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

使用工厂

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

注入具有私有属性的构造函数

图书馆回购的例子中有另一种可能更优雅的方式

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


推荐阅读