[BUG] [Javascript] Inherited classes contain all parent properties within child class
Created by: tripleplayj
Description
When inheriting from a parent class, the child class contains all of the parent properties within the actual child class. So it explicitly checks for and resets all the parent properties within the child class instead of actually inheriting from it.
openapi-generator version
4.0.0-beta3 (also happening with 3.3.4)
OpenAPI declaration file content or url
api.yaml
components:
schemas:
BaseClass:
type: "object"
required:
- type
properties:
type:
type: "string"
property0:
type: "string"
discriminator:
propertyName: "type"
ChildClass:
allOf:
- $ref: '#/components/schemas/BaseClass'
- type: "object"
properties:
property1:
type: "string"
property2:
type: "string"
GrandchildClass:
allOf:
- $ref: '#/components/schemas/ChildClass'
- type: "object"
properties:
property3:
type: "string"
property4:
type: "string"
Command line used for generation
openapi-generator generate -g spring -i api.yaml -o generated -DdelegatePattern=true,hideGenerationTimestamp=true
Steps to reproduce
Invoke the command line about with the provided api.yaml
Expected Output
Grandchild.js
import ChildClass from './ChildClass';
class GrandchildClass {
/**
* Constructs a new <code>GrandchildClass</code>.
* @alias module:model/GrandchildClass
* @implements module:model/ChildClass
*/
constructor() {
ChildClass.initialize(this, type);
GrandchildClass.initialize(this);
}
/**
* Initializes the fields of this object.
* This method is used by the constructors of any subclasses, in order to implement multiple inheritance (mix-ins).
* Only for internal use.
*/
static initialize(obj) {
obj['type'] = type;
}
/**
* Constructs a <code>GrandchildClass</code> from a plain JavaScript object, optionally creating a new instance.
* Copies all relevant properties from <code>data</code> to <code>obj</code> if supplied or a new instance if not.
* @param {Object} data The plain JavaScript object bearing properties of interest.
* @param {module:model/GrandchildClass} obj Optional instance to populate.
* @return {module:model/GrandchildClass} The populated <code>GrandchildClass</code> instance.
*/
static constructFromObject(data, obj) {
if (data) {
obj = obj || new GrandchildClass();
ChildClass.constructFromObject(data, obj);
if (data.hasOwnProperty('property3')) {
obj['property3'] = ApiClient.convertToType(data['property3'], 'String');
}
if (data.hasOwnProperty('property4')) {
obj['property4'] = ApiClient.convertToType(data['property4'], 'String');
}
}
return obj;
}
}
/**
* @member {String} property3
*/
GrandchildClass.prototype['property3'] = undefined;
/**
* @member {String} property4
*/
GrandchildClass.prototype['property4'] = undefined;
export default GrandchildClass;
Actual Output
Grandchild.js
/**
* trickle server
* TODO: description
*
* OpenAPI spec version: v1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*
*/
import ApiClient from '../ApiClient';
import ChildClass from './ChildClass';
class GrandchildClass {
/**
* Constructs a new <code>GrandchildClass</code>.
* @alias module:model/GrandchildClass
* @implements module:model/ChildClass
*/
constructor() {
ChildClass.initialize(this, type);
GrandchildClass.initialize(this);
}
/**
* Initializes the fields of this object.
* This method is used by the constructors of any subclasses, in order to implement multiple inheritance (mix-ins).
* Only for internal use.
*/
static initialize(obj) {
obj['type'] = type;
}
/**
* Constructs a <code>GrandchildClass</code> from a plain JavaScript object, optionally creating a new instance.
* Copies all relevant properties from <code>data</code> to <code>obj</code> if supplied or a new instance if not.
* @param {Object} data The plain JavaScript object bearing properties of interest.
* @param {module:model/GrandchildClass} obj Optional instance to populate.
* @return {module:model/GrandchildClass} The populated <code>GrandchildClass</code> instance.
*/
static constructFromObject(data, obj) {
if (data) {
obj = obj || new GrandchildClass();
ChildClass.constructFromObject(data, obj);
if (data.hasOwnProperty('type')) {
obj['type'] = ApiClient.convertToType(data['type'], 'String');
}
if (data.hasOwnProperty('property0')) {
obj['property0'] = ApiClient.convertToType(data['property0'], 'String');
}
if (data.hasOwnProperty('property1')) {
obj['property1'] = ApiClient.convertToType(data['property1'], 'String');
}
if (data.hasOwnProperty('property2')) {
obj['property2'] = ApiClient.convertToType(data['property2'], 'String');
}
if (data.hasOwnProperty('property3')) {
obj['property3'] = ApiClient.convertToType(data['property3'], 'String');
}
if (data.hasOwnProperty('property4')) {
obj['property4'] = ApiClient.convertToType(data['property4'], 'String');
}
}
return obj;
}
}
/**
* @member {String} type
*/
GrandchildClass.prototype['type'] = undefined;
/**
* @member {String} property0
*/
GrandchildClass.prototype['property0'] = undefined;
/**
* @member {String} property1
*/
GrandchildClass.prototype['property1'] = undefined;
/**
* @member {String} property2
*/
GrandchildClass.prototype['property2'] = undefined;
/**
* @member {String} property3
*/
GrandchildClass.prototype['property3'] = undefined;
/**
* @member {String} property4
*/
GrandchildClass.prototype['property4'] = undefined;
// Implement ChildClass interface:
/**
* @member {String} type
*/
ChildClass.prototype['type'] = undefined;
/**
* @member {String} property0
*/
ChildClass.prototype['property0'] = undefined;
/**
* @member {String} property1
*/
ChildClass.prototype['property1'] = undefined;
/**
* @member {String} property2
*/
ChildClass.prototype['property2'] = undefined;
export default GrandchildClass;
You can see that all the properties from the super class, and the immediate parent class are included in the grandchild class. This seems to be rather inefficient because the properties are already set and now whenever the class gets instantiated it has to go through 4 if statements to even get to the point that matters. Ideally, it would leave all super properties out, barring annotations that show it's a child.