Skip to content
/ struct Public

Typesafe and Validated structs for Typescript.

License

Notifications You must be signed in to change notification settings

b3nten/struct

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Struct

Struct 🧬

Typescript struct factories and validation

Npm package yearly downloads GitHub stars NuGet stable version

Struct is a Typescript utility library for defining and instantiating typed and prefilled Structs and validating and asserting objects and primitives.

Usage

Struct

Structs are factories for objects. You can instantiate a struct by either providing a type for an empty struct, the default values for a defaulted struct, or a type for the struct and default values for a partially pre-instantiated struct.

Basic usage

Structs with complete default values can infer their type from the provided defaults.

const Vec2 = Struct({ x: 0, y: 0 }); // Creates a struct factory with default values

const position = new Vec2(); // { x: 0, y: 0}

Empty Structs

A struct with no default values should be provided a type signature.

type Vec3 = {x: number, y: number, z: number};

const Vec3 = Struct<Vec3>();

const position = new Vec3({
  x: 1,
  y: 5,
  z: 2
}); // Must provide all required fields.

Partial defaults

For partial default values you must provide a type for both the entire struct and the default values <StructType, DefaultStructValues>. This is due to a limitation of Typescript regarding partial generics.

type Momentum = Vec3 & {velocity: number};

const Momentum = Struct<Momentum, { velocity: number }>({ velocity: 0 });
// <Type of Struct, Default values>
const m = new Momentum({
  x: 2,
  y: 3,
  z: 2 
  // velocity not required for instantiation
}); // { x: 2, y: 3, z: 2, velocity: 0 }

InferStructType

If you have a Struct, you can infer it's type using the InferStructType utility type.

const Euler = Struct({ x: 0, y: 0, z: 0, order: "XYZ" });

type Euler = InferStructType<Euler>; // { x: number, y: number, z: number, order: string }

RequiredProperties

You can infer the required properties of a struct from the struct type and default property type.

type Texture = {
  x: number,
  y: number,
  repeat: number,
  data: Uint8Array
};

type TextureDefaults = { x: number, y: number, repeat: number };

type RequiredTextureProps = RequiredProperties<
  Texture, TextureDefaults
>; // { data: Uint8Array }

const Texture = Struct<Texture, RequiredTextureProps>({
  x: 0, y: 0, repeat: 0
});

const tex = new Texture({
  data: textureData
});

Validated Struct (VStruct)

Validated Structs work similarly to Structs, but use a schema defined with regular Javascript and are validated on creation an property assignment.

Basic

const Vec2 = VStruct({
  x: Number,
  y: Number
});
const pos = new Vec2({
  x: 0, y: 2
}); // { x: 0, y: 2}

Advanced

const User = VStruct({
  id: Number,
  name: String,
  roles: Array(Number),
  address: {
    street: Optional(String),
    country: Union(Country, Number)
  },
  info: Any,
  isAdmin: Optional(Nullable(Boolean)),
  data: Unknown,
  nonUserProperty: Never,
});

const user = new User(possibleUser); // throws if invalid user;
user.address = "123 American St"; // throws

Types

String: string
Number: number
Boolean: boolean
BigInt: bigint
Symbol: symbol
Date:  DateConstructor
Object: ObjectConstructor
Function: FunctionConstructor
Map: MapConstructor
Set: SetConstructor
WeakMap: WeakMapConstructor
WeakSet: WeakSetConstructor
ArrayBuffer: ArrayBufferConstructor
DataView: DataViewConstructor
Int8Array: Int8ArrayConstructor
Uint8Array: Uint8ArrayConstructor
Uint8ClampedArray: Uint8ClampedArrayConstructor
Int16Array: Int16ArrayConstructor
Uint16Array: Uint16ArrayConstructor
Int32Array: Int32ArrayConstructor
Uint32Array: Uint32ArrayConstructor
Float32Array: Float32ArrayConstructor
Float64Array: Float64ArrayConstructor;
undefined: undefined
null: null

Utility Types

Union(Number, String): number | string
Nullable(Function): Function | null
Optional(String): string?
Any: any
Unknown: unknown
Never: never

InferVStructType

If you have a VStruct, you can infer it's type using the InferVStructType utility type.

const Light = VStruct({
  position: {
    x: Number, y: Number, z: Number,
  },
  intensity: Optional(Nullable(Number))
});

type Light = InferVStructType<Light>; 
// { position: { x: number, y: number, z: number}, intensity?: number | null | undefined }

About

Typesafe and Validated structs for Typescript.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published