microsoft / microsoft/typespec
Consider new option to seal tuples, or as part of `seal-object-schemas`
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
### Clear and concise description of the problem
There is some related discussion within the comments of [this issue](https://github.com/microsoft/typespec/issues/2459) but the original core purpose of that ticket seemed to be about the absence of _any_ tuple support in the emitters. This is no longer the case as tuples output `prefixItems` on the JSON schema emitter and the OpenAPI emitter when configured to 3.1.
And the [recent resolution of related problems around extraneous model properties](https://github.com/microsoft/typespec/issues/3549) further changes the lens through which this issue is viewed. The general direction on how TypeSpec handles the general concept of "sealing" via `seal-object-schemas` etc is now well-defined and so I feel there's gap around applying the same consideration to tuples.
At the moment, by default, extra items can be defined beyond the tuple limits. And missing items are also allowed provided the n items present match the first n items in the tuple. Much like the conversation around "sealed" models, I feel a similar mode is needed as the defaults are loose/somewhat unexpected.
This gap means there's still _not quite_ a pathway to globally configure typespec's core emitters such that you get 100% precision (i.e. "what you see defined in the typespec is what is allowed in the generated schema, and nothing else").
I propose two possible configuration approaches:
1. `seal-object-schemas` is made to also drive new strict behaviour around tuples.
2. Or, a separate `seal-tuples` option could be added.
Which would drive new emitter behaviours:
1. **OpenAPI 3.1 and JSON Schema**:
1. Keep `anyOf` for union cases.
1. Keep doing `prefixItems` which it now does
1. Set `@minItems()`, which is still needed for union-of-tuple cases where one or more members are a subset of other members. I don't believe `maxItems` is needed here.
1. Then either:
1. Set `unevaluatedItems` on all tuples to `false`
1. Or, set `items` on all tuples to `false` (since tuples aren't extendable anyway? So we don't care about a hard seal...? Not sure)
1. **OpenAPI 3.0**:
1. I don't think anything can be done, since OpenAPI 3.0 fundamentally does not support any way to achieve positional accuracy on tuples. Probably this option would no-op there, or even error -- since "sealed tuples" just isn't supported and tuples themselves haven't really ever been supported their either in any context. And probably for good reason -- the lack of positional typing support kills any notion of tuple imo. I'm aware of the possibility of unpacking it into a bunch of schemas in a `oneOf` covering every case, but that feels a bit like its obscuring reality and is going to great lengths to do so. But.... I could also be wrong :D.
I suspect the constraints around OpenAPI 3.0 mean a separate `seal-tuples` option might make the most sense.
### Checklist
- [x] Follow our [Code of Conduct](https://github.com/microsoft/typespec/blob/main/CODE_OF_CONDUCT.md)
- [x] Read the [docs](https://typespec.io/docs/).
- [x] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Contributor guide
Assessment
This issue has not been assessed yet.