Closed ruojianll closed 3 years ago
Thank you!
The type definitions are complex
Yes, definitely the most complex I've ever had to come up with. It takes some time to get back in the headspace of these types whenever I try to improve them.
How can I get more knowledge about them?
This should be easier to learn, there should be advanced type techniques and concepts articles out there but I never found any. These are also quite abstract and hard to search for on search engine, but any time I got lucky it always went to a question someone posted in an issue in the TypeScript GitHub repo. So I would recommend thinking about what you want to solve and the dozens of ways you could word it - and search right in that repo's issues.
I think the most important techniques I've used in these definitions are the following:
T extends { x: infer Y } ? Y : false
will tell me that T
is an object with X
and in the true section of the ternary, I now have the type for Y
. This can get very nested, and is necessary when deep inspecting a type.MyType<T> = { [K in keyof T]: T[K] extends number ? number : never }[keyof T]
that will convert the T
to another object but with only number properties and all others will be never, then [keyof T]
says return the property names which were non-never. So now I have a strict list of properties.T extends never
would suffice. But you need to do [T] extends [never]
. There are some more complex work arounds I had to do, I only was able to figure some of it out by pulling out the problem and making it as simple as possible and trying to solve it on https://www.typescriptlang.org/play before integrating it into the already complex types.
I hope this helps!
@ClickerMonkey Thank for your post. Would you explain this point?
Sometimes you want to check for an exact type, for example you want to make sure if something is "never" you would think T extends never would suffice. But you need to do [T] extends [never].
There are special typescript types (never, unknown, any) that could have meaning in your types, and sometimes you need to check if something is "never". In these type definitions I would use "never" to mean that a mutation or action doesn't have a payload, so if a user tries to pass one it errors. You can check types by doing stuff like T extends string
or T extends { x: number }
but if you want to check if something is never you have to convert them to tuples and then compare because never/unknown/any are special. So you do [T] extends [never]
@ClickerMonkey Thank for your helps. I will keep diving in it.
I'm amazing on you work. The type definitions are complex. How can I get more knowledge about them? The documents about type definitions are really poor.