This source generator aims to implement some higher order types known from other languages like TypeScript or F#. A higher order type creates a type from another type - aka computing with types. The currently implemented higher order types are: * Tagged Union (a choice of multiple named values) * Intersection (a type that contains the properties that are present in all given types) * Pick (a selection of the properties of a given type) * Omit (all but a selection of the properties of a given type) All types try to resemble Duck Types as close as is possible in C#. Duck Types are compared by their shape and not by their name as it is with normal C# types (nominal typing).
$ dotnet add package TypeSharperTypeSharper employs Roslyn, the .NET Compiler Platform, to facilitate the generation of C# source code. The primary
orchestrator of this operation is TypeSharperGenerator, which scans the provided codebase for specific attribute
applications that dictate the code generation process. It then delegates the task of generating the code for specific
types to individual type generators, such as TaggedUnionGenerator.
These type generators are designed to inherit from TypeGenerator, and they define their unique attributes. These
attributes, when applied to partial types (like interfaces or classes), act as markers signaling
the TypeSharperGenerator about the types that need code generation.
The generation process doesn't directly interact with the Roslyn API. Instead, it operates on the TsModel API, a
simplified Abstract Syntax Tree (AST) that carries semantic information. This makes the code generation process less
intricate and more focused on the specific needs of TypeSharper.
When a type generator depends on other types, these dependencies are specified as generic parameters of the attribute.
This ensures that the TypeSharperGenerator can ascertain the dependencies between types and generate them in the
correct order, maintaining the integrity and correctness of the generated code. The TypeDependencyGraph is
instrumental in tracking and resolving these dependencies.
TypeGenerator: This is the base class that provides essential functionalities and sets the
contract for type generators.AttributeDefinition: Utilize the TypeGenerator.AttributeDefinition() method
to define your custom attribute.Pick type, the type from which properties are picked is a dependency. This allows
the TypeSharperGenerator to determine the order of code generation based on these dependencies.TsModel instance. The TsModel instance can be used to look up references of dependent types and add new types.
It's important to note that TsModel is immutable, ensuring thread safety and deterministic behavior.TsModel.
In the end, a diff between the updated and the original model is generated as C# source, which is then integrated
into the target project.Model contains the data structures and models used throughout the library.
These models represent TypeScript-like constructs and offer methods to generate their C# counterparts.Similar in spirit to TsDict, TsList wraps .NET's immutable list to make it behave like a value. Its equality members
are tailored to compare the actual elements in the list rather than mere references, bringing value semantics to list
operations. This ensures a more intuitive and predictable behavior when working with lists, especially in scenarios
where content-based comparisons are essential. Though TsList includes a handful of convenience methods, its main
distinction is offering value-based behavior to .NET's immutable lists.
TsDict serves as a thin wrapper around .NET's immutable dictionary, engineered primarily to make the underlying data
structure behave like a value. This means that its equality members are designed to compare the actual contents of the
dictionaries rather than just references. By doing so, it introduces value semantics to dictionary operations in C#,
enabling developers to reason about dictionaries in terms of their actual contents. While it adds a few convenience
methods to ease dictionary operations, the core value of TsDict lies in its provision of true value-based comparisons
for immutable dictionaries.
The core component of the TypeSharper library. This class leverages the power of Roslyn to generate C# source code, introducing TypeScript-like types and constructs. It acts as a bridge, translating TypeScript idioms into their C# counterparts.