# Newtype

`$Newtype<T>` is a type-position macro that gives `T` a nominal brand. Two newtypes over the same
base are distinct types, and neither accepts a bare `T` without going through a constructor or
guard.

## Generated Output

```typescript
export type Meters = $Newtype<number>;
```

expands to

```typescript
export type Meters = number & { readonly [__mf_newtype_42]: true };
declare const __mf_newtype_42: unique symbol;
```

Every expansion declares its own `unique symbol`, named from the expansion's id, so the brand needs
no name and cannot collide, even for a `$Newtype` that another macro emits. The `declare const` is
type-only and erases at runtime. A base with a top-level `|` or `&`, or a function or conditional
type, is parenthesized.

`$Newtype` is built in and needs no import. It nests, so `$Newtype<$Newtype<number>>` carries both
brands.

The brand does not involve the alias's own type parameters: with `type Id<T> = $Newtype<string>`,
`Id<User>` and `Id<Order>` are the same type. A brand that should differ per parameter names it in
the type, as in `type Id<T> = string & { readonly [IdOf]: T }` with a
`declare const IdOf: unique symbol`.

## Constructing Values

A newtype has no constructor of its own. Derive `Decode` on the alias: for a primitive base,
`decode` checks the `typeof` and runs any validators written on the alias, which makes it the
validated constructor, and `is` the narrowing guard.

```typescript
/** @derive(Encode, Decode) */
/** @endec(nonNegative, finite) */
export type Meters = $Newtype<number>;

const parsed = Meters.decode(input); // { success, value } | { success, errors }
if (Meters.is(distance)) {
    travel(distance); // narrowed to Meters
}
```

`Encode` writes the bare primitive, and `Default` returns the primitive's default (or the alias's
`@default(value)`) cast to the newtype.

## Error Handling

The macro reports an expansion error when it does not receive exactly one type argument.
