5 ms·
I would have liked to see examples. My own instinct here would be to use simpler types, but examples could show why that isn't desirable.
by shadowofneptune 4y ago
I would have liked to see examples. My own instinct here would be to use simpler types, but examples could show why that isn't desirable.
- qudat 4y agoAgreed. I updated the blog to add an example. Copy/pasting here: I spend a decent amount of time in the redux world so `redux-toolkit` is a great library to see how types are done *correctly* in a real codebase. To be clear, they do a fantastic job with types, but the level of complexity is pretty startling. https://github.com/reduxjs/redux-toolkit/blob/master/packages/toolkit/src/createAction.ts#L58 https://github.com/reduxjs/redux-toolkit/blob/master/package... That is just one example but the codebase is riddled with complex types. Also, when you look around, note the amount of types vs actual code. It's pretty common in style guides to never nest ternaries. In typescript, that's the only way to narrow types based on other types. It's a mess!
- shadowofneptune 4y agoThank you.
- nkingsy 4y agoAlong the lines of "just use a dynamic language", we use unknown and any type for a lot of our internal stuff like this. Strongly typed shell, whatever works core.
- meheleventyone 4y agoI suspect it’s a case of bolting on types to soupy JS but would also love to see some examples. I agree with the other commentators that part of the point of a library is to suck in complexity but if you’re regularly doing high level type kungfu there are probably bigger structural issues.
- ryanmcbride 4y agoThey probably just keep running into issues that seem really trivial but are unable to find info on fixing. It's the reason I put off writing things in typescript until relatively recently. In that vein, if anyone here can tell me how the hell you functionally map over a typed object by key in typescript I'll be eternally grateful. I always wanna do something like Object.keys(typedObjName).map(...) but that doesn't work. It's so stupid and small and minor and it's never really prevented me from getting something done but it drives me out of my mind that I still can't find any clear documentation on how to do it.
- badlucklottery 4y ago> I always wanna do something like Object.keys(typedObjName).map(...) but that doesn't work. Is this a type space/value space thing? Like Object.keys(...) is always a string[] instead of Array<keyof TypedObj> like you might expect?
- ryanmcbride 4y agopossibly but the error (that I can't seem to get anymore) was always saying something about TypedObj missing an iterator, making Object.keys() unable to parse it. But I'm not getting that anymore so I have no idea what's going on. Like I said it's just a minor thing that's popped up a few times so I guess I'll just have to wait until it pops up again to know for sure what's up.
- cuddlecake 4y agoDo you have an example for what you want to do, with an object before and after mapping? I don't understand what you mean by "functionally map over a typed object by key"
- shadowofneptune 4y agoI think I have run into a similar issue. I wrote a lexer in Typescript. It is table-based, as is the parser that runs after it. The type for the table looks something like this: type TokenTable<T> = { plus: T, minus: T, bang: T, parenOpen: T, //etc. }; I also have a type defined as 'type TokenID = keyof TokenTable<unknown>;' this makes it possible to check if a string is a valid key at compile-time. The innermost loop of the lexer is a for..in loop. This gives you the keys of the object. One problem: if you try to apply the TokenID type to the loop variable, you get this message: "The left-hand side of a 'for...in' statement cannot use a type annotation." Because of the design of JavaScript, TS cannot give object keys any other type but 'string', even though this type seems like a clear match. To get the typechecking back on the keys, you either need to declare the loop variable outside of the loop itself, or use type casting like this: let token = ""; let id: TokenID | undefined; for (let key in patterns) { const match = patterns[key as TokenID].exec(substring); if (match && (match[0].length > token.length || key == "EOF")) { token = match[0]; id = key as TokenID; } } Neither is particularly clean.