```ts
export function weighUnit(spec: string, masses: Record<string, number>): number {
  if (typeof spec !== "string") {
    throw new Error("Invalid spec type");
  }
  if (spec.length === 0) {
    throw new Error("Spec cannot be empty");
  }

  let at = 0;
  const outer: { sum: number; bracket: string }[] = [];
  let sum = 0;

  const readCount = (): number => {
    let digits = "";
    while (at < spec.length && spec[at] >= "0" && spec[at] <= "9") {
      digits += spec[at];
      at += 1;
    }
    if (digits.startsWith("0")) {
      throw new Error("Count cannot start with zero");
    }
    return digits === "" ? 1 : Number(digits);
  };

  const readName = (): string => {
    let name = "";
    while (
      at < spec.length &&
      ((name.length === 0 && spec[at] >= "A" && spec[at] <= "Z") ||
        (name.length > 0 && spec[at] >= "a" && spec[at] <= "z"))
    ) {
      name += spec[at];
      at += 1;
    }
    if (!/^[A-Z][a-z]{0,2}$/.test(name)) {
      throw new Error("Invalid core name");
    }
    return name;
  };

  while (at < spec.length) {
    const ch = spec[at];
    if (ch === "(" || ch === "[") {
      outer.push({ sum, bracket: ch });
      sum = 0;
      at += 1;
    } else if (ch === ")" || ch === "]") {
      at += 1;
      const count = readCount();
      const last = outer.pop();
      if (!last) {
        throw new Error("Closing bracket without matching opener");
      }
      if ((ch === ")" && last.bracket !== "(") || (ch === "]" && last.bracket !== "[")) {
        throw new Error("Mismatched brackets");
      }
      sum = last.sum + sum * count;
    } else {
      const name = readName();
      const mass = masses[name];
      if (mass === undefined) {
        throw new Error(`Unknown core name: ${name}`);
      }
      sum += mass * readCount();
    }
  }

  if (outer.length !== 0) {
    throw new Error("Opener without matching closer");
  }

  return sum;
}
```