TypeScript Exercises Bonus🦠 - Answers Part 2
Tags: typescript, javascript
Published: 2020-04-03 11:31:57

--- series: Advanced TypeScript Exercises ---
For details of the questions and requirements please visit [the questions](
https://dev.to/macsikora/typescript-exercises-bonus-type-of-pandemia-1fd0). This post will include only answers for last two questions. If you are not aware of what this is about, then please take some time with the questions article. Also I would recommend the read about [TypeScript type system as a language](https://dev.to/macsikora/typescript-is-more-than-you-think-2nbf), which can help with understanding what we are doing here. 

This post includes half of the answers, first part can be found - [TypeScript Exercises Bonus🦠 - Answers Part 1](https://dev.to/macsikora/typescript-exercises-bonus-answers-part-1-1nmb)

### Answer 3
The question was: Make type level function which will check if given list of patients can be accommodated into the hospital with given list of free beds 🛌.  
```ts
// remove first item from the tuple
type Shift<T extends Array<any>> 
= ((...a: T) => any) extends ((a: any, ...result: infer Result) => any) ? Result : never;
// alternative version would be simpler with
// Variadic Tuple Types available from TS 4.0
type Shift<T extends Array<any>> = T extends [unknown, ...infer Rest] ? Rest : T;

type _Accomodate<
  Beds extends '🛌'[],
  Patients extends Patient[],
  > = Beds['length'] extends 0 ? Patients['length'] extends 0 ? true : false :
  Patients['length'] extends 0 ? true : { x: _Accomodate<Shift<Beds>, Shift<Patients>> }

type _TraverseA<T> = T extends object ? {
  [K in keyof T]: T[K] extends boolean ? T[K] : _TraverseA<T[K]>
}[keyof T] : T

type CanAccomodate
< Beds extends '🛌'[]
, Patients extends Patient[]
, _A = _Accomodate<Beds, Patients>> 
= _TraverseA<_A>
```
Ok, so now what we did here. We made three functions - `_Accomodate`, `_TraverseA` and the final `CanAccomodate`. 

Function `_Accomodate`:
 - takes list of beds and list of patients as arguments
 - recursively calls itself until beds or patients list will be empty
 - in every iteration its removes element from both lists by `Shift`
 - `{ x: _Accomodate<Shift<Beds>, Shift<Patients>> }` - we need to use container type in order to avoid TS blocking us with infinite recursive call, so its kinda hack 🏴‍☠️
 - function creates structure with a shape `{x: x: x: true | false}`, where amount of levels is equal to smaller list size, the last value is saying if `Patients` list is longer (false), or is smaller or equal (true)

Function `_TraverseA`:
- takes an object or boolean
- checks recursively if boolean it gives it back (this is the result)
- if not it recursively traverse the object until the boolean will be found
- finally it returns the final boolean in the structure prepared by `_Accomodate`

Function `CanAccomodate`
- it is final composition of `_Accomodate` and `_TraverseA`
- it calls `_Traverse` on object type made by `_Accomodate`

Full solution in [the playground](https://www.typescriptlang.org/play/index.html#code/C4TwDgpgBAyglgYwNZQLxQN4GdgENgQBcUA5FokiQL4BQokUAEhLgDbAAWIamO+RpDi3ZdqdcNACKAV1wAnXADtgcRdHTY8BYiQCOshctyqIY8QwAK+OBGU8MNKFEW4AtgJxzVAcxpUoAGRQABTwyFAAPkzCnNxRMvJKKmoAlADcNObQAFIA9hyK9i7uOnkF1IGwFFlQACq5rkVuAiT1rhVBzGyxNQDS-E0lpP0EHVXINQCycEjqmMUt07NjCYbJEDVW0qyDLVusY10iIDUAIrlyuaC7OueXoCsGSSY1AOJyEN4X3BoLOu+fb5jMJITY2OQIOYYZzNHQWcGQkhQfxBVbPNSZejQRi5LBgOB4HYaRxQXAAEzJHywWGInh8ABoSQAzD4QABCEDJNNIgF4NwAzeyQANoAXT8mQA9OKoB9XLkAG7QJlwOQ4KAEiCNFkNKCcaDAaRgVgbLGwDhwJnAAA8tSgEAAHgRFFyoABBOQKECWpQgAB8Pp4wWCADoQ7hiLUUmh-d7I-bHc7A2HSYoQPSoCGg1TtsBiKomRA5FAAEoQLDZyOoaMpyMAfmLpezUGIagVcgyNQA+i6EAgGrkyfxLSSOc647ZnSR+ULhYynFYVLZgFhbQ7x8v5zZlCLZ1B-egR1hBSQjYpvJwSMKV-HlwAGKB1jeLw-H2xnjgXq9rqB3uvAOTSaBiCZNgsEAklH2UZ8TzfD8xydW97x1f9AMwKA7WILsez7AcCEtGAzQtS0Dx9NN8PNK0IKXP1kUxCQoA7WoFFbUCXWtPc6k-eCoFyAAjAArCAEGARCHCcQVejVQpZhAXImTqYVw3Ey84OdHjclyI0lEQ2olKbejGNwZiIFYnTemFH0-EFaTZPkvTalohgAGElG7XtZRwiAiM5ZcVOXScBW3KBKJ81cuMowKux4TC3P7QcDzTYLqPQBimILFjLS7CyHOgEsy3YABGHhnMUVzsMHI8pzTfyLzTQUykUNM2nMqBJSQgC0wAd2gDhDL1IQoCwZpSVlaQ7BsnjvJqXLswAJiKlysPc8rqqqqcZygOr8kUZqWqlP92qgLqoB6hUoFlD4oAmrkpobdgAGZ5pKxbYtwwLNoKHbWuA1hQM67reucXJLsmk1pvYAAWR7SqW16Vt5AV1vehq6gaNM7iuEBPqlb7fsO-7TqNalgedTgtLAawnyAA)

### Answer 4
The question was: Make type level function which will group people from the given list. The three groups are people sick 🤒, people healthy 💪, people in quarantine 🔒.

```ts
// utility types needed
type Unshift<A, T extends Array<any>> 
= ((a: A, ...b: T) => any) extends ((...result: infer Result) => any) ? Result : never;
type Shift<T extends Array<any>> 
= ((...a: T) => any) extends ((a: any, ...result: infer Result) => any) ? Result : never;

type AddPatient<S extends Segregated, P extends Patient> = {
  sick: P extends Sick ? Unshift<P, S['sick']> : S['sick'],
  quarantine: P extends Quarantine ? Unshift<[P], S['quarantine']> : S['quarantine'],
  healthy: P extends Healty ? Unshift<P, S['healthy']> : S['healthy'],
}

type Segragate
<Patients extends Patient[]
, Result extends Segregated = {sick: [], quarantine: [], healthy: []}
,_Next extends Patient[] = Shift<Patients>
,_NextSize extends number = _Next['length']
> = {
  [K in (keyof Patients)]:
      Patients[K] extends Patient ?
        _NextSize extends 0 
        ? AddPatient<Result, Patients[K]>
        : Segragate<_Next, AddPatient<Result, Patients[K]>>
        : never
}[0]

``` 
Function `AddPatient`:
- makes wanted result structure with three sections for patients (sick, healthy,quarantine)
- for quarantine it additionally puts patient into isolation by `[P]`

Function `Segragate`:
- Make recursive call until list of patients is not empty
- For every iteration it calls `AddPatient` in order to put patient into correct section, and also removes this patient from the list as it was already used 

**Caution** the function is not ideal 😪, for bigger list of patients it gives an error about infinite call. Maybe you can make it better? Give it a try 💪

The full solution is available in [the playground](https://www.typescriptlang.org/play/?ssl=47&ssc=5&pln=26&pc=1#code/C4TwDgpgBAyglgYwNZQLxQN4GdgENgQBcUA5FokiQL4BQokUAEhLgDahqY75GkAWLdiGp1w0AIoBXXACdcAO2Bx50dNjwFiJAI7S5i3MogjRDAAr44ERZww0oUebgC2vHDOUBzGlSgAyKAAKeGQoAB8mQQ4IqVkFJRUASgBuGlNoACkAez55WydXLWzc6n9YCnSoABUs53yXXhIa51KA5jZQSoBpHnrC0h6CVvLkSoBZOCRVTALGianh2P0EiEqLSVY+xvXWYfahSoARLJksjjVZrWPT0EW9eKNKgHEZCE8TkC2tF7eP4ZCkGsrDIENMMJdSGZgaC7nFFI8aAB6RFQKQQHBwLJ5CzyAAmEGccFwUAAzFAALRQZy4KZQejQVgQABuEE2ADNJPIEEosVAAO58RB8flwVibBACUJwNl0vlZKBgSzWYBYKAIBRUiAQYBpemwN6vTw8XG2exQcjIYgAgDaAF0ADRm3RwlbEa1LB4qW12x0OAQdPggYj7UB2ny6sRQACq8iwgrZwAAPABBe3VKAQAAeBDxquTMjkIETChAAD5S5xAoFcMRU1AAHSNgBGxCqiTQFZL7azOdxqqrjfrrywG2AxGUbIgMigACV0aP26hO-IQO2APyz+fsKDEFQsmSpPUweNJqoZ7PWPtQfOF4sr8uVwKDmvVRfL1fn3v96vEEtpwfDqO47yJO05ziO7BvlAXZQBu4GjjujjMlOqSVMmuK4hYSjKomMCfpeqowAabzGmmZj4bmUBYVYigVmoZoWkgxDkT2BEjCgG4xnG0pJmYaYwNaZAUCQtoVlagmMSJvpQM6yxGMxFFXh68IqLB0axieibWmYDqwIJsmesYomIQJOj3CpRnSf67CBgprGUSGnycRpPGJnxekkNZwCBiJYkeV5PkOuGlREZ4chGgQNBuUqiiqvZV7UcqYZpvB27xYRxERRAJpqIxbq6QZFn5WmAVBlAdq0PaAD6AByPaKaqiWKHanDHq5TUqqWNDVXV2bwAAXtA6WOJIzhNlOnC1T2gmMvInjeSJNB0ZgZrWl0UDKEEUwgFkModVgiS2oQZoOA4+1rbaDVUTFwCwSdp0OFNfVwINV0AAxQPdD0buhmE3YmqXAGRN1YBdXUPQ9VoGrgWWJk9QPXhhHUA1uCPnV0ongxDDi7shMg+Nab22hGDDJgmU6hYali8uglMwzwWlmsU8jSc00mDBA0nzJzZo7NJ1xnCAjqiUiABUov2GTFOZdTeRxlkGwmuN9h2A9eXlRzabM7aqQPYVeDyeV1oC6AunWtzto6-dXlldpuAbGmzRW1AtBQKLiJAA)

**This series will continue**. If you want to know about new exciting questions from advanced TypeScript please follow me on [dev.to](https://dev.to/macsikora) and [twitter](https://twitter.com/macsikora). **Be healthy and take care!**