What is the difference between these two "extends" clause?
(A whole bunch of idk the answer but here's some digging I did to maybe give you some context and related info)
This both baffles me and excites me. Essentially you made me realize "unknown[] | [unknown]" can be used to infer tuples. I always wanted to do this. This does seem hacky and I cant figure out how this works. I found this ts-essentials type for tuple. Then I did a little more digging and found this github reply explaining how this works. This helps us a bit. We now know that "unknown[] | [unknown]" forces the complier to infer the tuple type. But why? I dont know that yet. Cant seem to find anything to explain this behavior.
My thought before I did some research on this. So I cant directly answer your question, but I came across this related stackoverflow post. You can use rest parameters to easily infer tuple types. I like this method because it seems its something the typescript creators intended. But it adds runtime boiler plate and thats not good.
I found this other way(solution 2) to do this, but still not a fully proper solution. With this one you require the user of the function to do "as const" on the array.
// solution 1
function tuple<T extends unknown[]>(...v: T) {
return v;
}
function rSelf3<T>(vs: T): T {
return vs;
}
const nVal3 = rSelf3(tuple("a", 1, true));
// solution 2
type Writable<T> = { -readonly [P in keyof T]: T[P] };
function rSelf4<T extends readonly unknown[]>(vs: T): Writable<T> {
return vs;
}
const nVal4 = rSelf4(["a", 1, true] as const);