4 ms·
One think I struggled a lot with until I got it is that the TypeScript types and the JavaScript code live in totally separate universes, and you cannot cross fr
by 323 4y ago
One think I struggled a lot with until I got it is that the TypeScript types and the JavaScript code live in totally separate universes, and you cannot cross from the type world to JavaScript values because the types are erased when transpilling - meaning they can't leave any trace.
This means that it's impossible to write this function:
function isStringType<T>(): boolean { return ... }
const IS_STRING: boolean = isStringType<string>();
At best you can do something like this, which is inconvenient for more complex cases:
function isStringType<T, IsString extends boolean = T extends string ? true : false>(isString: IsString): boolean { return isString }
const IS_STRING_1: boolean = isStringType<string>(true); // compiles
const IS_STRING_2: boolean = isStringType<string>(false); // type error
You basically need to pass the actual result that you want in and just get a type error if you pass in the wrong one. Still better than nothing.
Link if you want to play with it online: https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABDAzgZSgJxmA5gFQE8AHAUwB58AaRASXSx10VIA8pSwATFRAIzhwANqQCGSALyJ8Ldpx6IUjPIgD8iLCFKIAXImCihKUgD4AFKgzY8e+laYBKPQOFikAb0SZSUEJiSWyswAvgBQoRAISnRoAPpo+ABKtAByAOKxAIzOgiLiiFKB1gQkFErF5pqkDgDciAD09YiRALbEMCIoEVFQMfFJqRkATDmu+YUMxURk5OVM5gZG1XWNGqUsmJhwmKFAA https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABDA...
Put another way, you can't do reflection with TypeScript.
You can write that function in C++ templates, and I naively assumed that it's possible in TypeScript too, since from my observations TypeScript allows complex typing to be expressed easier in general than C++.
- rideg 4y agoYou can use type guards for something similar: https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types https://www.typescriptlang.org/docs/handbook/advanced-types....
- melony 4y agoDoes TypeScript support dynamic dispatch? JS by nature is dynamically typed you should be able to introspect at get the type at runtime.
- davidatbu 4y agoYou might be interested in DeepKit[0]. In short, it enables introspection/reflection of typescript types at runtime, and builds off of that to do super interesting things like an ORM, an API framework, ... etc. [0] https://deepkit.io/ https://deepkit.io/
- 323 4y agoThanks, their @deepkit/type is exactly what I would need, but it seems they do that by a TypeScript plugin, and I'm in an esbuild setup which completely bypasses TypeScript. But I will check if maybe I can use DeepKit to auto-generate files with the reflection info I need as a separate build step.
- iainmerrick 4y agoI think that’s actually a positive feature of TypeScript -- a useful limitation. Reflection is generally a bad idea and it’s good to be forced to do without it. It is a bit annoying sometimes that you can’t have overloaded functions with different types, but in that case you can usually just give the overloads different names, and usually that’s better for readability anyway. (Or if you really want to, write one function and use JS reflection to do the overloading manually) (but you really don’t!) Here’s an interesting discussion of the overloading question in Swift: https://belkadan.com/blog/2021/08/Swift-Regret-Type-based-Overloading/ https://belkadan.com/blog/2021/08/Swift-Regret-Type-based-Ov...
- brundolf 4y agoWanted to note that you can do function signature overloading in typescript- you just have to have a single function at the bottom that encapsulates all the different signatures and then branches its logic dynamically based on the values it's given: https://stackoverflow.com/questions/13212625/typescript-function-overloading/13212871#13212871 https://stackoverflow.com/questions/13212625/typescript-func... I actually think this is a super cool and elegant way to do overloading
- jcelerier 4y ago> Reflection is generally a bad idea it is not - dynamic reflection certainly has its issues, but static reflection is absolutely fine > it’s good to be forced to do without it. it just leads to people reinventing it even more badly with separate tools
- iainmerrick 4y agoYou’re right, I was just thinking about dynamic reflection. My concern is with fiddly runtime stuff like “instanceof” -- I find that can go wrong in surprising ways. Better to just trust values to implement the interface they say they implement rather than trying to forcibly cast them.
- adamddev1 4y agoHow do you give the overloads different names? Can you give a little example?
- likeclockwork 4y agoThat boundary is why I have a hard time taking TypeScript seriously. A type system that doesn't participate in code generation is what.. just for linting and documentation basically? Is that what we are become? Is that all people think a type system is good for? Worse there is one value that is both a user-definable TypeScript type and a JS value.
- nawgz 4y ago> That boundary is why I have a hard time taking TypeScript seriously. A type system that doesn't participate in code generation is what How is being able to check code correctness at compile-time even close to "just linting and documentation basically"? This has to be a bad faith argument > Worse there is one value that is both a user-definable TypeScript type and a JS value. What does this even mean? I don't think you understand TypeScript.
- likeclockwork 4y agoIt's just fancy documentation. It doesn't contribute to behavior at all. Typescript can describe polymorphism, lamely, but it can't drive it.
- nawgz 4y ago> It doesn't contribute to behavior at all I agree that TypeScript, in and of itself, doesn't change the way the code executes. This is self-evident. But the idea that that makes it simply "fancy documentation" is hilarious. I have never seen documentation that can tell you at compile-time how your code will behave, it's fundamentally stupid to argue that static type checking is in any way comparable with documentation
- deleted 4y ago[deleted]