```typescript
export function maskFromPrefix(prefix: number): string {
  if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) {
    throw new Error("Invalid prefix: must be an integer between 0 and 32.");
  }

  let mask = "255.255.255.255";
  for (let i = 31; i >= prefix; i--) {
    mask = mask.replace(/\d$/, '0');
  }
  return mask;
}

export function prefixFromMask(mask: string): number {
  if (typeof mask !== "string") {
    throw new Error("Invalid mask: must be a string.");
  }

  const octets = mask.split(".");
  if (octets.length !== 4) {
    throw new Error("Invalid mask: must have exactly four dot-separated fields.");
  }

  for (const octet of octets) {
    if (!/^\d+$/.test(octet) || (octet[0] === "0" && octet.length > 1)) {
      throw new Error("Invalid mask: field must contain only decimal digits.");
    }
    const num = parseInt(octet, 10);
    if (num < 0 || num > 255) {
      throw new Error("Invalid mask: octet must be between 0 and 255.");
    }
  }

  let prefix = 32;
  for (let i = 0; i < octets.length; i++) {
    const num = parseInt(octets[i], 10);
    if (num !== 255 && num !== 0) {
      break;
    }
    prefix--;
  }

  return prefix;
}
```