Skip to main content

Nitro's Typing System

Nitro uses an extensible typing system to efficiently convert between JS and C++ types - statically defined and fully type-safe and null-safe at compile-time.

For example, a JS number will always be a double on the native side:

Math.nitro.ts
interface Math extends HybridObject {
add(a: number, b: number): number
}
HybridMath.hpp
class HybridMath : public HybridMathSpec {
double add(double a, double b);
}

Nitro strictly enforces type-safety and null-safety - both at compile-time and at runtime. This prevents accidentally passing a wrong type to add(..) (for example, a string) and performs null-checks to prevent passing and returning null/undefined values.

On the JS side (TypeScript), type- and null-safety is enforced via TypeScript - so use it!

Nitrogen

Nitrogen ensures that TypeScript definitions are always in sync with native type definitions. You can also use Nitro without nitrogen, in this case TypeScript definitions have to be written manually.

Supported Types

These are all the types Nitro supports out of the box:

JS TypeC++ TypeSwift TypeKotlin Type
numberdouble / int / floatDoubleDouble
booleanboolBoolBoolean
stringstd::stringStringString
bigintint64_t / uint64_tInt64Long
T[]std::vector<T>[T]Array<T> / PrimitiveArray
T?std::optional<T>T?T?
[A, B, ...]std::tuple<A, B, ...>(A, B) 🟡  (#38)
A | B | ...std::variant<A, B, ...>Variant_A_B 🟡  (#39)
Promise<T>std::future<T>Promise<T>Promise<T>
(T...) => voidstd::function<void (T...)>@escaping (T...) -> Void(T...) -> Unit
(T...) => Rstd::function<std::future<R> (T...)>
Record<string, T>std::unordered_map<std::string, T>Dictionary<String, T>Map<String, T>
objectstd::shared_ptr<AnyMap>AnyMapHolder 🟡  (#57)AnyMap
ArrayBufferstd::shared_ptr<ArrayBuffer>ArrayBufferHolderArrayBuffer
..any HybridObjectstd::shared_ptr<HybridObject>HybridObjectSpecHybridObject
..any interfaceTTT
..any enumTTT
..any unionTTT