Advanced typed get

Not so long ago, I dug up a type-challenges repository on the open spaces of GitHub  . I have a whole blog where I solve problems from there, but today I will try to show not only the implementation  Get



, but also demonstrate common problems, show improvements and use in production.





If you would like to familiarize yourself with the TypeScript concepts that are required in this article before reading, skip to the end.





Also, this article is a translation of an article I wrote in English. If interested, go ahead .





1. Basic implementation

""





, ( )





?





1.1.

, JavaScript:





,  keys.reduce



, . JavaScript split



. TypeScript - .





TypeScript 4.1,  Template Literal types. .  Path



  :





. , ( ).  Playground. :





. Playground.





1.2. Reducer

, , - keys.reduce



. ,  GetWithArray



 , K







:





  1. K extends [infer Key, ...infer Rest]



     ,





  2. Key extends keyof O



       O[Key]



     





 ( Playground). , . :





Playground





1.3.

, : Playground. , .





2.

production, , . ?



, null



undefined



.





Playground. , TypeScript .





. - :





,  undefined



 or null



. .





2.1. undefined, null

3 :





,  undefined



 / null



  union type, , . "" .





, ,  Playground





2.2. reducer

GetWithArray



:





  1. , undefined



    / null







  2. , ( undefined



    )





, (  Playground).





3.

:





JavaScript :





,  string



  number



, Path



:





3.1. Reducer

,  keys.reduce



 . TypeScript  GetWithArray



 . ,  GetWithArray



  .





. A



  O



  :





 Playground, :





  1.  string



     :





     '1' extends keyof string[]



      ,  never



    .





  2. readonly







  3. [0, 1, 2]



    )  never



      undefined



    :





.





3.2. T | undefined

 T | undefined



( , ), T



:





 A extends readonly (infer T)[]



 , .. ( readonly



) .





, .  Playground.





3.3.

, , ( undefined



)





, , extends



( ExtendsTable



) , :





4 :





  1. [0]







  2. number[]







  3. readonly number[]







  4. any[]







, , :













[0]







number[]







readonly number[]







any[]







[0]







βœ…





βœ…





βœ…





βœ…





number[]







❌





βœ…





βœ…





βœ…





readonly number[]







❌





❌





βœ…





❌





any[]







❌





βœ…





βœ…





βœ…





βœ… , , . :





  • [0] extends [0]







  • number[] extends readonly number[]







, ❌, , . :





  • number[] extends [0]







  • readonly number[] extends number[]







 any[]



:  [0]



  ❌, () – βœ….





, !





any[] extends A



 GetWithArray



:





  1.  any[] extends A







  2.  T | undefined







  3. , ,





  4. ,  undefined







,  Playground.





4.

:





:





:  ExtractFromObject



  ExtractFromArray



, , , :





(Generic Constrains):





  1. ExtractFromObject



     β€“  O extends Record<PropertyKey, unknown>



    . , O







  2. ExtractFromArray



     :  A extends readonly any[]







 GetWithArray



:





.  Playground.





5. JavaScript

JavaScript:





 lodash



  ,  get



.  common/object.d.ts @types/lodash



, .  get



  any



 : typescript-lodash-types





 reduce



   for



( for-of



), , undefined



null



:





 get



 , . :





  1. Get



      ,





  2. - (, )





, function



, :





.  Get



 :





 Codesandbox:





  1. get











  2. get







Summary

TypeScript:





  1.   TypeScript 1.3,  (Variadic Tuple Types) 4.0, spread





  2. (Conditional types)  TypeScript 2.8





  3. infer



      , TypeScript 2.8





  4. (Recursive conditional types) TypeScript 4.1





  5. (Template Literal types) TypeScript 4.1





  6. (?) (Generic Constrains)





  7. (Function Overloads)





Thank you all for your attention. If you have any suggestions, write in the comments. Have a nice evening and weekend everyone.








All Articles