As a part of a backoffice team in a financial organisation, I have to deal with a lot of complex data structures: customer personal data, transacti...
For further actions, you may consider blocking this person and/or reporting abuse
Hello, I have used your code with little change to adapter
_.get()
method and create a pull request github.com/DefinitelyTyped/Definit.... All lodash user can enjoy the feature now, thanks for your working! XDDDWhy use lodash
get
when the path is static (i.e. you know it in advance)? For the first example just useuser?.address?.street
, and your code is perfectly readable and type-safe.If still wanna use
get
for some reason, add an explicit type cast:This helps to understand the type from the first glance, especially when you look at the code not in your IDE but somewhere where types can't be inferred easily, e.g. on GitHub. And if type of 'street' property changes, you'll be alerted.
On the other hand, lodash's
get
is really useful when your path is determined dynamically in runtime, e.g. generated by some algorithm or provided by backend. And that's where inferring type is just impossible without an explicit runtime check.So why complicate things to solve unrealistic problems?
P.S. Would be cool to see a real-life scenario for using this feature.
Yes, I absolutely agree with you. For static paths, it's definitely better to prefer regular field access with an optional chaining. However,
_.get
is still widely used, and some might find it easier to replace a function call or augment lodash typings.Speaking of type-casting, in the first place, you want to avoid it as much as possible. This thing makes type checking looser, and after all, that's not why we are enabling
strict
flag, right? In this particular case, you are giving TS a hint that thisany
is a more specific type. Butget
anyway returnsany
, and if for some reason type ofaddress.street
changes, TS will not complain. In the end,any
could be cast to literally any type.Regarding dynamic paths, of course, not every case is covered (and
GetFieldType
should probably returnunknown
when the field is not found). But this approach still works when you have a union of possible valuesAnd anyway, you could think of this article as an exercise to better understand template literal and conditional types 🙂
As for a real-life scenario, we use it in a slightly different, a bit less dynamic way, to create strongly-typed APIs similar to
react-table
columns config. But that's a topic for another article 😉Great read!
To tell arrays apart from tuples - arrays have a
length
property of type 'number' whereas for a tuple the length property is a specific number. After checking that T is either an array or a tuple (usingT extends unknown[]
, maybe?), it should be possible to tell them apart usingnumber extends T['length']?
How about adding in support for properly typing the return type so that default value is known uinstead of
undefined | default
? (Should be Typescript 4.8+ to support {} as "any non null | undefined value")Thanks a lot for sharing this @tipsy_dev !
I'm building a library and this could be really useful there. Do you know if/how to add type-safety in the path of the properties via template literals? I mean, not to return
undefined
but to make the compiler ensure the path is a valid path.E.g.
So if we do:
Is there a way to do this?
Thanks a lot @tipsy_dev. It is a great approach. But you missed some cases:
string[number][number]
,[number].string
etc.I did add it here: tsplay.dev/mAjB8W . Check it out please. You can find result types at d.ts tab at the right panel.
This post makes me fall in love with Typescript (again!) Very well done 🎉
I'm in love with TypeScript for the last four years, and it feels like it's one of the best things that happen to JS community 🤩
Is there a way to avoid 3 levels of ternary operators? Even 2 levels is hard to read.
Unfortunately, TS doesn't support conditional operators, so it's not possible to concatenate a few expressions with
&&
. The only way I know is to extract each ternary operator into a dedicated type, similar to how it is done withFieldWithPossiblyUndefined
andIndexedFieldWithPossiblyUndefined
. But to my mind, it adds even more boilerplate.Thank you! I'm glad you liked it 🙂
Wow, mind blowing! I don't use typescript on my day job, but this just makes me feel bad about using regular js.
You definitely should give it a try! In the end, regular js is a perfectly valid ts code, so the transition might be not that hard as you imagine it 🙂
This is brilliant and a feature I've needed a few times. Might allow indefinitely deep plucking for cefn.com/lauf/api/modules/_lauf_st...
Thanks @cefn , I'm really happy the article was helpful 🙌
this is f*cking insane. why would you do that. imagine somebody new comes to the project - there is no way to understand this type stuff in a reasonable amount of time.
this is a prime example of why not to use typescript. just create a function that does what you need instead of messing around with these weird types. how would you debug that?
Wouldn't it be possible to add this type inference to
_.get
's typings, why do you have to make a new method?yeah, I'm agree with you. so I create a pull request to
@types/lodash
with the code, now you can update to latest version if youo use_.get()
Thanks for sharing this great awesome articles!
I'm not sure using
lodash.get
should be something I could recommend (and most oflodash
at all).