-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Open
Description
Describe the bug
When instantiating new Typescript classes by passing data to constructor, some properties do not get set if that class extends another class. (Only the properties of the extended class get set when passing data via the constructor).
Version used
V14.2.0
To Reproduce
Server side classes:
public class PaginationFilter: BaseFilter
{
public int PageNumber { get; set; }
public int PageSize { get; set; } = int.MaxValue;
}
public class BaseFilter
{
public string Keyword { get; set; }
}
Code generation settings:
var codeGenerationSettings = new TypeScriptClientGeneratorSettings
{
ClassName = "{controller}Client",
GenerateClientClasses = true,
Template = TypeScriptTemplate.Angular,
RxJsVersion = 7.0M,
UseSingletonProvider = true,
IncludeHttpContext = false,
HttpClass = HttpClass.HttpClient,
WithCredentials = false,
InjectionTokenType = InjectionTokenType.InjectionToken,
BaseUrlTokenName = baseUrlTokenName,
OperationNameGenerator = new MultipleClientsFromOperationIdOperationNameGenerator(),
ClientBaseClass = string.Empty,
QueryNullValue = string.Empty,
GenerateClientInterfaces = false,
GenerateOptionalParameters = false,
ExcludedParameterNames = [],
ExceptionClass = "ApiException",
WrapDtoExceptions = false,
WrapResponses = false,
UseTransformOptionsMethod = false,
UseTransformResultMethod = false,
WrapResponseMethods = [],
GenerateDtoTypes = true,
ImportRequiredTypes = true
};
codeGenerationSettings.TypeScriptGeneratorSettings.ModuleName = moduleName;
codeGenerationSettings.TypeScriptGeneratorSettings.Namespace = string.Empty;
codeGenerationSettings.TypeScriptGeneratorSettings.TypeScriptVersion = 4.3M;
codeGenerationSettings.TypeScriptGeneratorSettings.InlineNamedDictionaries = false;
codeGenerationSettings.TypeScriptGeneratorSettings.InlineNamedAny = false;
codeGenerationSettings.TypeScriptGeneratorSettings.ExportTypes = true;
codeGenerationSettings.TypeScriptGeneratorSettings.TypeStyle = TypeScriptTypeStyle.Class;
codeGenerationSettings.TypeScriptGeneratorSettings.EnumStyle = TypeScriptEnumStyle.Enum;
codeGenerationSettings.TypeScriptGeneratorSettings.UseLeafType = false;
codeGenerationSettings.TypeScriptGeneratorSettings.NullValue = TypeScriptNullValue.Undefined;
codeGenerationSettings.TypeScriptGeneratorSettings.DateTimeType = TypeScriptDateTimeType.Date;
codeGenerationSettings.TypeScriptGeneratorSettings.GenerateDefaultValues = true;
codeGenerationSettings.TypeScriptGeneratorSettings.MarkOptionalProperties = true;
codeGenerationSettings.TypeScriptGeneratorSettings.GenerateCloneMethod = false;
codeGenerationSettings.TypeScriptGeneratorSettings.ExcludedTypeNames = [];
codeGenerationSettings.TypeScriptGeneratorSettings.HandleReferences = false;
codeGenerationSettings.TypeScriptGeneratorSettings.GenerateConstructorInterface = true;
codeGenerationSettings.TypeScriptGeneratorSettings.ConvertConstructorInterfaceData = false;
codeGenerationSettings.TypeScriptGeneratorSettings.ExtendedClasses = [];
codeGenerationSettings.TypeScriptGeneratorSettings.TemplateDirectory = null;
Auto-generated output:
export class BaseFilter implements IBaseFilter {
advancedSearch?: Search | undefined;
keyword?: string;
advancedFilter?: Filter | undefined;
constructor(data?: IBaseFilter) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.advancedSearch = _data["advancedSearch"] ? Search.fromJS(_data["advancedSearch"]) : <any>undefined;
this.keyword = _data["keyword"];
this.advancedFilter = _data["advancedFilter"] ? Filter.fromJS(_data["advancedFilter"]) : <any>undefined;
}
}
static fromJS(data: any): BaseFilter {
data = typeof data === 'object' ? data : {};
let result = new BaseFilter();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["advancedSearch"] = this.advancedSearch ? this.advancedSearch.toJSON() : <any>undefined;
data["keyword"] = this.keyword;
data["advancedFilter"] = this.advancedFilter ? this.advancedFilter.toJSON() : <any>undefined;
return data;
}
}
export interface IBaseFilter {
advancedSearch?: Search | undefined;
keyword?: string;
advancedFilter?: Filter | undefined;
}
export class PaginationFilter extends BaseFilter implements IPaginationFilter {
pageNumber?: number;
pageSize?: number;
orderBy?: string[];
constructor(data?: IPaginationFilter) {
super(data);
}
override init(_data?: any) {
super.init(_data);
if (_data) {
this.pageNumber = _data["pageNumber"];
this.pageSize = _data["pageSize"];
if (Array.isArray(_data["orderBy"])) {
this.orderBy = [] as any;
for (let item of _data["orderBy"])
this.orderBy!.push(item);
}
}
}
static override fromJS(data: any): PaginationFilter {
data = typeof data === 'object' ? data : {};
let result = new PaginationFilter();
result.init(data);
return result;
}
override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["pageNumber"] = this.pageNumber;
data["pageSize"] = this.pageSize;
if (Array.isArray(this.orderBy)) {
data["orderBy"] = [];
for (let item of this.orderBy)
data["orderBy"].push(item);
}
super.toJSON(data);
return data;
}
}
export interface IPaginationFilter extends IBaseFilter {
pageNumber?: number;
pageSize?: number;
orderBy?: string[];
}
Typescript usage:
const filter = new ApiClient.PaginationFilter({
keyword: 'Search String',
pageSize: 10,
pageNumber: 1
});
console.assert(filter.pageSize === 10); // filter.pageSize stays undefined
console.assert(filter.pageNumber === 1); // filter.pageNumber stays undefined
Expected behavior
I expect that filter.pageSize and filter.pageNumber get assigned the values that are passed via the constructor.
Additional context
While all the data that is initially passed is forwarded to the baseFilter class constructor:
constructor(data?: IPaginationFilter) {
super(data);
}
The IBaseFilter type ends up hiding the 2 properties that would exist in the IPaginationFilter type:
constructor(data?: IBaseFilter) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
Metadata
Metadata
Assignees
Labels
No labels