SharpTS
June 6, 2026 · View on GitHub
A TypeScript interpreter and ahead-of-time compiler written in C#.
Overview
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
Features
Language Support
- 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
Compiler Features
- Static type checking with helpful error messages
- Nominal typing for classes, structural typing for interfaces
- Compile to standalone executables or .NET assemblies
- Reference assembly output for C# interop (
--ref-asm) - IL verification (
--verify)
.NET Interop
- 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
Quick Start
Prerequisites
- .NET 10 SDK or later (required)
- Visual Studio 2026 18.0+ or Visual Studio Code (optional, for IDE support)
Note for MSBuild SDK users: SharpTS.Sdk requires .NET 10 SDK and uses modern C# features for optimal performance.
Installation
Install CLI tool from NuGet (recommended):
dotnet tool install -g SharpTS
Or use TypeScript in a .NET project:
<Project Sdk="SharpTS.Sdk/1.0.0">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<SharpTSEntryPoint>src/main.ts</SharpTSEntryPoint>
</PropertyGroup>
</Project>
Usage
REPL Mode:
sharpts
Run a TypeScript file (interpreted):
sharpts script.ts
Compile to .NET assembly:
sharpts --compile script.ts
dotnet script.dll
Compile to self-contained executable:
sharpts --compile script.ts -t exe
script.exe
Additional 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 enums
Generate 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 $KEY
Package metadata is read from package.json in the source directory.
Decorator support:
Decorators are enabled by default (TC39 Stage 3).
sharpts script.ts # Stage 3 decorators (default)
sharpts --experimentalDecorators script.ts # Legacy (Stage 2) decorators
sharpts --noDecorators script.ts # Disable decorators
Examples
Hello World
// hello.ts
console.log("Hello, World!");
$ sharpts hello.ts
Hello, World!
Classes and Inheritance
// 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 Programming
// 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
Compiled Execution
# Compile to .NET assembly
$ sharpts --compile functional.ts
# Run the compiled assembly
$ dotnet functional.dll
[2, 4, 6, 8, 10]
[2, 4]
15
Use .NET Types from TypeScript
// 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());
$ sharpts --compile dotnet-example.ts
$ dotnet dotnet-example.dll
Hello from .NET!
Access TypeScript classes from .NET (C#)
// 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
Documentation
- 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
Project Status
SharpTS is under active development. See STATUS.md for current feature support and roadmap.
Testing
The standard test suite (xUnit, in SharpTS.Tests/) runs via:
dotnet test
Two additional conformance suites live as standalone projects (not in SharpTS.sln, so the standard dotnet test doesn't pick them up). They each pin against an external corpus via git submodule:
- SharpTS.Test262/ — TC39 ECMA-262 conformance, interpreter + compiled-IL modes.
- SharpTS.TypeScriptConformance/ — TypeScript conformance against the canonical
microsoft/TypeScripttest corpus, type-checker only.
Initialize the submodules and invoke the projects explicitly:
git submodule update --init external/test262 external/typescript
dotnet test SharpTS.Test262/SharpTS.Test262.csproj
dotnet test SharpTS.TypeScriptConformance/SharpTS.TypeScriptConformance.csproj
Both suites use a committed-baseline + diff harness — runs hard-fail on regression or new-pass against the committed bucket assignments. Update baselines after intentional changes via SHARPTS_TEST262_UPDATE_BASELINE=1 or SHARPTS_TSCONFORMANCE_UPDATE_BASELINE=1.
Windows note: the
microsoft/TypeScriptrepo contains paths exceeding Windows' default 260-charMAX_PATH. Setgit config --global core.longpaths truebefore initializing theexternal/typescriptsubmodule.
Contributing
Contributions are welcome! Please read our Contributing Guide for details on:
- Code style guidelines
- How to add new language features
- Submitting pull requests
License
This project is licensed under the MIT License - see the LICENSE file for details.