RicoSuter / NJsonSchema

JSON Schema reader, generator and validator for .NET
http://NJsonSchema.org
MIT License
1.38k stars 532 forks source link

Wrong discriminator for inheritance when using mutliple level of inheritance #1721

Open Louis9902 opened 1 month ago

Louis9902 commented 1 month ago

When using multiple level of inheritance the dicriminators in the root type are not using the defined descriminator value. Instead they fallback to the typename of the derived type. This can be obersved in the example in my repository.
In my example I used NSwag to generate the open api spec (commited in the repo) and also to generate typescript clients (also commited in the repo). The spec contains the correct discriminator values but the typescript type generator uses the wrong one for the base type. This might be related to the fact that the spec only contains the descriminators in the intermediate type. I don't known enough about the spec to decide if the discrimainators should also be part of the base descriminator map or not.

Wrong descriminator values in typescript base type

static fromJS(data: any): Base {
    data = typeof data === 'object' ? data : {};
    if (data["$type"] === "SealedA") {
        let result = new SealedA();
        result.init(data);
        return result;
    }
    if (data["$type"] === "Intermediate") {
        throw new Error("The abstract class 'Intermediate' cannot be instantiated.");
    }
    if (data["$type"] === "SealedB") {
        let result = new SealedB();
        result.init(data);
        return result;
    }
    throw new Error("The abstract class 'Base' cannot be instantiated.");
}

correct types in typescript intermediate type

static override fromJS(data: any): Intermediate {
    data = typeof data === 'object' ? data : {};
    if (data["$type"] === "seal-a") {
        let result = new SealedA();
        result.init(data);
        return result;
    }
    if (data["$type"] === "seal-b") {
        let result = new SealedB();
        result.init(data);
        return result;
    }
    throw new Error("The abstract class 'Intermediate' cannot be instantiated.");
}