abp icon indicating copy to clipboard operation
abp copied to clipboard

Javascript proxy generation: all enums are generated as nullable

Open hillin opened this issue 10 months ago • 3 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues

Description

In abp 9.1.0-rc2, all enum properties are generated as nullable in the javascript proxy.

Reproduction Steps

public class MyDto {
  public MyEnum Value { get; set; }
}
> abp help     
ABP CLI 9.1.0-rc.2
> abp generate-proxy -t ng --entry-point .
export interface MyDto {
  value?: MyEnum;  // should not be nullable
}

Expected behavior

Generate enum properties with correct nullablility.

Actual behavior

All enum properties are generated as nullable.

Regression?

Possibly.

Known Workarounds

No response

Version

9.1.0-rc2

User Interface

Angular

Database Provider

None/Others

Tiered or separate authentication server

None (Default)

Operation System

Windows (Default)

Other information

Related issues: https://github.com/abpframework/abp/issues/21995 https://github.com/abpframework/abp/pull/22037 https://github.com/abpframework/abp/issues/22118 https://github.com/abpframework/abp/pull/22120

hillin avatar Feb 12 '25 13:02 hillin

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Apr 26 '25 01:04 stale[bot]

Hello @hillin you will need to make it required by adding a flag. Am I mistaken @maliming ?

sumeyyeKurtulus avatar Apr 28 '25 05:04 sumeyyeKurtulus

@sumeyyeKurtulus I believe required is only for reference types. For value types (numbers, enums and structs) they should always be generated as non-nullable - unless they are declared as Nullable<T>, which makes them becoming reference type.

Currently numbers are always generated as non-nullable, enums should be consistent with them.

hillin avatar Apr 28 '25 05:04 hillin

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jun 27 '25 05:06 stale[bot]

Hello @hillin here is how we determine the nullability for the proxy generation https://github.com/abpframework/abp/blob/5fb0c4c02f94c589e17c4877266637e57d2afea2/npm/ng-packs/packages/schematics/src/utils/model.ts#L188

You can also check how the generation is covered by checking the generate-proxy.json. Here is an example

  "types": {
    "MyProjectName.Test.OfferDto": {
      "properties": [
        {
          "name": "OfferId",
          "jsonName": null,
          "type": "System.Guid",
          "typeSimple": "string",
          "isRequired": false,
          "minLength": null,
          "maxLength": null,
          "minimum": null,
          "maximum": null,
          "regex": null
        },
        {
          "name": "Type",
          "jsonName": null,
          "type": "MyProjectName.Test.OfferDto.OfferType",
          "typeSimple": "enum",
          "isRequired": false,
          "minLength": null,
          "maxLength": null,
          "minimum": null,
          "maximum": null,
          "regex": null
        },
        {
          "name": "ProductType",
          "jsonName": null,
          "type": "MyProjectName.Test.OfferDto.ProductType?",
          "typeSimple": "enum?",
          "isRequired": false,
          "minLength": null,
          "maxLength": null,
          "minimum": null,
          "maximum": null,
          "regex": null
        }
      ]
    },

for such dto

public class MyProjectName.Test.OfferDto : EntityDto<Guid>
    {
        public Guid OfferId { get; set; }
        public Type Type { get; set; }
        public ProductType? ProductType { get; set; }
    }

I do not believe that this behaves in a wrong way, what do you think @maliming

sumeyyeKurtulus avatar Jun 30 '25 12:06 sumeyyeKurtulus

Take a look at this example:

public class TestDto
{
    public int? OptionalInt { get; set; }
    public int NonNullInt { get; set; }
    public required int RequiredInt { get; set; }

    public TestEnum? OptionalEnum { get; set; }
    public TestEnum NonNullEnum { get; set; }
    public required TestEnum RequiredEnum { get; set; }
}

public enum TestEnum
{
    A,
    B
}

Generated proxy:

export interface TestDto {
  optionalInt?: number;
  nonNullInt: number;  // NON-NULLABLE
  requiredInt: number;
  optionalEnum?: TestEnum;
  nonNullEnum?: TestEnum;  // !! NULLABLE !!
  requiredEnum: TestEnum;
}

export enum TestEnum {
  A = 0,
  B = 1,
}

My point is simple: enums are no different than numbers, thus we would expect them to be handled in a consistent way. So in the example above, either nonNullableInt should be nullable, or nonNullEnum should be non-nullable.

hillin avatar Jul 01 '25 04:07 hillin

This problem is the same with this one mentioned here https://github.com/abpframework/abp/issues/22408, so I am closing this as duplicate.

sumeyyeKurtulus avatar Sep 08 '25 12:09 sumeyyeKurtulus

@sumeyyeKurtulus no they are not the same.

hillin avatar Dec 01 '25 09:12 hillin