microsoft / microsoft/typespec

[core] Add signifier that designates a "must-understand" type.

Open
#5,275 0 comments 0 reactions 0 assignees View on GitHub
compiler:core design:needed triaged:core
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.