1 Kumori DSL Type System
The Kumori DSL features a statically-typed system that ensures correctness, consistency, and clarity in your application specifications. By catching errors before deployment, the type system helps you write robust and maintainable code.
1.1 Benefits of a Static Type System
- Early Error Detection: Catches mistakes (typos, incorrect types) during development, preventing deployment failures.
- Consistency: Enforces adherence to defined contracts and schemas.
- Clear Contracts: Reinforces clear interactions between application parts.
- Improved Readability: Makes code easier to understand and maintain.
1.2 Primitive Types
Kumori DSL provides several built-in primitive types:
bool: Boolean values (trueorfalse).string: Unicode text values (e.g.,"some-value").number: Numeric values, including integers and floats (e.g.,1,0.4545).list: A collection of strings or numbers (e.g.,["item1", "item2"]or[1, 2, 3]).any: A universal type that can hold any value. Use it sparingly to bypass type system limitations when necessary.
1.3 Complex Types
1.3.1 Structs
A struct defines a data structure with named fields. Fields can be required or optional (using ?).
1.3.2 Open Structs
Open structs allow arbitrary additional fields, making them flexible for configurations or resources. They are similar to Go’s map[string]Type or TypeScript’s Map<string, Type>.
struct open[]: Accepts any fields with any value type.struct open[Type]: Accepts any fields, but all values must conform toType.
1.3.3 Unions
Union types (also known as enums) are defined using the | operator. A value of a union type can be any of the specified types.
1.3.4 Lists
Lists are defined using []Type:
1.4 Type Definitions
Kumori DSL provides two ways to define new types: alias and type.
1.4.1 alias
- Creates a type synonym for an existing type or type expression.
- Does not introduce a new, distinct type; it simply gives a new name to an existing type.
- Aliases are interchangeable with the type they refer to.
- Useful for creating readable names for complex types or defining unions.
1.4.2 type
- Creates a new, named type definition.
- Introduces a distinct type in the type system, even if its structure matches another type.
- Named types are not interchangeable, even if their structure is identical.
- Important for strict type identity, modularity, and API contracts.
When declaring a variable of a named type, you must explicitly instance it through the constructor:
1.4.3 Declaring Custom Types
Custom types can only be declared inside a library block in a .kumori file.
1.5 Optional Fields and Default Values
1.5.1 Optionals
Any field in a struct can be made optional by adding a ? to its name.
1.5.2 Default Values
Struct fields can have default values. If a field with a default value is omitted, the default is automatically used.
Struct entries within the resource field of artifacts cannot have a default value.
1.6 Assignability
Assignability determines whether a value of one type can be assigned to a variable, field, or parameter of another type.
- Primitive Types: A value of a primitive type can only be assigned to a variable of the same type.
anyType: Theanytype can accept any value.- Aliases: Aliases are fully interchangeable with the types they refer to.
- Named Types: Named types are not assignable to other types, even if their structure matches.
- Structs: For a struct to be assignable, all required fields must be present and have assignable types. Optional fields may be omitted. Extra fields are only allowed in open structs.
- Unions: A value is assignable to a union type if it is assignable to at least one of the union’s member types.
- Lists: A list is assignable if all its elements are assignable to the list’s element type.
1.7 Built-in Functions
The Kumori DSL type system exposes functions as first-class types. However, you can only use the built-in functions provided by the compiler. You cannot define your own functions.
For further reading, see the kumori/builtin package documentation.