Description
❓ Guidance
While I am submitting this for guidance, this is a blocking issue me. Errors point out this is a limitation issue, but not how to resolve it. See below for details.
Affected Languages
-
TypeScript
orJavascript
-
Python
-
Java
- .NET (
C#
,F#
, ...) -
Go
General Information
- JSII Version: 1.34.0 (build 9b72778), typescript 3.9.10
- Platform:. 18.7.0 Darwin Kernel Version 18.7.0
The Question
Below is a simplified example of a common pattern in TypeScript using abstract classes (could easily interface instead, it should not matter for this) to group elements of a similar type. In this case, we have the Vehicle
abstract class, and it states that all vehicles should contain a properties
property. As Vehicle
is the most generic structure for vehicles, the type is set to unknown
.
Then we define two child classes which extendVehicle
. Both Car
and Plane
will have properties
, but we expect their type to be different. We do this so we can call properties
on any vehicle, and so when users are instantiating either a Car
or Plane
, they receive the correct code-hints.
// The most generic, abstract class "vehicle"
// This class joins our "vehicles" under a shared type
export abstract class Vehicle {
properties: unknown;
}
export class Car extends Vehicle {
properties: CarProperties;
constructor(properties: CarProperties) {
super()
this.properties = properties
}
}
export class Plane extends Vehicle {
properties: PlaneProperties;
constructor(properties: PlaneProperties) {
super()
this.properties = properties
}
}
interface CarProperties {
doors: number;
color: string;
}
interface PlaneProperties {
wings: number;
callSign: string;
}
The code above is valid and working TypeScript, but this will not compile under JSII due to JSII5003
// This pattern above exists so that we might
// do something like the following:
const myVehicles: Vehicle[] = []
const myCar = new Car({doors: 2, color: "red"}) // proper type code-hints are given here
const myPlane = new Plane({wings: 2, callSign: "bravo"}) // proper type code-hints are given here
myVehicles.push(myCar)
myVehicles.push(myPlane)
myVehicles.forEach( vehicle => {console.log(vehicle.properties.toString())})
Error:
Type model errors prevented the JSII assembly from being created
error JSII5004: "Car#properties" changes the property type to "CarProperties" when overriding Vehicle. Change it to "unknown"
The only way around this I see is to drop the Typing on Car
and Plane
, which would leave the user blind when instantiating those classes. What is the recommended pattern for dealing with this type of scenario with JSII?
Edit:
I have just discovered #2314 which appears to be the same topic