```ts
export function fillPlaceholders(
  text: string,
  slots: Record<string, string>
): string {
  if (typeof text !== "string" || typeof slots !== "object") {
    throw new Error("Invalid arguments");
  }

  let out = "";
  let i = 0;
  while (i < text.length) {
    if (text[i] === "%" && i + 1 < text.length && text[i + 1] === "%") {
      out += "%";
      i += 2;
    } else if (text[i] === "%") {
      let j = i + 1;
      while (j < text.length && text[j] !== "%") {
        j++;
      }
      if (j === text.length) {
        throw new Error("Unmatched '%'");
      }
      const slotName = text.slice(i + 1, j);
      if (!slots.hasOwnProperty(slotName)) {
        throw new Error(`Unknown slot: ${slotName}`);
      }
      out += slots[slotName];
      i = j + 1;
    } else {
      out += text[i++];
    }
  }

  return out;
}
```