```ts
export function rankWithPolicy(scores: number[], policy: string, direction: string): number[] {
  if (scores.length === 0) {
    throw new Error("Scores list cannot be empty");
  }

  scores.forEach((score) => {
    if (!Number.isInteger(score)) {
      throw new Error("All scores must be integers");
    }
  });

  const validPolicies = ["dense", "gapped", "entry"];
  if (!validPolicies.includes(policy)) {
    throw new Error(`Invalid policy: ${policy}. Must be one of ${validPolicies.join(", ")}`);
  }

  const validDirections = ["asc", "desc"];
  if (!validDirections.includes(direction)) {
    throw new Error(`Invalid direction: ${direction}. Must be one of ${validDirections.join(", ")}`);
  }

  const sortedScores = [...scores].sort((a, b) => (direction === "asc" ? a - b : b - a));

  const rankMap = new Map<number, number>();
  let currentRank = 1;

  for (let i = 0; i < sortedScores.length; i++) {
    if (!rankMap.has(sortedScores[i])) {
      switch (policy) {
        case "dense":
          rankMap.set(sortedScores[i], currentRank);
          break;
        case "gapped":
          rankMap.set(sortedScores[i], currentRank + i - Array.from(rankMap.keys()).indexOf(sortedScores[i]));
          break;
        case "entry":
          rankMap.set(sortedScores[i], i + 1);
          break;
      }
    }
    if (policy === "dense" || policy === "gapped") {
      currentRank++;
    }
  }

  return scores.map((score) => rankMap.get(score)!);
}
```