[HN Gopher] TypeScripting the Technical Interview ___________________________________________________________________ TypeScripting the Technical Interview Author : ycitm Score : 431 points Date : 2023-03-12 13:58 UTC (9 hours ago) (HTM) web link (www.richard-towers.com) (TXT) w3m dump (www.richard-towers.com) | magnio wrote: | This is a delightful read, which reminds me of two other | articles. The first is also a caricature of the technical | interview, solving FizzBuz with Tensorflow: | https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/ | | The second is a explanatory story, or "discovery fiction" as the | article classifies itself: https://paulbutler.org/2022/what-does- | it-mean-to-listen-on-a... | | I love these humorous yet pedagogic technical writings, woven | with a bit of literary eloquence and down-to-earth narrative. | Thank you for this. | Espressosaurus wrote: | Fizz-buzz in Tensorflow is a delight. | | The ending is perfect. | higeorge13 wrote: | The fizzbuzz tensorflow must be one of the funnier posts ever. | stevekemp wrote: | I think you would enjoy this too | | https://aphyr.com/posts/353-rewriting-the-technical-intervie... | codetrotter wrote: | And of course, the original. | | https://aphyr.com/posts/342-typing-the-technical-interview | | (Also linked I the first paragraph of the link you posted, as | well as in the intro of the OP.) | ex3xu wrote: | Long ago, on Svalbard, when you were a young witch of forty- | three, your mother took your unscarred wrists in her hands, and | spoke: Vidrun, born of the sea-wind through the | spruce Vidrun, green-tinged offshoot of my bough, joy and | burden of my life Vidrun, fierce and clever, may our | clan's wisdom be yours: Never read Hacker News | | But Hacker News has read of you, in their snicker-slithing | susurrential warrens, and word has spread... | | https://aphyr.com/posts/341-hexing-the-technical-interview | forgotusername6 wrote: | The word "susurrential" returns only two Google results. One is | for this post. Does anyone know what this word is supposed to | mean? | [deleted] | antonyt wrote: | Most likely a corruption of susurrant. From susurrus, meaning | a murmuring or whispering sound. | stevula wrote: | susurrus or susurration is a very literary word for a | whisper/whispering. The usual adjective would be susurrous or | susurrant, rather than susurrential, but in any case it would | mean "full of whispering sounds". | ex3xu wrote: | I think it's a portmanteau of susurrus and torrential, | which serves to invoke the force and volume of a torrential | downpour to the description. | [deleted] | implicit wrote: | Richard has a whole series of these. | | I was going to try to pick out one of my favourites from this | series, but I really can't. Every last one is a treasure. | | EDIT: Oops! This is based on Aphyr's work. My bad! | orf wrote: | Can you link them? I couldn't find them on his blog. | MatthiasPortzel wrote: | The series is actually by Aphyr, and the first one is here. | https://aphyr.com/posts/340-reversing-the-technical- | intervie... | | This post translates one of them from Haskell to typescript | (very well IMO). | ycitm wrote: | The series is actually by Aphyr: | https://aphyr.com/tags/interviews | | This post is a pastiche of | https://aphyr.com/posts/342-typing-the-technical-interview | orf wrote: | Thanks! I was aware of the Aphyr series, but he said | Richard also had a series. | borissk wrote: | TypeScript has the most complicated type system ever. Don't know | why Anders&Co needed to go that far. | teaearlgraycold wrote: | Typescript is God's language. Don't @ me. | rorymalcolm wrote: | Having the type system this complicated is mostly for library | builders, makes the developer experience of tools like tRPC, | Zod and Prisma possible. An engineer writing business logic in | TypeScript will probably never have to learn how to write (or | even read tbh) complex TypeScript signatures, but benefit | significantly from the solutions the type system complexity is | a necessary precursor for. | eyelidlessness wrote: | As much as people complain about the TS type system's | complexity, it is just modeling real world JS. The vast | majority of its complexity is hardly used in TS that doesn't | interop with existing JS, because you generally won't write | such highly dynamic code when you have to define its types. But | it does allow for safer interop. | | Even so, JS itself being so dynamic, TS still can't claim full | type safety. | | And as much as people complain about the type system's | verbosity, many newer features are designed specifically to | allow you to be much more terse while improving expressivity | and safety. A great example: the satisfies operator lets you | narrow a value's type to conform to whatever it satisfies, and | simultaneously widen it to whatever it adds (including anything | optional in the narrower type). This is _great_ for | composition, only takes two words to accomplish. And its | meaning should be immediately obvious at a glance once you know | about the operator. | heisenbit wrote: | > TS that doesn't interop with existing JS | | which tends to happen at the edge of the application where it | interacts with the outside world and all the interesting | things happen. | evilduck wrote: | This is a joke post. Day to day life using TS doesn't resemble | this at all. | cwalv wrote: | It aims to be able to express the typing used in a bunch of | pre-existing javascript libraries. Many/most of these were | written in a "how would I solve this if the type system just | let me do whatever I wanted" style (since that's what runtime | dynamic typing actually does). | golergka wrote: | Another reminder that Typescript type system is Turning complete. | teaearlgraycold wrote: | Not yet complete, but will soon turn complete! | [deleted] | jonorsi wrote: | So beautiful and horrific at the same time :D. | cjbprime wrote: | In case folks miss the link at the top of the article, this is | translated from an old 2017 post by Aphyr. | | That post was in Haskell, where it's not too surprising that you | can do serious computation inside the type system. | | This new post translates the ideas to TypeScript, which is more | widely known, and which I once heard described as having | "accidentally Turing-complete" types: | | https://github.com/microsoft/TypeScript/issues/14833 | hnfong wrote: | I'd say it's "inspired" rather than "translated". | | The part about using the typescript language server to compute | the solution, and the protagonist claiming the code is | "concise" because only 4 lines of javascript were generated, | was absolutely brilliant. Cracked me up at least. | | Glancing at the actual code, I admit I'm with Criss in my | ability to follow the logic, but it doesn't look like a direct | translation from Haskel types to Typescript types either. | | At any rate, very well done. | blauditore wrote: | The final punch line is that types vanish and the compiled | code is effectively useless. | girvo wrote: | I know my mind is decidedly poisoned when I could follow the | type definitions perfectly, and they reminded me of certain | types I have written myself... ah, TypeScript, what have you | done to me... | the_gipsy wrote: | I am not well versed in Haskell, but wasn't the original also | computing the solution with just the type system? | tome wrote: | Yup | MatthiasPortzel wrote: | Aphyr has a series of posts in this style, all of which are | excellent. | faitswulff wrote: | This post also mentions "Vidrun," which features heavily in | Aphyr's posts. And the interviewer in this post recognizing | the situation they were in had me literally laughing out | loud! | dabreegster wrote: | I love this series. It also reminds me a bit of | https://unsongbook.com -- another beautiful work of creative | writing combining technology and magic. | eyelidlessness wrote: | Here[0] is the open issue about TypeScript being Turing | complete. The current most recent comment[1] is showing the | type system parsing its own type syntax. Of course there have | been many parsers written in the type system since template | literal types landed, but I found this one particularly | amusing. | | 0: https://github.com/microsoft/TypeScript/issues/14833 | | 1: | https://github.com/microsoft/TypeScript/issues/14833#issueco... | dec0dedab0de wrote: | So he wrote all that for the typescript lsp to respond with the | answer, but when it compiles down it's nothing? And we're using | runes as variables just because? | | That is pretty neat, and silly. | | I also think it highlights my natural aversion to static type | checking in dynamic languages. I know that I could get sucked | into writing a bunch of code for the checker, instead of using my | energy for making the application work. | ycitm wrote: | The runes are mostly "just because", but there is a reason. | | Ideally, I would have written: type Nil = | unique symbol | | Which would ensure the Nil type wouldn't match with anything | but itself. Unfortunately, the compiler doesn't allow unique | symbol other than on const variables initialised with Symbol(). | So I needed some meaningless symbols. | | I could also have done type Nil = "nil" | | But then it would have looked like the string meant something. | 8n4vidtmkvmk wrote: | this is why i love ts when not working for a megacorp. when the | ts gets too cray i just nope out. throw an any or as in there | and get on with my day. wouldn't pass a code review but i don't | care | trhr wrote: | [flagged] | 8n4vidtmkvmk wrote: | none? is this a jab? | rexpop wrote: | This is a jab (insult), and I've flagged it, but I am also | curious. If you could, please describe the qualities of a | "bootcamp" grad by which you recognize them? | | Edit: especially pertaining to type inference, I guess? | trhr wrote: | If you wanted to have a conversation, you wouldn't have | flagged it. So, no. | nicolas-siplis wrote: | I remember reading the original version and thinking "Ah, this | would be so much more grokkable if only I knew Haskell"... | Delusions of grandeur are a marvelous thing! | [deleted] | davidmurdoch wrote: | This is what I mean when I search for "How to ______ in | TypeScript": types! Too many blogs and Stack Overflow questions | say "TypeScript" when they mean JavaScript, making it harder to | find information on actual type problems. | joenot443 wrote: | Well written and super funny. Reminded me a bit of Scott's | writing, particularly the descriptions of the horrified | interviewer. | | I've never worked in a Typescript shop, is there any truth to the | satire here? The sea of confusing types to solve any problem? | nayroclade wrote: | I'd say generally the opposite is true. Most commercial | software I've worked on typically contained only simple typing | --discriminated unions are about as complex as it gets--and | it's more of a problem that people get lazy and start using | "any" too much than they go overboard. | | Where complex types can be a problem is when working with open | source libraries, especially when the types are community- | developed, separate to the library itself. The library API may | not be particularly amenable to easy typing, and the community | types can end up being rather confusing, especially to people | who developed neither the types nor the original library. | TheCleric wrote: | I tell my fellow developers at work: "Any is banned. If you | want any, use JavaScript, and we don't use JavaScript here. | Perhaps you haven't heard about unknown?" | | In my experience, 90% of the time when a developer uses any, | they just don't know about unknown. 9% it's because they are | lazy. 1% is because you are implementing something from an | imported library, and they fell into the other 99%. | oblak wrote: | Use "unknown" and TS complains that you're treating | something as an object. | | Use Object.defineProperties and TS complains because that | stuff is invisible to it after how many years? | | I think you're right, of course, but TS is hardly perfect | and treating its ways as gospel is not an improvement over | JS. The "right ways" change over time and beliefs are not | shared among everyone. | eyelidlessness wrote: | I make an exception for using any in type params which | extend type params, eg const foo = <T | extends Record<string, any>>(dict: T) => ... | | This is a good signal that foo maps over dict in some | generic way that cares more about its dictionary-ness than | its values. Sure, unknown works in that position too, but | at least IMO the "doesn't care" bit is more informative | than "doesn't know". The latter might imply more type | narrowing will happen than is the case. | alexgrover wrote: | The problem with that is that when consuming of the | dictionary, "doesn't know" is actually more appropriate. | If you then access Object.values(foo) in your method you | are given an iterable of anys which is unsafe. | eyelidlessness wrote: | If the function is _doing something_ with the values | which is unsafe, sure. My point was the more relaxed | constrain on the type signature can be used to imply it's | only concerned with the dictionary's keys. | hnfong wrote: | > is there any truth to the satire here? | | As long as you're satisfied with the answer being shown on a | tooltip when you hover over a variable... sure. | | Notice how the whole type structure ending up as 4 lines of | inconsequential javascript after going through the typescript | compiler at the very end. | AgentOrange1234 wrote: | It's a very beautiful language even despite being compatible | with Javascript. The code here is delightfully absurd, please | don't think it is representative. | davedx wrote: | I've worked for TypeScript companies for a while now. Most devs | I've met are fairly pragmatic and wouldn't try something like | this for production code, but I've definitely met a couple who | have an exceedingly deep grasp of the type system and would | appreciate the whimsy of it. | tengbretson wrote: | In my experience, even the more wild/exotic patterns in | typescript tend to flatten into something rather readable at | their usage site. 95% of the time when I use a library that | does anything close to what is done in this article I write my | code, hover over it, intellisense tells me its type and I say | "wow, how was it able to do that? Cool!" And I carry on. | sebazzz wrote: | > The sea of confusing types to solve any problem? | | Mostly in typings either provided by the library itself or via | the 3rd party DefinitelyTyped project. Some typings have been | made so complex, that it is hard to follow what kind of | concrete type is exactly expected or allowed. | | [1]: https://github.com/DefinitelyTyped/DefinitelyTyped | gardenhedge wrote: | A good example of how TypeScript can be done so incredibly wrong. | irrational wrote: | Is this really what technical interviews are like in Silicon | Valley? I've never seen anything like it in the "real" world. | tantalor wrote: | Um, which part? | irrational wrote: | Asking about setting a Queen on a chess board. Unless I'm | being hired at a company that programs chess sets, it is a | nonsense question. If you want to test someone's problem | solving skills, test them with a problem that actually | reflects the real work they will be doing at your company. | tantalor wrote: | > N-Queens is a classic backtracking problem that gets | asked a lot during interviews. | | https://fizzbuzzed.com/top-interview-questions-3/ | siriusfeynman wrote: | Which is exactly the point, it's a leetcode question that | tests whether you've memorised a bunch of leetcode | interview questions | wiseowise wrote: | > classic backtracking problem | | Literally in the parent post. | 8n4vidtmkvmk wrote: | more or less. i wasn't asked n queens specifically, but i was | asked to move a knight from one square to another. but no, | you're not supposed to solve it using the type system itself | lozenge wrote: | Only if you want to get hired. | irrational wrote: | I've been hiring developers for decades at a Fortune 100 | company and have never engaged in such nonsense. Unless you | are hiring people to program chess sets, the question in the | article is foolish. If you want to test their problem solving | or coding skills, give them a problem from the actual work | they will be doing at your company. | LambdaComplex wrote: | I wish more companies thought that way. It seems like most | of them are just cargo culting Google's hiring methods with | the expectation that it will turn them into the next | Google. | wiseowise wrote: | > Unless you are hiring people to program chess sets, the | question in the article is foolish. | | Ever heard about word "abstraction"? | expertentipp wrote: | I never engage in such teasing and not getting hired, so | you're likely correct. | iampims wrote: | Make sure you read till the end. Brilliant. | Buttons840 wrote: | Why did they only solve for 7 Queens and not 8 Queens? | | I'm reminded of https://github.com/type-challenges/type- | challenges -- I've only looked at some of the more challenging | problems, but one involves writing a JSON parser in the type | system. The easy problems look reasonably useful to solve. | ycitm wrote: | I wondered if anyone would spot this :) | | There's a recursion depth limit of 500 on the TypeScript | compiler, which prevents this solution working for N > 7 | | Even Aphyr's original Haskell solution only demonstrates N = 6, | so in some sense this is an improvement on the state of the art | for type-level N Queens solutions /s | davidmurdoch wrote: | I don't _really_ know what it means, but I 've seen it used | to work around depth issues in Typescript, but can this use a | "trampoline"? | ycitm wrote: | I don't think there's any way to do iteration in the type | system (other than recursion), so there's no way around it. | | I considered forking the compiler to set a deeper limit, | but at some point Typescript itself is going to stack | overflow. Also that probably goes a bit beyond what Criss | is expecting in an interview... | jitl wrote: | If you want to see some more legs on TypeScript type-level logic, | check out this SQL database as Typescript types: | https://github.com/codemix/ts-sql: import { | Query } from "@codemix/ts-sql"; const db = { | things: [ { id: 1, name: "a", active: true }, | { id: 2, name: "b", active: false }, { id: 3, name: | "c", active: true }, ], } as const; | type ActiveThings = Query< "SELECT id, name AS nom FROM | things WHERE active = true", typeof db >; | // ActiveThings is now equal to the following type: type | Expected = [{ id: 1; nom: "a" }, { id: 3; nom: "c" }]; ___________________________________________________________________ (page generated 2023-03-12 23:00 UTC)