#Keep only literals from string type
24 messages · Page 1 of 1 (latest)
in this case the type is reduced fully to string, you'd need string & {} to preserve the union at all
I am using a library that I cant edit, which provides me this type. I am stuck then 😦
what library? that type is probably pointless
from there you can use distribution to remove string
Preview:ts ... type WithoutString<T extends string> = T extends T ? string extends T ? never : T : never ...
hmm
as mkantor said, the type is pretty much useless at that point.
did you maybe miss something when reducing the example?
Corporate library - I dont want to go in details about it - I hoped we could have some magic trick in typescript.
But ya, the type is useless, I will sweat a bit to have it changed 😬
Thank you all 🙂
What is the point of T extends T?
I see it a lot but I don’t get its reason for it being there. Wouldn’t it always be true (aka T does extend T)?
@sonic patrol It makes it a distributive conditional
type Box<T> = { value: T };
type BoxDistributive<T> = T extends T ? { value: T } : never;
type Example = Box<string | number> // { value: string | number }
type Example2 = BoxDistributive<string | number>; // { value: string } | { value: number }
The distributive thing, everytime i read about it, everytime i squint 😄
Yeah; it's one of the stranger parts of TS behavior.
It's useful but pretty unintuitive in how it's triggered.
yeah i personally use T extends T to mark distribution, but other tautologies would work too, like extends unknown, extends any, extends <constraint of T>
I will try to recall the precise use-case, but I rememver vaguely one time where distributive behavior was not wanted and we had to find hacks to prevent it. this is when i read about it actually 😄
Yeah, you run into that occasionally and end up doing something like [T] extends [OtherThing] to prevent it.
Sort of a classic example, trying to write an IsNever utility requires preventing the distrubtion because never is treated like an empty union:
type IsNever_Broken<T> = T extends never ? "Yes" : "No";
type Test1 = IsNever_Broken<never>; // Expected "Yes", but got never, because it distributed the never
type IsNever<T> = [T] extends [never] ? "Yes" : "No";
type Test2 = IsNever<never>; // Got "Yes"
This is why ts-toolbelt is so complex to look at
So basically T extends T ? T : never and [T] are opposites of each other. The T extends T distributes the union in T and [T] keeps it together. Is that right?
any T extends ... where T is dynamic (generic or inferred) is distributed.
[T] extends ... isn't in this form, so it isn't distributed