Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Intro:
- Filtering requirements have grown. We need to be
- able to filter any kind of Persons.
- Exercise:
- Fix typing for the filterPersons so that it can filter users
- and return User[] when personType='user' and return Admin[]
- when personType='admin'. Also filterPersons should accept
- partial User/Admin type according to the personType.
- `criteria` argument should behave according to the
- `personType` argument value. `type` field is not allowed in
- the `criteria` field.
- Higher difficulty bonus exercise:
- Implement a function `getObjectKeys()` which returns more
- convenient result for any argument given, so that you don't
- need to cast it.
- let criteriaKeys = Object.keys(criteria) as (keyof User)[];
- -->
- let criteriaKeys = getObjectKeys(criteria);
- */
- interface User {
- name: string;
- age: number;
- occupation: string;
- }
- interface Admin {
- name: string;
- age: number;
- role: string;
- }
- export type Person = User | Admin;
- export const isAdmin = (person: Person): person is Admin => !!Object.keys(person).find(x => x === "role");
- export const isUser = (person: Person): person is User => !!Object.keys(person).find(x => x === "occupation");
- export const getObjectKeys= <T>(instance: T) => Object.keys(instance) as (keyof T)[];
- export const persons: Person[] = [
- { name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
- { name: 'Jane Doe', age: 32, role: 'Administrator' },
- { name: 'Kate Müller', age: 23, occupation: 'Astronaut' },
- { name: 'Bruce Willis', age: 64, role: 'World saver' },
- { name: 'Wilson', age: 23, occupation: 'Ball' },
- { name: 'Agent Smith', age: 23, role: 'Anti-virus engineer' }
- ];
- export function logPerson(person: Person) {
- console.log(
- ` - ${person.name}, ${person.age}, ${isAdmin(person) ? person.role : person.occupation}`
- );
- }
- export function filterPersons(persons: Person[], personType: string, criteria: Partial<Person>): Person[] {
- return persons
- .filter((person) => personType === "admin" ? isAdmin(person) : isUser(person))
- .filter((person) => {
- return getObjectKeys(criteria).every((fieldName) => {
- return person[fieldName] === criteria[fieldName];
- });
- });
- }
- export const usersOfAge23 = filterPersons(persons, 'user', { age: 23 });
- export const adminsOfAge23 = filterPersons(persons, 'admin', { age: 23 });
- console.log('Users of age 23:');
- usersOfAge23.forEach(logPerson);
- console.log();
- console.log('Admins of age 23:');
- adminsOfAge23.forEach(logPerson);
- // In case if you are stuck:
- // https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads
Add Comment
Please, Sign In to add comment