Adds more static typing and a C#-like structure to JavaScript without relying on TypeScript.
TypeSalad is a lightweight library that provides typed wrappers, metadata reflection, and convenience utilities for JavaScript. It includes classes such as SaladString
, SaladInt
, SaladBool
, and more—emulating a statically typed style similar to C#, all while staying in pure JavaScript (no compile step required).
- Features
- Installation
- Usage
- API Overview
- Extending TypeSalad (Packages)
- Examples
- Contributing
- License
-
Typed Wrappers: Classes like
SaladString
,SaladInt
,SaladBool
,SaladDate
, etc., each storing an internal value but maintaining a.type
property. -
C#-like Syntax: Simulates typed structures and simple reflection (e.g.,
addMetadata
,getMetadata
, andQueryableArray
). -
No Build Step Required: Pure JavaScript, no TypeScript config needed. Just
import
and go. -
Optional Event System: Provides a simple
EventEmitter
class for event-based programming. -
Extensible Architecture: A
System
singleton supports dynamically loading “packages” (e.g.,SaladMath
,SaladLinq
, etc.) via ES modules for additional functionality.
npm install typesalad
(Requires Node.js to install.)
import {
System,
SaladString,
SaladInt,
TypedIf
} from 'typesalad';
// Create typed values
const greeting = new SaladString('Hello, TypeSalad');
const numberOne = new SaladInt(1);
const numberTwo = new SaladInt(2);
// Print using System
System.Print(greeting); // Logs: "Hello, TypeSalad"
// Compare with TypedIf
TypedIf(
numberOne,
numberTwo,
() => console.log('They are equal!'),
() => console.log('They are not equal!')
);
// Logs: "They are not equal!"
const {
System,
SaladString,
SaladInt,
TypedIf
} = require('typesalad');
(If your package.json
has "type": "module"
, you’ll use ES Modules. Otherwise, CommonJS might be your default.)
- SaladString: Wraps a string.
- SaladInt: Wraps an integer.
- SaladFloat: Wraps a floating-point number.
- SaladBool: Wraps a boolean.
-
SaladDate: Wraps a
Date
object. - SaladArray: A typed, array-like structure.
- SaladObject: A typed, object-like structure.
- SaladVec2, SaladVec3: Vector classes for 2D/3D operations.
Each class has a .type
property (e.g. "String"
, "Int"
, etc.) and methods like toString()
, valueOf()
, or other specialized methods.
-
TypedIf(expr1, expr2, onEqual, onNotEqual): Checks if two typed objects share the same
.type
and.valueOf()
, then invokes the appropriate callback. - createGenericList(expectedType): Creates a class that enforces a specific type for all items added.
-
QueryableArray: A chainable array wrapper with
.where()
,.select()
,.orderBy()
, etc. - Overloadable: Allows defining multiple method overloads based on parameter types.
- addMetadata(obj, key, value) and getMetadata(obj, key): Simple reflection-like metadata storage.
-
System (singleton):
-
Print(value)
: Logs typed strings. -
Concat(expr1, expr2)
: Concatenates two typed values (String or Int). -
StoreData(key, value) / RetData(key)
: Simple typed storage. -
UsePackage(packageName, packagePath, exportName?)
: Dynamically imports a package and stores it underSystem.Packages
.
-
TypeSalad is designed to be easily extensible. You can create custom “packages” in separate .mjs
files and load them via the built-in System.UsePackage()
method.
By default, TypeSalad includes four optional “built-in” packages that demonstrate how to extend functionality:
-
SaladMath (imported as
"SaladMath"
):System.UsePackage("SaladMath", "./packages/SaladMath.mjs"); // Then access with System.SaladMath
- Exposes classes like
ImagInt
andVector
for complex arithmetic and vector math.
- Exposes classes like
-
SaladLinq (imported as
"SaladLinqPackage"
):System.UsePackage("SaladLinq", "./packages/SaladLinq.mjs", "SaladLinqPackage"); // Then access with System.SaladLinq
- Provides chainable query operators (like a LINQ-inspired API).
-
SaladFiles (imported as
"SaladFilesPackage"
):System.UsePackage("SaladFiles", "./packages/SaladFiles.mjs", "SaladFilesPackage"); // Then access with System.SaladFiles
- Offers typed read/write for text and JSON files (Node.js environments).
-
SaladDOM (imported as
"SaladDOMPackage"
):System.UsePackage("SaladDOM", "./packages/SaladDOM.mjs", "SaladDOMPackage"); // Then access with System.SaladDOM
- Lets you create and manipulate DOM elements using typed wrappers in the browser.
You can create your own packages in a similar fashion—just export a class that extends TypeSalad
(or uses typed objects) and load it via System.UsePackage("YourPackageName", "./path/YourPackage.mjs", "ExportedClassName")
.
-
Using
SaladArray
:import { SaladArray, SaladString } from 'typesalad'; const arr = new SaladArray([ new SaladString("Apple"), new SaladString("Banana") ]); arr.push(new SaladString("Cherry")); console.log(arr.length); // 3 console.log(arr.toString()); // [Apple, Banana, Cherry]
-
Overloading Methods:
import { Overloadable, SaladString, SaladInt } from 'typesalad'; const myObj = new Overloadable(); myObj.defineOverload('doSomething', ['String'], function(str) { return `Doing something with string: ${str}`; }); myObj.defineOverload('doSomething', ['Int'], function(intVal) { return `Doing something with int: ${intVal}`; }); console.log(myObj.callOverload('doSomething', new SaladString('Hello'))); // => "Doing something with string: Hello" console.log(myObj.callOverload('doSomething', new SaladInt(42))); // => "Doing something with int: 42"
-
Metadata Reflection:
import { addMetadata, getMetadata } from 'typesalad'; const user = {}; addMetadata(user, 'role', 'admin'); console.log(getMetadata(user, 'role')); // "admin"
-
Loading a Built-in Package:
import { System, SaladInt } from 'typesalad'; // Load SaladMath package await System.UsePackage("SaladMath", "./packages/SaladMath.mjs"); const { add, multiply } = System.SaladMath; // Typed math operations const a = new SaladInt(3); const b = new SaladInt(4); const result = multiply(a, b); // => SaladInt(12) console.log(result.valueOf()); // 12
Contributions are welcome! Here’s how you can help:
- Fork the repository on GitHub and clone it locally.
- Create a new branch with a descriptive name.
- Make your changes, add new features or bug fixes, and (if possible) include tests.
- Push to your fork and create a Pull Request.
Please file an issue if you find any bugs or have ideas for improvements.
This project is licensed under the MIT License. See the LICENSE file for details.