打字稿泛型和创建新实例

时间:2019-05-17 13:53:09

标签: typescript typescript-typings

我有此代码:

export class JsonSerializable {
    toJson(): any {
        const jsonConvert = new JsonConvert();
        jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;
        return jsonConvert.serialize(this);
    }

    static fromJson<T extends JsonSerializable>(data: any): T {
        const jsonConvert = new JsonConvert();
        jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;

        return jsonConvert.deserializeObject(data, T) as T;
    }
}

deserializeObject()定义为:

deserializeObject<T>(jsonObject: any, classReference: {
        new (): T;
    }): T;

我不太了解如何声明我的类以接受此操作而不会出现“ 'T'仅指类型,但在此处被用作值”的错误。

1 个答案:

答案 0 :(得分:3)

您的线索来自deserializeObject的定义。您不能在表达式中使用类型。在编译T之后类型将被删除,运行时将不存在。这就是为什么deserializeObject有第二个参数将类作为构造函数签名的原因(classReference参数)。

您可以执行相同的操作,并将类作为额外的参数:

export class JsonSerializable {
    toJson(): any {
        const jsonConvert = new JsonConvert();
        jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;
        return jsonConvert.serialize(this);
    }

    static fromJson<T extends JsonSerializable>(data: any, classReference: {
        new (): T;
    }): T {
        const jsonConvert = new JsonConvert();
        jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;

        return jsonConvert.deserializeObject(data, classReference);
    }
}

class MyClass extends JsonSerializable {
    public f = ""
}

let a = JsonSerializable.fromJson({}, MyClass); // a is MyClass

或者,如果您不介意在要反序列化的类上调用fromJson,则可以使用this(为this参数添加适当的类型注释):< / p>

export class JsonSerializable {
    toJson(): any {
        const jsonConvert = new JsonConvert();
        jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;
        return jsonConvert.serialize(this);
    }

    static fromJson<T extends JsonSerializable>(this: new () => T, data: any): T {
        const jsonConvert = new JsonConvert();
        jsonConvert.valueCheckingMode = ValueCheckingMode.ALLOW_NULL;

        return jsonConvert.deserializeObject(data, this);
    }
}

class MyClass extends JsonSerializable {
    public f = ""
}

let a = MyClass.fromJson({}); // a is MyClass