Guest User

Untitled

a guest
Sep 25th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.53 KB | None | 0 0
  1. export function composeGetter<K extends string>(prop: K) {
  2. function getter<T extends { [P in K]?: any }>(object: T): T[typeof prop]
  3. function getter<T extends { [P in K]: any }>(object: T) {
  4. return object[prop]
  5. }
  6.  
  7. return getter
  8. }
  9.  
  10. export function composeSetter<K extends string>(prop: K) {
  11. function setter<T extends { [P in K]?: any }>(object: T, value: T[typeof prop]): T
  12. function setter<T extends { [P in K]: any }>(object: T, value: T[typeof prop]): T {
  13. return Object.assign(object, {
  14. [prop]: value
  15. })
  16. }
  17.  
  18. return setter
  19. }
  20.  
  21. export interface GetProperty<K extends string> {
  22. <T extends { [P in K]?: any }>(object: T): T[K]
  23. <T extends { [P in K]: any }>(object: T): T[K]
  24. }
  25.  
  26. export interface SetProperty<K extends string> {
  27. <T extends { [P in K]?: any }>(object: T, value: T[K]): T
  28. <T extends { [P in K]: any }>(object: T, value: T[K]): T
  29. }
  30.  
  31. // Examples
  32.  
  33. interface User {
  34. id: number,
  35. username: string,
  36. }
  37.  
  38. type NewUser = Partial<User>
  39.  
  40. export const getUserId = composeGetter('id')
  41.  
  42. type UsernameGetter = GetProperty<'username'>
  43. const getUsername: UsernameGetter = composeGetter('username')
  44.  
  45. declare const user: User
  46. declare const newUser: NewUser
  47.  
  48. const userId = getUserId(user) // :number
  49. const userUsername = getUsername(user) // :number | undefined
  50.  
  51. const newUserId = getUserId(newUser) // :number | undefined
  52. const newUserUsername = getUsername(newUser) // :string | undefined
  53.  
  54. const nextUser = composeSetter('username')(newUser, 'foobar')
  55. const nextUserUsername = nextUser.username // :string | undefined
Add Comment
Please, Sign In to add comment