[HN Gopher] Learn how to unleash the full potential of the type ...
       ___________________________________________________________________
        
       Learn how to unleash the full potential of the type system of
       TypeScript
        
       Author : NeekGerd
       Score  : 296 points
       Date   : 2022-09-20 15:31 UTC (7 hours ago)
        
 (HTM) web link (type-level-typescript.com)
 (TXT) w3m dump (type-level-typescript.com)
        
       | bwestergard wrote:
       | This is fantastic! I've often had to advise coworkers to read
       | documentation for OCaml or Rust to learn idiomatic, functional,
       | statically typed programming. It's great to see a Typescript
       | specific resource with exercises.
        
       | mikessoft_gmail wrote:
        
       | downvoteme77221 wrote:
       | my HTML blog only has 30 lines of JS. i didn't need a framework
       | and i certainly don't need types. grumble grumble web should just
       | be simple html javascript grumble serverside render in my pet
       | language grumble /s
        
         | cutler wrote:
         | Add another 1 to your army. We all know how Typelevel Scala
         | ended.
        
         | jaredcwhite wrote:
         | I feel seen.
        
       | Rapzid wrote:
       | I wish this issue would get addressed:
       | https://github.com/microsoft/vscode/issues/94679
       | 
       | Showing fully resolved types in Intellisense would be the single
       | largest usability enhancement they could make for me right now..
        
         | uup wrote:
         | The Id<T> type defined in the first comment seems like a pretty
         | good, albeit ideally unnecessary, workaround.
        
           | Rapzid wrote:
           | Those hacks work but in practice I wouldn't classify them as
           | "good". You end up having to look at a ton of types including
           | in library code like React and etc that can be quite complex.
           | Having to stop and try to wrap those on the fly is terrible
           | ergonomics.
        
         | lf-non wrote:
         | Yeah, this is a recurring pain.
         | 
         | I know the universe at large has moved away from eclipse, but I
         | loved their rich tooltips where you had nice structured
         | representation (not just a blob of text from lsp) and could
         | click through and navigate the type hierarchy.
        
           | 9dev wrote:
           | Try any IntelliJ IDE, they've got that. I can't understand
           | why anyone would want to use VS Code with a Typescript
           | project voluntarily...
        
       | Myrmornis wrote:
       | This looks fantastic, not just for people learning Typescript,
       | but I'd think it would be useful (when completed) as an
       | introduction to generics and type-level thinking etc for lots of
       | newcomers to those areas.
        
       | theteapot wrote:
       | Didn't know `Expect` existed. Can't find it docs?
        
         | gvergnaud wrote:
         | It's actually _not_ in the standard library, but you can write
         | it yourself:
         | 
         | type Expect<T extends true> = T;
         | 
         | `T extends true` puts a type constraint on the parameter, which
         | then needs to be assignable to the literal type `true` to type-
         | check.
        
           | theteapot wrote:
           | OK cool, now what about `Equal` :).
        
             | triyambakam wrote:
             | type Equal<A, B> = A extends B ? (B extends A ? true :
             | false) : false;
        
       | guggleet wrote:
       | Seems like a good start, but there are a lot of interesting
       | offerings in the introduction that really don't exist in the
       | content so far.
       | 
       | Maybe finishing one of the more advanced chapters would be enough
       | to lure people who are more experienced to check back on progress
       | / pay / whatever you want traffic for.
        
       | AkshatJ27 wrote:
       | This reminded me of the Typescript type-level Quine.
       | https://youtu.be/UzE6d1ueT_E
        
       | theteapot wrote:
       | Course is probably great, but I find it really weird and
       | unnecessary to describe Typescript type system as Turing
       | complete. Who cares?
        
         | lolinder wrote:
         | People who are trying to statically describe the behavior of
         | highly dynamic JavaScript code.
        
           | theteapot wrote:
           | Yeah but how is Turing completeness directly relevant to
           | that? Article doesn't seem to explain, just says "Turing
           | Complete" in the title. Again, so what? I suppose it's
           | somewhat indirectly vaguely reassuring.
           | 
           | P.S. You might like this http://beza1e1.tuxen.de/articles/acc
           | identally_turing_complet...
        
       | simlevesque wrote:
       | Wow I think I know a lot of Typescript but I'll have to go
       | through it because I'm always asked for ressources to get started
       | and this one seem great.
       | 
       | I also recommend type-challenges: https://github.com/type-
       | challenges/type-challenges
       | 
       | It works great with the VSCode extension.
        
       | kbr- wrote:
       | Is there any place I could report issues or ask questions about
       | the course other than Twitter?
       | 
       | If the author is reading this, the proposed solution to the
       | `merge` challenge is:                 function merge<A, B>(a: A,
       | b: B): A & B {         return { ...a, ...b };       }
       | 
       | That's the "obvious" solution, but it means that the following
       | type-checks:                 const a: number = 1;       const b:
       | number = 2;       const c: number = merge(a, b);
       | 
       | That's not good. It shouldn't type check because the following:
       | const d: number = { ...a, ...b };
       | 
       | does not type check.
       | 
       | And I don't know how to express the correct solution (i.e. where
       | we actually assert that A and B are object types).
       | 
       | Also, looking forward to further chapters.
        
         | KrishnaShripad wrote:
         | > And I don't know how to express the correct solution (i.e.
         | where we actually assert that A and B are object types).
         | 
         | You can do this:                 function merge<         A
         | extends Record<string, unknown>,         B extends
         | Record<string, unknown>       >(a: A, b: B): A & B {
         | return { ...a, ...b }       }            const result = merge({
         | a: 1 }, { b: 2 })
        
           | ttymck wrote:
           | Why Record and not object?
        
             | lediur wrote:
             | Linters for TypeScript recommend using `Record<string,
             | any>` instead of `object`, since using the `object` type is
             | misleading and can make it harder to use as intended.
             | 
             | See:
             | 
             | - https://typescript-eslint.io/rules/ban-types/
             | 
             | - https://github.com/typescript-eslint/typescript-
             | eslint/issue...
             | 
             | - https://github.com/microsoft/TypeScript/issues/21732
             | 
             | - https://github.com/microsoft/TypeScript/pull/50666
        
             | davidatbu wrote:
             | Avoid the Object and {} types, as they mean 'any non-
             | nullish value'.         This is a point of confusion for
             | many developers, who think it means 'any object type'.
             | 
             | https://github.com/typescript-eslint/typescript-
             | eslint/blob/...
        
             | KrishnaShripad wrote:
             | Because you only want to merge two objects that have keys
             | with string type. "object" is represented as Record<any,
             | any>. That would mean, you can use any type as key. Here is
             | an example:                 function merge<         A
             | extends object,         B extends object       >(a: A, b:
             | B): A & B {         return { ...a, ...b }       }
             | const result = merge(() => {}, () => {}) // should fail!
             | const anotherResult = merge([1, 2], [3, 4]) // should fail!
             | 
             | Which is obviously not what you want.
             | 
             | This table here gives you a good overview of differences
             | between object and Record<string, unknown>: https://www.red
             | dit.com/r/typescript/comments/tq3m4f/the_diff...
        
         | brundolf wrote:
         | Yeah, TypeScript gets funky around the boundary of "things that
         | can only be objects", because JavaScript itself gets funky
         | around "what is an object"
         | 
         |  _Technically_ TypeScript  "object types" only describe
         | _properties_ of some value. And in JavaScript... arrays have
         | properties, and primitives have properties. Arrays even have a
         | prototype object and can be indexed with string keys. So... {}
         | doesn 't actually mean "any object", it means "any value"
         | 
         | At its boundaries, TypeScript has blind-spots that can't
         | realistically be made totally sound. So the best way to think
         | of it is as a 90% solution to type-safety (which is still very
         | helpful!)
        
       | agentultra wrote:
       | Nice course, and nice site.
       | 
       | Although, as a Haskell developer, I am curious what type system
       | TS is using (System F? Intuitionist? etc) and what limitations
       | one can expect. Aside from the syntax of TS being what it is,
       | what are the trade-offs and limitations?
       | 
       | I was under the impression, and this was years ago -- things are
       | probably different now?, that TS's type system wasn't sound (in
       | the mathematical logic sense).
        
         | 323 wrote:
         | Non-soundness is sort of a feature, it lets you force your way
         | through and just say "trust me, this is a Thing" when it's just
         | hard (or impossible) to make TypeScript see that. In practice,
         | you can write large code bases where you only need to do this
         | every 1000 lines or so. Not ideal, but better than no typing.
        
           | agentultra wrote:
           | Is it fair to say that the limitation is that the type
           | checker can admit programs that are not type correct?
        
             | 323 wrote:
             | Yes. For example it has the "any" type which will bypass
             | any sort of type check.
             | 
             | But I think it's more nuanced. Depends of what you mean by
             | type correct. Even in Haskell you can override the compiler
             | and say "trust me on this".
        
               | jakear wrote:
               | Any isn't required. The go-to example of unsoundness is
               | the Cat[] ref that you alias as an Animal[], append a Dog
               | to, then map over the original ref calling 'meow()' on
               | each entry.
        
             | spion wrote:
             | You can make "believe_me" assertions, which is incredibly
             | useful when writing advanced (metaprogramming heavy)
             | library code. The idea is to try and contain / and heavily
             | test the small "unsafe" library part and isolate it from
             | the rest of the code, then enjoy the advanced type
             | transformations and checks in the "normal" application
             | code.
             | 
             | For example, an SQL query builder library may internally do
             | unchecked assertions about the type of the result row that
             | a query transformation would produce (e.g. group_by),
             | however assuming that part is correct, all application code
             | using the query builder's group_by method would benefit
             | from the correct row types being produced by `group_by`
             | which can then be matched against the rest of the
             | application code.
        
             | diroussel wrote:
             | Yea, because typescript is trying to model what can be done
             | in JavaScript, which is a very permisssive runtime.
        
             | Tade0 wrote:
             | That's by design, considering that its original purpose was
             | to introduce static typing in JS codebases.
        
         | AaronFriel wrote:
         | I don't believe it is using any type system described outside
         | of the TypeScript compiler. The goal of the system is to
         | accurately describe real-world JavaScript programs and
         | semantics, not to introduce a formalization that existed
         | elsewhere and impose it on JS.
         | 
         | As a consequence, it has aspects of structural types, dependent
         | types, type narrowing, and myriad other features that exist
         | solely to model real-world JavaScript.
         | 
         | As far as soundness: it's not a goal of the type system.
         | https://www.typescriptlang.org/docs/handbook/type-compatibil...
        
       | Ayc0 wrote:
       | I love the content!!
        
       | d4mi3n wrote:
       | I'm always impressed at how much the type system in TS is capable
       | of. The provided examples remind me of what I'd expect in
       | something like Rust; it brings me joy that we can do this sort of
       | stuff in our frontend code and tooling these days.
       | 
       | We have come far.
        
         | danellis wrote:
         | I'm currently working on a project that uses both Typescript
         | and Scala. The overlap in concepts is rather useful when
         | switching contexts.
        
       | kaladin_1 wrote:
       | Just came here to say that this is really nice. Fantastic way to
       | play with Typescript Types even for people with decent knowledge
       | of Typescript as I would consider myself.
       | 
       | Particularly enjoy the confetti :)
        
       | nonethewiser wrote:
       | This is a really nice website.
        
       | willthefirst wrote:
       | Great content. Give it me to me as a daily-dose newsletter :)
        
       | HellsMaddy wrote:
       | This is great. Can you please create an email list where we can
       | sign up to be notified when new chapters are available? If I
       | follow you on Twitter, I will invariably miss any announcements.
        
       | amadeuspagel wrote:
       | Looks cool. I like how it gives immidiate feedback, but doesn't
       | feel constraining or arbitrary. Is there are more basic tutorial
       | in a similar style?
        
       | cercatrova wrote:
       | Speaking of types, what are your thoughts on fp-ts if you've used
       | it? It brings functional programming concepts like in Haskell
       | such as monads into TypeScript.
        
         | SpikeMeister wrote:
         | If you stick to a few useful types like `Option` and
         | `Either`/`TaskEither` you can get a lot of value out of it when
         | writing server side code, particularly when combined with `io-
         | ts` for safely parsing data.
         | 
         | If you go all in and use every utility it provides to write
         | super succint FP code, it can get pretty unreadable.
        
         | NTARelix wrote:
         | I haven't used fp-ts directly, but I use an adjacent package
         | that declares fp-ts as a peer dependency: io-ts. I've almost
         | exclusively for easier type management during deserialization.
         | In vanilla TypeScript I would have defined an interface and a
         | user-defined type guard to handle deserialization:
         | 
         | interface ClientMessage { content: string }
         | 
         | function isClientMessage(thing: unknown): thing is
         | ClientMessage { return thing !== null && typeof thing ===
         | 'object' && typeof thing.content === 'string' }
         | 
         | expect(isClientMessage('nope')).toBeFalse()
         | 
         | expect(isClientMessage({ content: 'yup' })).toBeTrue()
         | 
         | but user-defined type guards basically duplicate the interface,
         | are prone to error, and can be very verbose. io-ts solves this
         | by creating a run-time schema from which build-time types can
         | be inferred, giving you both an interface and an automatically
         | generated type guard:
         | 
         | import { string, type } from 'io-ts'
         | 
         | const ClientMessage = type({ content: string })
         | 
         | expect(ClientMessage.is('nope')).toBeFalse()
         | 
         | expect(ClientMessage.is({ content: 'yup' })).toBeTrue()
         | 
         | Very nifty for my client/server monorepo using Yarn workspaces
         | where the client and server message types are basically just a
         | union of interfaces (of various complexity) defined in io-ts.
         | Then I can just:
         | 
         | ws.on('message', msg => {                 if
         | (ClientMessage.is(msg)) {              // fullfill client's
         | request            } else {              // handle invalid
         | request            }
         | 
         | })
         | 
         | Only thing missing is additional validation, which I think can
         | be achieved with more complicated codec definitions in io-ts.
        
         | seer wrote:
         | haven't used it myself but other teams at the company I work
         | for have tried with mixed results.
         | 
         | It's very opinionated about the way you structure your code and
         | basically makes anything thats not fully fp-ts hard to
         | integrate, and also is quite hard for general JS people to wrap
         | their head around.
         | 
         | It's been designed by FP people for FP people and if there are
         | some on your team who are not fully on board or are just
         | starting to learn FP - expect lots of friction.
         | 
         | At my company it was mostly scala coders and "cats" lovers
         | (category theory stuff lib for scala) mixed in with regular
         | nodejs devs and I could sense a lot of animosity around fp-ts
         | and its use.
         | 
         | But on a more practical note, the more they converted their
         | codebase to fp-ts the more they reported massive compile time
         | slowness. Like it would start to take minutes to compile their
         | relatively isolated and straight forward services.
         | 
         | From what I gathered, if you want to go fp-ts its just too much
         | friction and you're much better off picking up a language
         | designed from the bottom up for that - scala / ocaml / elixr /
         | etc.
         | 
         | To be honest once I've been comfortable enough with the more
         | advanced TS features, you can write plain old javascript in a
         | very functional style, and thats actually pretty great,
         | especially if you throw date-fns, lodash/fp or ramda into the
         | mix, and it remains largely approachable to people outside of
         | FP and you can easily integrate external libs.
        
           | cercatrova wrote:
           | That sounds about what I've expected. Frankly in a TS
           | codebase with many other devs that are not versed in FP, I
           | wouldn't want to bring in a pure FP library because it, like
           | you said, needs everyone to understand the "meta-language" of
           | FP so to speak, such as how monads work, not having raw side
           | effects, mutation etc.
           | 
           | Ramda et al seem like a good compromise. Looking through its
           | docs though, doesn't JS have a lot of this stuff covered? ie
           | filter, map, reduce etc. What new stuff is it bringing in
           | that covers say the 90% of most use cases?
        
           | rockyj wrote:
           | Totally agree. I wrote my thoughts and experiences on FP-TS
           | and maybe those csn help -https://rockyj.in/2022/03/24/fun-
           | with-composition-2
           | 
           | IMHO, functional TS is great with ramda, currying etc. and
           | solves a lot of problems nicely. See also https://mostly-
           | adequate.gitbook.io/mostly-adequate-guide/ch0...
        
         | gherkinnn wrote:
         | fp-ts [0] and the accompanying io-ts [1] are very well designed
         | and neatly implemented. I'd consider them the reference for all
         | things FP in Typescript.
         | 
         | In practice though I find that they don't mesh well with the
         | language and ecosystem at large. Using them in a
         | React/Vue/Whatever app will catch you at every step, as neither
         | the language nor the frameworks have these principles at their
         | core. It takes a lot of effort to escape from their
         | gravitational pull. Using Zod [2] for your parsing needs and
         | strict TS settings for the rest feel more natural.
         | 
         | It could work in a framework-agnostic backend or logic-heavy
         | codebase where the majority of the devs are in to FP and really
         | want / have to use Typescript.
         | 
         | 0 - https://gcanti.github.io/fp-ts/
         | 
         | 1 - https://gcanti.github.io/io-ts/
         | 
         | 2 - https://zod.dev
        
       | gitowiec wrote:
       | Hi n I have a question. I will go as simple and short as
       | possible. I joined a small team working on the internal invoicing
       | tool. Backend is Spring. Front-end is ExtJS used for me in very
       | peculiar way. It emulates Java classes, there are Ext.define
       | declarations with FQN names eg:
       | "com.projectName.ds.Board.ui.extjs" (as string, casing important)
       | Then in the code this class is instantiated by its FQN but used
       | as identifier eg: var Board = new
       | com.projectName.ds.Board.ui.extjs(); There are also a lot of FQNs
       | with short namespaces, different are associated with business
       | short names and other like Dc, Ds, Frame belong to code
       | architecture domain (data controller, data store, a frame on the
       | screen). How I could use typescript to improve developer
       | experience here? I'm from the react world, I programmed 4 years
       | only in typescript, react, node and mongo. Thanks!
        
       | classified wrote:
       | Is TypeScript's type system Turing-complete?
        
         | 9dev wrote:
         | Why yes it is:
         | https://github.com/microsoft/TypeScript/issues/14833
        
       | cogman10 wrote:
       | A great idea. Now, everyone that learns this stuff, show some
       | restraint!
       | 
       | The drawback of a powerful type system is you can very easily get
       | yourself into a type complexity mudhole. Nothing worse than
       | trying to call a method where a simple `Foo` object would do but
       | instead you've defined 60 character definition of `Foo`
       | capabilities in the type system in the method signature.
       | 
       | Less is more.
        
         | tobyhinloopen wrote:
         | True that.
         | 
         | Once types get so complex, I've no idea what's going wrong.
         | 
         | Today I had code running fine but throwing errors all over the
         | place because some deeply nested type mismatch between two
         | libraries.
         | 
         | I just any'd it... i aint got no time for that shit
        
         | marcosdumay wrote:
         | The types in your code are just as designed just like any other
         | aspect of it. It's not a matter of restraint, it's a matter of
         | doing things on the correct way.
        
           | dllthomas wrote:
           | So less can be more but more can also be more, more or less?
        
         | primitivesuave wrote:
         | Second this. By the end of a progressive multi-year TS
         | migration at my last company, we were refactoring
         | `HTTPRequest<GetRequestBody<IncrementUpdate>>` back into its JS
         | ancestor `HTTPGetRequest`.
        
         | johnfn wrote:
         | This is so true. I've been thinking recently that in the same
         | way that "use boring technology" is a pretty well-known
         | concept, so should "use boring types" enter the collective
         | conscious. Type operators are exciting and flashy, but I found
         | that using them too much leads to brittle and confusing types.
         | Saving them for a last resort tends to be the right strategy.
         | Often there's an extremely dumb way to write your types that
         | works just as well - maybe even better :)
        
       | arberx wrote:
       | There are only 3 chapters so far...
        
       | tunesmith wrote:
       | Might as well ask here. On our teams, we have the occasional
       | developer that is insistent on using Typescript in an OO fashion.
       | This has always struck me as square peg round hole. Even though I
       | come from an OO background, Typescript strict settings really
       | seem to push me in a direction of using interfaces and types for
       | type signatures, and almost never classes, subclasses,
       | instantiated objects. I don't have a very good answer for "yeah,
       | but what about dependency injection"? though. Any thoughts from
       | anyone?
        
         | WHATDOESIT wrote:
         | An ES module is encapsulated enough. You can dependency inject
         | with them as you wish. It's like having a class, no need for a
         | class inside a class.
         | 
         | The biggest argument is that my functional-ish code is always
         | 3x shorter with the same features, though.
        
           | bilalq wrote:
           | This. Creating classes to wrap dependencies is a pattern only
           | needed because of language limitations. With JS/TS, you can
           | mock at the import statement level, so no need to twist your
           | code to abstract away importing.
           | 
           | Also, even if you didn't want to mock that way, you can get
           | dependency injection with functions just by taking a
           | parameter for a dependency. If dependency injection is the
           | only reason you have to use a class, you probably shouldn't
           | use a class.
        
             | spion wrote:
             | Request-scoped DI (as seen in ASP.NET MVC) is great on the
             | backend for servicing requests. You can ask for e.g. a
             | class representing the current user information to be
             | injected anywhere, or to keep track of request-associated
             | state like opentelemetry spans, or a transaction, etc. The
             | alternative is to pass the user information class or
             | transaction to all other services, which can be annoying
             | 
             | Its rarely seen in the ecosystem as a solution,
             | unfortunately (everyone is passing all arguments all the
             | time), but its one of the rare places where this is still
             | useful. I've had bad experience with the alternative
             | (continuation local storage) and its not nearly as elegant.
        
           | depaulagu wrote:
           | How do you dependency inject a ES module?
        
         | diroussel wrote:
         | I get this question sometimes from a developer new to my team
         | asking if it's ok to add OOP code since most of the existing
         | code is just functions.
         | 
         | My view on that is that it's ok to use OOP and define classes
         | if you are really defining an OOP style object. Back in the 90s
         | is was taught that an object has identify, state and behaviour.
         | So you you don't have all three, it's not really an object in
         | the OOP style.
         | 
         | Looking at it through this lens helps make it clearer when you
         | should add classes or just stick to function and closures.
        
         | spion wrote:
         | I'll give a practical, non-philosophical answer.
         | 
         | Indeed, if you want to use emitDecoratorMetadata for automatic
         | dependency injection, you should use classes. If the library
         | itself takes advantage (again likely due to decorators) of
         | classes e.g. https://typegraphql.com/docs/getting-started.html
         | then yes, classes are again a fine choice.
         | 
         | The general answer is that they're useful when the type also
         | needs to have a run-time representation (and metadata).
         | Otherwise, not really.
        
       | YoannMoinet wrote:
       | I particularly love the interactivity of the training. So
       | polished.
       | 
       | Can't get enough of the fireworks!
        
       | 323 wrote:
       | 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/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 wrote:
         | You can use type guards for something similar:
         | https://www.typescriptlang.org/docs/handbook/advanced-types....
        
           | 323 wrote:
           | Keyword similar. I use type guards for other things (like
           | typing JSON responses), but they can't solve this particular
           | problem.
        
           | brundolf wrote:
           | What they were getting at is that you can't observe T itself,
           | only values passed in as type T
        
         | [deleted]
        
         | iainmerrick wrote:
         | I 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-Ov...
        
           | brundolf wrote:
           | Wanted 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-
           | func...
           | 
           | I actually think this is a super cool and elegant way to do
           | overloading
        
         | melony wrote:
         | Does TypeScript support dynamic dispatch? JS by nature is
         | dynamically typed you should be able to introspect at get the
         | type at runtime.
        
         | davidatbu wrote:
         | You 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/
        
           | 323 wrote:
           | Thanks, 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.
        
         | likeclockwork wrote:
         | That 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.
        
       ___________________________________________________________________
       (page generated 2022-09-20 23:00 UTC)