```ts
export function expiryCache(capacity: number, ops: (string | number)[][]): number[] {
  if (!Number.isInteger(capacity) || capacity <= 0) {
    throw new Error("Capacity must be a positive integer");
  }

  const cache = new Map<string, { value: number; expiry: number }>();
  const results: number[] = [];

  for (const op of ops) {
    if (!Array.isArray(op) || op.length < 3) {
      throw new Error("Invalid operation format");
    }

    const [operation, time, key] = op;
    let value: number | undefined;
    let ttl: number | undefined;

    if (operation === "set") {
      if (op.length !== 5) {
        throw new Error("Set operation must have exactly 5 arguments");
      }
      [, , key, value, ttl] = op;
      if (!Number.isInteger(value) || value <= 0) {
        throw new Error("Value must be a positive integer");
      }
      if (!Number.isInteger(ttl) || ttl <= 0) {
        throw new Error("TTL must be a positive integer");
      }
    } else if (operation === "get") {
      if (op.length !== 3) {
        throw new Error("Get operation must have exactly 3 arguments");
      }
    } else {
      throw new Error("Unknown operation");
    }

    if (!Number.isInteger(time)) {
      throw new Error("Time must be an integer");
    }

    // Purge dead entries
    for (const [k, entry] of cache.entries()) {
      if (entry.expiry <= time) {
        cache.delete(k);
      }
    }

    if (operation === "set") {
      const expiry = time + ttl;
      cache.set(key as string, { value: value!, expiry });
      // Evict if over capacity
      if (cache.size > capacity) {
        let toEvict: string | null = null;
        for (const [k, entry] of cache.entries()) {
          if (toEvict === null || entry.expiry < cache.get(toEvict)!.expiry ||
              (entry.expiry === cache.get(toEvict)!.expiry && k < toEvict)) {
            toEvict = k;
          }
        }
        if (toEvict !== null) {
          cache.delete(toEvict);
        }
      }
    } else if (operation === "get") {
      const entry = cache.get(key as string);
      results.push(entry && entry.expiry > time ? entry.value : -1);
    }
  }

  return results;
}
```