benjaminvr

Untitled

Jun 27th, 2022 (edited)
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  
  3. Intro:
  4.  
  5.     Filtering requirements have grown. We need to be
  6.     able to filter any kind of Persons.
  7.  
  8. Exercise:
  9.  
  10.     Fix typing for the filterPersons so that it can filter users
  11.     and return User[] when personType='user' and return Admin[]
  12.     when personType='admin'. Also filterPersons should accept
  13.     partial User/Admin type according to the personType.
  14.     `criteria` argument should behave according to the
  15.     `personType` argument value. `type` field is not allowed in
  16.     the `criteria` field.
  17.  
  18. Higher difficulty bonus exercise:
  19.  
  20.     Implement a function `getObjectKeys()` which returns more
  21.     convenient result for any argument given, so that you don't
  22.     need to cast it.
  23.  
  24.     let criteriaKeys = Object.keys(criteria) as (keyof User)[];
  25.     -->
  26.     let criteriaKeys = getObjectKeys(criteria);
  27.  
  28. */
  29.  
  30. interface User {
  31.     name: string;
  32.     age: number;
  33.     occupation: string;
  34. }
  35.  
  36. interface Admin {
  37.     name: string;
  38.     age: number;
  39.     role: string;
  40. }
  41.  
  42. export type Person = User | Admin;
  43.  
  44. export const isAdmin = (person: Person): person is Admin => !!Object.keys(person).find(x => x === "role");
  45. export const isUser = (person: Person): person is User => !!Object.keys(person).find(x => x === "occupation");
  46.  
  47. export const getObjectKeys= <T>(instance: T) => Object.keys(instance) as (keyof T)[];
  48.  
  49. export const persons: Person[] = [
  50.     { name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
  51.     { name: 'Jane Doe', age: 32, role: 'Administrator' },
  52.     { name: 'Kate Müller', age: 23, occupation: 'Astronaut' },
  53.     { name: 'Bruce Willis', age: 64, role: 'World saver' },
  54.     { name: 'Wilson', age: 23, occupation: 'Ball' },
  55.     { name: 'Agent Smith', age: 23, role: 'Anti-virus engineer' }
  56. ];
  57.  
  58. export function logPerson(person: Person) {
  59.     console.log(
  60.         ` - ${person.name}, ${person.age}, ${isAdmin(person) ? person.role : person.occupation}`
  61.     );
  62. }
  63.  
  64. export function filterPersons(persons: Person[], personType: string, criteria: Partial<Person>): Person[] {
  65.     return persons
  66.         .filter((person) => personType === "admin" ? isAdmin(person) : isUser(person))
  67.         .filter((person) => {
  68.             return getObjectKeys(criteria).every((fieldName) => {
  69.                 return person[fieldName] === criteria[fieldName];
  70.             });
  71.         });
  72. }
  73.  
  74. export const usersOfAge23 = filterPersons(persons, 'user', { age: 23 });
  75. export const adminsOfAge23 = filterPersons(persons, 'admin', { age: 23 });
  76.  
  77. console.log('Users of age 23:');
  78. usersOfAge23.forEach(logPerson);
  79.  
  80. console.log();
  81.  
  82. console.log('Admins of age 23:');
  83. adminsOfAge23.forEach(logPerson);
  84.  
  85. // In case if you are stuck:
  86. // https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads
  87.  
Add Comment
Please, Sign In to add comment