The comment is correct: it will be nearly impossible to guarantee that only unique arrays will make it through, so no matter what you should have runtime code in place to de-duplicate any array passed in no matter what you do with the typing.
Still, you might want the typing to give users hints that you should only pass in each parameter type at most once. This is possible and not even completely crazy with TypeScript 4.1's support for recursive conditional types:
type UniqueFrom<T extends any[], U> =
U[] extends T ? T :
T extends [infer F, ...infer R] ?
[U, ...UniqueFrom<R, Exclude<U, F>>] : []
type Vals = 'one' | 'two' | 'three' | 'four' | 'five';
function foo<T extends Vals[]>(...t: UniqueFrom<T, Vals>) { }
The idea is that UniqueFrom<T, Vals> should produce a tuple of the same length as T, showing which elements from Vals are still available at each step as you walk through T from left to right. for example:
type U = UniqueFrom<["one", "two", "three"], Vals>;
// [Vals, "two" | "three" | "four" | "five", "three" | "four" | "five"]
This says that the first element of T can be anything from Vals; once the first element is chosen to be "one", now the next element can be anything from Vals except "one". When the second element is chosen to be "two", now the last element can be anything from "three", "four", or "five".
As long as T is assignable to UniqueFrom<T, Vals>, then the compiler will accept a tuple of type T as a rest argument to foo(). Let's see if it works:
foo("one", "two", "three", "four", "five"); // okay
foo("two", "one", "six", "five"); // error!
// -------------> ~~~~~
// type '"six"' is not assignable to type 'Vals'
foo("one", "two", "three", "two", "five"); // error!
// ----------------------> ~~~~~
// type '"two"' is not assignable to type '"four" | "five"'
This looks reasonable to me. The compiler complains about a second parameter named "two", and tells you that it was expecting either "four" or "five" there.
Playground link to code