This appears to be the same problem as in this closed issue: https://abp.io/support/questions/6657/Generation-of-Service-Proxies-for-Angular-not-handling-subclasses-of-PagedResultDtoT-correctly
After running the proxy generator, the resulting models.ts file includes both an import for MyEntityDto and and interface definition for MyEntityDto. Compiling the file results in the error, "error TS2440: Import declaration conflicts with local declaration of 'MyEntityDto'"
Steps to Reproduce
- Create a DTO on the C# side
- public class MyEntityDto : EntityDto<Guid>
- Create a subclass of PageResultDto<T> where T is MyEntityDto
- public class MessageCenterCustomPagedResultDto : PagedResultDto<MessageDto>
- Run "abp generate-proxy -t ng"
- Attempt to build the angular project
2 Answer(s)
-
0
- What is happening?
This is a known limitation of the Angular proxy generator:
when you have custom classes that subclassPagedResultDto<T>(or other complex generics), the generatedmodels.tscan end up with:import type { MyEntityDto } from './models'; export interface MyEntityDto { // ... }or similar patterns for generic type parameters (e.g.
T,TKey), causing TypeScript errors like:TS2440: Import declaration conflicts with local declaration of 'MyEntityDto'TS2303 / TS2459about circular definition or missing exported memberT,TKey, etc.
The official support answer for the linked ticket confirms:
The
generate-proxycommand may not support all C# types; you need to modify the generated code manually for now.So this is a limitation/bug of the proxy generator, not your specific project.
- Recommended fixes / workarounds
You have two practical options. The recommended one is to simplify the C# DTOs so they’re proxy‑friendly.
Option A – Change your C# DTO design (recommended)
Avoid exposing custom subclasses of
PagedResultDto<T>in your public application contracts.Instead of:
public class MyEntityDto : EntityDto<Guid> { // ... } public class MessageCenterCustomPagedResultDto : PagedResultDto<MyEntityDto> { }Change your application service methods to return the base
PagedResultDto<T>directly:public class MyEntityDto : EntityDto<Guid> { // ... } // AppService method public virtual async Task<PagedResultDto<MyEntityDto>> GetListAsync(MyInputDto input) { // ... }If you need extra properties on the “paged result”, make them normal properties on a non‑generic DTO instead of subclassing
PagedResultDto<T>:public class MyEntityPagedResultDto { public long TotalCount { get; set; } public List<MyEntityDto> Items { get; set; } // Any additional fields you need public string SomeExtraInfo { get; set; } } // AppService method public virtual async Task<MyEntityPagedResultDto> GetCustomListAsync(MyInputDto input) { // Map manually from a PagedResultDto<MyEntityDto> or query result }This produces simple DTO shapes that the Angular proxy generator can handle without generating recursive imports or bogus generic imports.
After changing the contracts:
- Rebuild the backend.
- Run the proxy generator again:
abp generate-proxy -t ng- Build the Angular project.
You should no longer see
TS2440onMyEntityDto(or similar generic / import issues).
Option B – Manually fix the generated TypeScript after each generation
If you must keep the C# design as‑is, you can:
- Run
abp generate-proxy -t ng. - Open
src/app/proxy/models.ts(and anyclient-models/models.tsin modules, if applicable). - Manually fix the problematic parts, for example:
- Remove the self‑import:
// Remove this line: import type { MyEntityDto } from './models';- Or rename the locally declared interface to avoid name clash and adjust usages.
- Then build the Angular app.
The downside: every time you regenerate proxies, these files can be overwritten, so you must either:
- keep your changes minimal and easy to re‑apply, or
- exclude those DTOs from your public HTTP APIs and use separate non‑generic DTOs for Angular.
- Why this happens / what to expect
- The current generator does not correctly handle:
- C# types that are subclasses of
PagedResultDto<T>. - Some generic types used in DTOs (e.g.,
CompareLookupDto<TKey>,MyEntityCustomPagedResultDto<T>).
- C# types that are subclasses of
- It tries to treat type parameters or derived generic types as if they were standalone DTOs in the shared
models.ts, leading to:- recursive imports (
import { MyEntityDto } from './models';while also definingMyEntityDto), - or imports of generic parameters (
import { T } from '../../../models';).
- recursive imports (
Given the current behavior, the most robust, maintenance‑friendly fix is to refactor your application contracts as in Option A so they only use:
PagedResultDto<MyEntityDto>directly, or- simple DTOs with
TotalCount+Items+ any extra fields.
- Source
Support ticket describing this exact behavior and official guidance that
generate-proxydoes not support all C# types and may require manual fixes:- https://abp.io/support/questions/6657/Generation-of-Service-Proxies-for-Angular-not-handling-subclasses-of-PagedResultDtoT-correctly
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
Thanks, option A worked.