-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Right now, if we have a type with:
members:
options:
mutable: true
schema:
$interface: "ShapeOptions#SameAsInterface"...and ShapeOptions is defined using the following (as supported by #18):
components:
interfaces:
# A "oneOf" interface can be used to generate a TypeScript type union or a
# Rust enumeration, including the "Post", etc., variants.
#
# This is not a superclass! It's a type union, using `|` in TypeScript to
# allow more than one type. This affects the design in several surprising
# ways. Among other things, we might have several union types that include
# different concrete interface types in their union. For example,
# `ShapeOptions`, `RoundishShapeOptions`, etc.
#
# We can only create a `oneOf` union of multiple interfaces if the
# individual types _all_ use the same discriminator member (see below).
ShapeOptions:
description: "Options for a shape."
oneOf:
- $interface: "SquareShapeOptions#SameAsInterface"
- $interface: "RoundShapeOptions#SameAsInterface"
SquareShapeOptions:
# The discriminator is a property of `SquareShapeOptions`, even if this
# type appears without being part of `ShapeOptions`. This is because it
# affects how the variants of this type get generated.
discriminatorMemberName: "type"
members:
type:
required: true
initializable: true
schema:
type: string
const: square
height:
required: true
mutable: true
schema:
type: number
width:
required: true
mutable: true
schema:
type: number
RoundShapeOptions:
discriminatorMemberName: "type"
members:
type:
required: true
initializable: true
schema:
type: string
const: round
radius:
required: true
mutable: true
schema:
type: number...then it is impossible to send a Merge Patch changing .options from:
{
"type": "square",
"height": 10,
"round": 20
}...to:
{
"type": "round",
"radius": 15
}This patch necessary for this conversion looks like:
{
"type": "round",
"radius": 15,
"height": null,
"width": null,
}We need to be able to pass other keys as null, so we can remove the original square parameters when PATCHing type.
There are several strategies we can use here:
- Allow passing any key with
"key": null. We could do this usingadditionalProperties: { schema: { type: "null" } } }. But we need to check with @blakew about whether this breaks our doc tooling. - Only allow
height: nullandwidth: nullinRoundShapeOptionsMergePatch. But this would require generating a special version ofRoundShapeOptionsMergePatchthat knows aboutSquareShapeOptionsMergePatch. Call it "ShapeOptionsRoundShapeOptionsMergePatch". But sinceoneOfis a type union, not inheritance, we might need several versions ofRoundShapeOptionsMergePatch, one for each type union which includes it. So if we havetype RoundedShapeOptions = RoundShapeOptions | EllipticalShapeOptions, then we would needRoundedShapeOptionsRoundShapeOptionsMergePatchandRoundedShapeOptionsEllipticalShapeOptionsMergePatch, and so on. This is one of those classic bad ideas that just keeps getting worse. - Like (2), but we bake
RoundShapeOptionsMergePatchandSquareShapeOptionsMergePatchdirectly intoShapeOptionsMergePatch. This would require a lot of code, but we might be able to make it nice?
Metadata
Metadata
Assignees
Labels
No labels