A TypeScript interpreter and ahead-of-time compiler written in C#.
SharpTS is an implementation of a TypeScript interpreter and compiler. It implements the complete pipeline from source code to execution:
- Lexical Analysis - Tokenizing source code
- Parsing - Building an Abstract Syntax Tree
- Type Checking - Static type validation
- Execution - Either interpretation or compilation to .NET IL
SharpTS supports two execution modes:
- Interpretation - Tree-walking execution for rapid development
- AOT Compilation - Compile TypeScript to native .NET assemblies
- Types:
string,number,boolean,null,any,void,unknown,never - Generics: Generic functions, classes, and interfaces with type constraints
- Advanced Types: Union (
|), intersection (&), tuples, literal types - Arrays: Typed arrays with
push,pop,map,filter,reduce,forEach, etc. - Objects: Object literals with structural typing
- Classes: Constructors, methods, fields, inheritance,
super, static members - Abstract Classes: Abstract classes and abstract methods
- Interfaces: Structural type checking (duck typing)
- Functions: First-class functions, arrow functions, closures, default parameters
- Async/Await: Full
async/awaitwithPromise<T>and combinators (all,race,any) - Modules: ES6
import/exportwith default, named, and namespace imports - Decorators: Legacy and TC39 Stage 3 decorators with Reflect metadata API
- Control Flow:
if/else,while,do-while,for,for...of,for...in,switch - Error Handling:
try/catch/finally,throw - Operators:
??,?.,?:,instanceof,typeof, bitwise operators - Destructuring: Array/object destructuring with rest patterns
- Built-ins:
console.log,Math,Date,Map,Set,RegExp,bigint,Symbol, string methods
- Static type checking with helpful error messages
- Nominal typing for classes, structural typing for interfaces
- Compile to standalone .NET executables
- Reference assembly output for C# interop (
--ref-asm) - IL verification (
--verify)
- Use .NET types from TypeScript via
@DotNetTypedecorator - Access BCL classes like
StringBuilder,Guid,DateTime,TimeSpan - Automatic type conversion and overload resolution
- Compile TypeScript for C# consumption with reflection or direct reference
- .NET 10 SDK or later (required)
- Visual Studio 2026 18.0+ (optional, for IDE support)
Note for MSBuild SDK users: SharpTS.Sdk requires .NET 10 SDK and uses modern C# features for optimal performance.
Install CLI tool from NuGet (recommended):
dotnet tool install -g SharpTSOr use the MSBuild SDK in your project:
<Project Sdk="SharpTS.Sdk/1.0.0">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<SharpTSEntryPoint>src/main.ts</SharpTSEntryPoint>
</PropertyGroup>
</Project>Or build from source:
git clone https://github.com/nickna/SharpTS.git
cd SharpTS
dotnet buildREPL Mode:
sharptsRun a TypeScript file (interpreted):
sharpts script.tsCompile to .NET assembly:
sharpts --compile script.ts
dotnet script.dllCompile with custom output:
sharpts --compile script.ts -o myapp.dllAdditional compiler options:
sharpts --compile script.ts --ref-asm # Reference assembly for C# interop
sharpts --compile script.ts --verify # Verify emitted IL
sharpts --compile script.ts --preserveConstEnums # Keep const enumsGenerate NuGet package:
sharpts --compile Library.ts --pack # Creates Library.1.0.0.nupkg
sharpts --compile Library.ts --pack --version 2.0.0-beta # Custom version
sharpts --compile Library.ts --pack --push https://api.nuget.org/v3/index.json --api-key $KEYPackage metadata is read from package.json in the source directory.
Decorator support:
sharpts --experimentalDecorators script.ts # Legacy (Stage 2) decorators
sharpts --decorators script.ts # TC39 Stage 3 decorators// hello.ts
console.log("Hello, World!");$ sharpts hello.ts
Hello, World!// animals.ts
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): string {
return this.name + " makes a sound";
}
}
class Dog extends Animal {
speak(): string {
return this.name + " barks!";
}
}
let dog = new Dog("Rex");
console.log(dog.speak());$ sharpts animals.ts
Rex barks!// functional.ts
let numbers: number[] = [1, 2, 3, 4, 5];
let doubled = numbers.map((n: number): number => n * 2);
let evens = numbers.filter((n: number): boolean => n % 2 == 0);
let sum = numbers.reduce((acc: number, n: number): number => acc + n, 0);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(evens); // [2, 4]
console.log(sum); // 15# Compile to .NET assembly
$ sharpts --compile functional.ts
# Run the compiled assembly
$ dotnet functional.dll
[2, 4, 6, 8, 10]
[2, 4]
15// Use BCL types directly in TypeScript
@DotNetType("System.Text.StringBuilder")
declare class StringBuilder {
constructor();
append(value: string): StringBuilder;
toString(): string;
}
let sb = new StringBuilder();
sb.append("Hello from .NET!");
console.log(sb.toString());// Compile your TypeScript with --ref-asm:
var person = new Person("Alice", 30.0); // Direct instantiation
Console.WriteLine(person.name); // Direct property access
string greeting = person.greet(); // Typed return values- Using .NET Types - Use .NET BCL and libraries from TypeScript
- .NET Integration - Consume compiled TypeScript from C#
- MSBuild SDK Guide - Integrate SharpTS into your .NET build process
- Architecture Guide - Deep dive into the compiler/interpreter internals
- Contributing Guide - How to contribute to the project
SharpTS is under active development. See STATUS.md for current feature support and roadmap.
Looking for help with:
- Additional TypeScript features
- IL compiler feature parity
- Performance optimizations
- Test coverage
Contributions are welcome! Please read our Contributing Guide for details on:
- Code style guidelines
- How to add new language features
- Submitting pull requests
This project is licensed under the MIT License - see the LICENSE file for details.