> For the complete documentation index, see [llms.txt](https://docs.activejs.dev/activejs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.activejs.dev/activejs/guides/type-safety.md).

# Typings

ActiveJS is strictly typed, it does its best to infer and enforce as many typings as possible. \
However, where it can't infer a type, it uses generics so that you can pass a type.

For example, [Units](/activejs/fundamentals/units.md), [Systems](/activejs/fundamentals/systems.md), and [Action](/activejs/fundamentals/action.md) accept a type for their value.\
[Cluster](/activejs/fundamentals/cluster.md) doesn't need to be passed types, as it can infer the types from the provided members automatically.

## Units

[BoolUnit](/activejs/fundamentals/units/boolunit.md), [NumUnit](/activejs/fundamentals/units/numunit.md), and [StringUnit](/activejs/fundamentals/units/stringunit.md) don't accept a type because it's already implied as `boolean`, `number`, and `string`, respectively.

[ListUnit](/activejs/fundamentals/units/listunit.md)'s value already has an `array` type, but it can't know about the type of items that the array is going to contain. You can pass it at the time of instantiation.

```typescript
// a ListUnit whose value type would be string[]
const namesList = new ListUnit<string>();

namesList.push('Mr. Anderson'); // works
namesList.dispatch(['Trinity', 'Morpheus']) // works

namesList.push(737); // linting error, invalid value
namesList.dispatch([737]) // linting error, invalid value
```

[DictUnit](/activejs/fundamentals/units/dictunit.md)'s value already has an `object` literal type, but it doesn't know the type of key-value pairs it's going to hold. You can pass it at the time of instantiation.

```typescript
// a DictUnit whose value type would be {[key in 'a' | 'b' | 'c']: number}
const someDict = new DictUnit<{[key in 'a' | 'b' | 'c']: number}>();

someDict.set('a', 1993) // works
someDict.dispatch({a: 1, b: 2, c: 3}) // works

someDict.set('b', 'not a number') // linting error, invalid value
someDict.set('d', 1993) // linting error, invalid key
someDict.dispatch({a: 1, b: 2}) // linting error, property 'c' is missing
```

[GenericUnit](/activejs/fundamentals/units/dictunit.md)'s value has an `any` type, it allows all types of values and leaves the typings to the developer. You can pass it at the time of instantiation.

```typescript
// a GenericUnit whose value type would be string | number | boolean
const primitivesUnit = new GenericUnit<string | number | boolean>();

primitivesUnit.dispatch(42); // works
primitivesUnit.dispatch('HanuMan'); // works
primitivesUnit.dispatch(true); // works

primitivesUnit.dispatch(['you and I']) // linting error, invalid value
primitivesUnit.dispatch({youAreMine: true}) // linting error, invalid value
```

## Systems

[AsyncSystem](/activejs/fundamentals/systems/asyncsystem.md) doesn't have a value of its own, it derives value from its member Units, 3 of them are GenericUnits and 1 is BoolUnit. The three GenericUnits can be supplied types through AsyncSystem's generics.

```typescript
type UserQuery = number; // type for queryUnit's value
type UserData = string; // type for dataUnit's value
type UserError = {status: number, message: string}; // type for errorUnit's value

// pass the types to AsyncSystem
const userSystem = new AsyncSystem<UserQuery, UserData, UserError>();

userSystem.queryUnit.dispatch(666) // works
userSystem.dataUnit.dispatch('evil string') // works
userSystem.errorUnit.dispatch({status: 418, message: "I'm a teapot"}) // works

userSystem.queryUnit.dispatch('not a number') // linting error, invalid value
userSystem.dataUnit.dispatch(420) // linting error, invalid value
userSystem.errorUnit.dispatch("I'm a teapot") // linting error, invalid value
```

[Custom AsyncSystem](/activejs/fundamentals/systems/custom-asyncsystem.md) doesn't need to be passed types explicitly, since it doesn't create Units itself, they are provided externally, and it can infer the types from the provided Units.

## Action

[Action](/activejs/fundamentals/action.md) has `any` as its default value type, it can be restricted by passing a specific type through generics.

```typescript
// an Action that will allow strings
const heroAction = new Action<string>();

heroAction.dispatch('fight injustice') // works
heroAction.dispatch('defeat bullies') // works

heroAction.dispatch(['catch', 22]) // liniting error, invalid value
```
