logoalt Hacker News

reissbakeryesterday at 2:16 AM1 replyview on HN

Not sure I follow the first part of what you're saying.

For the part where you're describing what's possible or not in TypeScript/JS, though, you're incorrect:

You can't do something like title("hi") vs title({attr:123}, "hi")

Yes, you can. In JS it's trivial; in TypeScript, you can even do it while preserving type safety. Here's the function in TypeScript:

    // First define which signatures are allowed
    function title(content: string): string;
    function title(attrs: Record<string, any>, content: string): string;

    // Then, implement the function, handling the two possible cases:
    function(contentOrAttrs: string | Record<string, any>, maybeContent?: string) {
      const content = typeof contentOrAttrs === "string" ? contentOrAttrs : maybeContent!;
      const attrs = typeof contentOrAttrs === "string" ? {} : contentOrAttrs;

      // now use content and attrs as you please
    }
This will be typechecked by the compiler so that if you call title("hi"), it'll know there are no more arguments, and if you call title({ attr: 123 }, "hi"), it'll validate that the first argument is a Record<string, any> and the second argument is a string.

Replies

its-summertimeyesterday at 9:54 AM

that part was clarified later, "so you need to have fixed function signatures unless you want to have a lot of bother in implementing things"

I should not have used "can't" at that point, correct

To be more clear, you "can't" have a difference between an arbitrary object and a record, unless you know the type of the object and a way to disambiguate that from a record.

Of course, you "can" have a difference, a record "is" `typeof record === 'object' && Object.getPrototypeOf(record) === Object.getPrototypeOf({})` (At least as long as no one uses plain objects as non-recordy things), but, this isn't something I've ever had to care about in any other language. In some you have multiple dispatch built into the language, in some you can just pass named arguments arbitrarily. Javascript and Typescript are very inflexible in this aspect.