microsoft / microsoft/typespec
[core] Add signifier that designates a "must-understand" type.
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
### Clear and concise description of the problem
When writing an emitter and deciding how to represent models, there are generally two kinds of types:
- Ordinary models that are safe to represent as if they are equivalent to their shapes.
- Special **must-understand** models that cannot be represented as equivalent to their shapes.
Examples of must-understand models are:
- TypeSpec.Array
- TypeSpec.Record
- TypeSpec.Streams.Stream
The first two examples are covered by the core `isStdType` function, but `Stream` isn't. These models all carry special meaning that is part of the type's identity, not part of its shape.
Taking Stream as an example:
```tsp
@streamOf(Type)
model Stream {}
```
An emitter cannot construct a valid representation of Stream (or any type with `@streamOf` on it) unless it specifically recognizes the streamOf decorator. If an emitter tries to represent Stream as a normal model, it will treat it as an empty model, violating the spec.
## Proposal
Add new metadata:
```ts
export function setMustUnderstandType(program: Program, type: Type);
export function isMustUnderstandType(program: Program, type: Type): boolean;
```
The `@streamOf` decorator would call `setMustUnderstandType` internally. We could also optionally expose a decorator for other libraries to declare their own must-understand concepts:
```
extern dec mustUnderstand(target: unknown);
```
This will allow emitters to simply check `isMustUnderstandType` on any type reference rather than tracking a list of fully qualified must-understand type names.
Unlike scalars, it is probably not okay for emitters to default to treating the type as if it were `unknown` for unrecognized must-understand types. I expect emitters would yield errors if they encounter a type where `isMustUnderstandType` returns true, but they don't recognize it. Types like `Stream` require specific handling to represent as stream types which implement specific language interfaces to support this functionality, and the emitter cannot just assume that any value the user passes to it can be serialized/deserialized as a stream.
### 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.