Given a strongly-typed tuple created using a technique such as described here:
const tuple = (...args: T) => args;
const furnitu
There are ways of doing this but it might be a bit messy for you. The two stumbling blocks here are the absence of partial type parameter inference and invalid types. Here is my solution:
type Furniture = 'chair' | 'table' | 'lamp' | 'ottoman';
const exhaustiveStringTuple = () =>
(
...x: L & ([T] extends [L[number]] ? L : [
Error, "You are missing ", Exclude])
) => x;
const missingFurniture = exhaustiveStringTuple()('chair', 'table', 'lamp');
// error, [string, string, string] is not assignable to parameter of type
// ["chair", "table", "lamp"] & [Error, "You are missing", "ottoman"]
const extraFurniture = exhaustiveStringTuple()(
'chair', 'table', 'lamp', 'ottoman', 'bidet');
// error, "bidet" is not assignable to a parameter of type 'Furniture'
const furniture = exhaustiveStringTuple()('chair', 'table', 'lamp', 'ottoman');
// okay
As you can see, exhaustiveStringTuple is a curried function, whose sole purpose is to take a manually specified type parameter T and then return a new function which takes arguments whose types are constrained by T but inferred by the call. (The currying could be eliminated if we had proper partial type parameter inference.) In your case, T will be specified as Furniture. If all you care about is exhaustiveStringTuple, then you can use that instead:
const furnitureTuple =
(
...x: L & ([Furniture] extends [L[number]] ? L : [
Error, "You are missing ", Exclude])
) => x;
const missingFurniture = furnitureTuple('chair', 'table', 'lamp');
// error, [string, string, string] is not assignable to parameter of type
// ["chair", "table", "lamp"] & [Error, "You are missing", "ottoman"]
const extraFurniture = furnitureTuple('chair', 'table', 'lamp', 'ottoman', 'bidet');
// error, "bidet" is not assignable to a parameter of type 'Furniture'
const furniture = furnitureTuple('chair', 'table', 'lamp', 'ottoman');
// okay
The other issue is that the error you get when you leave out a required argument is