Identical static methods in parent/child classes are mistakenly recognized as invalid in JSII
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 267
- Avg merge
- 1d 25m
- Merged PRs (30d)
- 14
Description
## :bug: Bug Report
Related issues: https://github.com/aws/jsii/pull/3407, https://github.com/aws/jsii/issues/2358
### Affected Languages
- [x] `TypeScript` or `Javascript`
- [x] `Python`
- [x] `Java`
- [x] .NET (`C#`, `F#`, ...)
- [x] `Go`
### General Information
* **JSII Version:** 1.54.0
* **Platform:** macOS 12.2.1
### What is the problem?
When compiling with JSII, overriding static methods on child classes with different return types results in an error, even when the types are technically compatible. For example:
```typescript
class BaseValue {
public readonly prop1: string = "hi";
}
class DerivedValue extends BaseValue {
public readonly prop2: boolean = true;
}
class BaseClass {
public static hello(): BaseValue {
return new BaseValue();
}
}
class DerivedClass extends BaseClass {
public static hello(): DerivedValue {
return new DerivedValue();
}
}
```
produces an error like:
```
error JSII5003: "DerivedClass#hello" changes the return type to "DerivedValue" when overriding BaseClass. Change it to "BaseValue"
```
Since `DerivedValue` extends `BaseValue`, this compiles in TypeScript and is valid ES6 code. This kind of structure is also valid in Java:
```java
class BaseValue {
private int prop1;
public BaseValue(int prop1) {
this.prop1 = prop1;
}
}
class DerivedValue extends BaseValue {
private int prop2;
public DerivedValue(int prop1, int prop2) {
super(prop1);
this.prop2 = prop2;
}
}
class Base {
public static BaseValue hello() {
return new BaseValue(5);
}
}
class Derived {
public static DerivedValue hello() {
return new DerivedValue(10, 5);
}
}
```
In C# I think this is also valid, but this needs validation. I suspect it's valid based on this comment in our docs:
```
!!! danger Properties and methods that are static can feature the overrides attribute, as static members are inherited with the prototype in JavaScript (as part of the ES6 specification). Not all target languages have this capability (most, like C# and Java, only support hiding static declarations), and consequently code generators may ignore this (or explicitly hide parent declarations) instead.
```
In Python, I think @ classmethod's can be directly overriden so I don't think this causes any issues. (can anyone confirm?)
In Go there's no real "static" methods, so the transpiled code from jsii should also be valid.
### Verbose Log
N/A
Contributor guide
Research direction
Start with the minimal TypeScript reproduction in the issue and review related pull request #3407 and issue #2358. Confirm the compatible static override behavior across the listed target languages; done means JSII no longer reports JSII5003 for this case and generated code remains valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, go, java, python, typescript
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100