DEV Community

Cover image for Type | Treat Challenge 2

Type | Treat Challenge 2

Gabrielle Crevecoeur on October 27, 2020

Welcome to the second Type | Treat challenge! Today we will be deriving the types of pumpkins and busting ghosts! Yesterday's Solution ...
Collapse
 
johnnhoj profile image
John Cheng

In the advanced/intermediate challenge. It states that 'Bobby Tables' cannot have peanuts but to me, the solution seems to do the opposite and actually keep all the candies where there are peanuts 🤔

type HasPeanuts<A> = A extends { peanuts: true } ? A : never;
type AllCandiesWithoutPeanuts = HasPeanuts<AllCandies>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dungdung profile image
Houston
type AllCandies = Extract<ResultsFromHalloween, {candy: true}>;
type AllTricks = Extract<ResultsFromHalloween, {trick: true}>;
type AllCandiesWithoutPeanuts = Exclude<AllCandies, {peanuts: true}>;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
johnnhoj profile image
John Cheng • Edited

I agree with your implementation. I was discussing the solution provided in this post :)
Maybe @gcrev93 can help me if I misinterpreted it

Thread Thread
 
dungdung profile image
Houston

My bad, should have said something instead of just plopping down a solution - yes you are correct saying that:

type AllCandiesWithoutPeanuts = HasPeanuts<AllCandies>
Enter fullscreen mode Exit fullscreen mode

is the opposite of the solution. Something more correct would have the inverted type. I'm not sure how one would go from HasPeanuts to something like OmitsPeanuts but declaring it from scratch is straightforward:

type OmitsPeanuts<A> = A extends { peanuts: true } ? never : A;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mattiasbuelens profile image
Mattias Buelens

Also, the proposed solution for AllCandies removes all candies from the union, instead of only keeping the candies.

type AllCandies = Exclude<ResultsFromHalloween, {candy: true}>
// type AllCandies = Toothpaste | Pencil
Enter fullscreen mode Exit fullscreen mode

This should probably use Extract instead of Exclude:

type AllCandies = Extract<ResultsFromHalloween, {candy: true}>
// type AllCandies = SnackBars | Gumballs | Apples | SnickersBar | Cookies
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ricklove profile image
Rick Love

Bobby is on his way to the hospital now. Thankfully somebody had an epi-pen ready.

Collapse
 
clandau profile image
Courtney

"The need to use [number] is an interesting twist, because [0] or 1 would have worked just as well too. Doing this right would also have raised the typo in the original code."

I'm confused by the wording here. So, number AND [0] or [1] would work? So, you don't actually have to use number?

Collapse
 
orta profile image
Orta

Yeah, you can use number or any literal like 1, 2, etc.

In this case, number however feels more right, because you're saying any number from the index, not a specific one.

Collapse
 
clandau profile image
Courtney

Thanks! That makes sense.

Collapse
 
andrewgreenh profile image
Andreas Roth

Here is my attempt :)

Collapse
 
dungdung profile image
Houston • Edited

If we aren't allowed to change type Ghosts and function investigateReport which accepts an array of Ghosts, can we simply return false for both function areGods and function areEctoplasmic?

My implementation of function areDemons using user-defined type guard:

type Demons = Extract<Ghosts, {sendBackToHell(): void}>
function areDemons(ghosts:Ghosts[]): ghosts is Demons[] {
  return ghosts.every(ghost => (ghost as Demons).sendBackToHell !== undefined)
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ricklove profile image
Rick Love

Not if you want to live... and save NYC.