jsii icon indicating copy to clipboard operation
jsii copied to clipboard

Enable base class members overriding

Open leandropadua opened this issue 4 years ago • 7 comments

:rocket: Feature Request

As per current state of JSII, there's a limitation regarding overriding base class members. This is described in the typescript restrictions documentation.

export class Base {
  public method(): any { /* ... */ }
}

export class Child {
  // ⛔️ Illegal change of signature when overriding a member
  public method(): string { /* ... */ }
}

However, c# recently announced covariant returns to enable the specialized class to override the base class method: https://devblogs.microsoft.com/dotnet/c-9-0-on-the-record/#covariant-returns

If the whole limitation can't be removed, maybe we could at least allow override when the new member type is an extension of the original base member.

Also, I haven't tried myself, but it would be interested to explore if this can also remove the limitation of overriding interface members.

Thank you.

Affected Languages

  • [ ] TypeScript or Javascript
  • [ ] Python
  • [ ] Java
  • [x] .NET (C#, F#, ...)

leandropadua avatar Dec 07 '20 00:12 leandropadua

Hey!

Thanks for this feature request. If C# 9.0 allows covariant return types, then we could be able to alleviate the restriction, however the minimum supported target is C# 9.0+, which would not be the case until .NET Core 3.1 goes EOL...

RomainMuller avatar Dec 09 '20 09:12 RomainMuller

Hey!

Thanks for this feature request.

If C# 9.0 allows covariant return types, then we could be able to alleviate the restriction, however the minimum supported target is C# 9.0+, which would not be the case until .NET Core 3.1 goes EOL...

That's a very good point. We are blocked until dotnet core supports it. Let's hold it until then. Thanks

leandropadua avatar Dec 09 '20 23:12 leandropadua

Hi, is this why properties cannot have their type changed, even to a subtype of the original?

This doesn't work for me currently:

export abstract class PipelineBase extends cdk.Construct {...}
export class SinglePipeline extends PipelineBase {...}

export abstract class PipelineStackBase extends cdk.Stack {
  public readonly abstract pipeline: PipelineBase;
}

export class SinglePipelineStack extends PipelineStackBase {
  // this fails with error JSII5004: ... changes the property type to ... when overriding ...
  public readonly pipeline: SinglePipeline;
}

tomas-mazak avatar Feb 04 '21 13:02 tomas-mazak

@tomas-mazak this is correct!

RomainMuller avatar Feb 24 '21 12:02 RomainMuller

Is there a recommended pattern for getting around this issue?

KyleTryon avatar Oct 13 '21 18:10 KyleTryon

Is there a recommended pattern for getting around this issue?

Not really. C# very strictly enforces Liskov's substitutability... so we kind of have to abide, otherwise we cannot represent the same behavior in C# than in other languages.

RomainMuller avatar Jan 31 '22 10:01 RomainMuller