# Type system

Kyna checks whether a value fits the type required by a binding, parameter, or return annotation. The compiler keeps parser annotations as `TypeRef` values and resolves them when checking the program.

## Type compatibility

Compatibility is directional: a value may fit a broader type without the broader type fitting the original one.

- `int` and `float` values fit `num`.
- A value fits a union when it fits at least one member of that union.
- `null` fits a nullable type.
- An explicit `any` annotation bypasses static compatibility checks at that location. Inferred, unrelated types do not automatically become `any`.

The analyzer represents types with `kyna::types::Type`. Primitive types use shared instances in the type universe; function signatures, named types, unions, and nullable types form the rest of the graph.

## Collections and other type shapes

The semantic type module can represent fixed arrays, dynamic slices, maps, pointers, structs, structural interfaces, tuples, directional channels, constrained type parameters, and aliases.

These internal representations do not mean that every shape is available in the current source grammar or runtime. Kyna's existing `array<T>` spelling has slice semantics. Array literals preserve their element type when you access an element by index.

## Mutable and constant bindings

Binding mutability is separate from a value's type. The analyzer records whether a binding uses `var` or `const` and rejects assignment to a constant. Runtime cells repeat this check.

Object members have their own mutability. An immutable object reference can still expose a mutable field.

## Function contracts

The analyzer checks parameter types and explicit return annotations. When a function has no return annotation, its result type is currently inferred dynamically at call sites. Explicit return contracts remain strict.

`void` and `null` are distinct types.

## Interfaces

Interfaces (`intf`) are structural contracts checked at `implements` conformance and object-literal assignment:

```kyna
intf Shape {
  area(): float;
}
intf Named<T> extends Shape {
  name: str;
  label?: str;
  (): int;                 // call signature
  [key: str]: int;         // index signature
}
class Circle implements Named<float> {
  public name: str;
  public fn area(): float { return 3.14; }
  public fn _(): int { return 1; }
}
```

- `extends` merges parent contracts (a base's members are inherited); a generic parent can be specialized, e.g. `extends Base<int>` binds the parent's type parameter.
- Generic interface parameters (`intf Named<T>`) are instantiated at `implements`/`extends` sites, with type substitution applied to inherited fields, methods, call signatures, and index signatures.
- Optional properties (`name?: T`) are not required of implementing classes or object literals.
- `implements` requires compatible public fields and methods; method parameter and return types are checked after generic substitution.

Type-definition files (`.kyna.d`, `.d.ky`, `.ky.d`) are ambient: they declare interfaces used only at compile time and never execute.