Type | Treat Challenge 4
Welcome to the fourth Type | Treat challenge! Today we will be stopping hauntings and putting puppies in their place.
Yesterday's Solution
Beginner/Learner Challenge
We were looking for some pretty simple types in this challenge:
type Treat = {
location: string
result: "treat",
treat: { candy: string, baked?: string }
}
type Trick = {
location: string
result: "trick",
trick: string
}
type NoShow = {
location: string
result: "no-show"
}
We can safely and efficiently reuse the properties in each field by extend
ing them with an interface.
type House = {
location: string
result: "treat" | "trick" | "no-show"
}
interface Treat extends House { treat: { candy: string, baked?: string } }
interface Trick extends House { trick: string }
interface NoShow extends House { trick: string }
We can specialize each result
property with the specific value a Trick
, Treat
, or NoShow
will hold by re-declaring it.
interface Treat extends House { result: "treat", treat: { candy: string, baked?: string } }
interface Trick extends House { result: "trick", trick: string }
interface NoShow extends House { result: "no-show" }
Which would give the exact string value for result
in each type.
Intermediate/Advanced Challenge
This one either stumped people for ten minutes or was considered a breeze. We had a few different answers in the TypeScript team, but we think this one is the most elegant.
type Result = {
done: boolean,
who: string,
loot: Record<string, any>
}
type TrunkOrTreatResults = Record<typeof trunkOrTreatSpots[number], Result>
This challenge was a great reminder that a Record
is simply a type-alias to a conditional type:
type Record<K extends string | number | symbol, T> = { [P in K]: T; }
Which can convert the original answer:
type Result = {
done: boolean,
who: string,
loot: Record<string, any>
}
type ResultMapper<P extends readonly string[]> = {
[K in P[number]]: Result
};
type TrunkOrTreatResults = ResultMapper<typeof trunkOrTreatSpots>;
into code which is both easier to read, and requires knowing less language concepts. Kudos to the folks who made it seem very easy!
Here's our answer. Bonus: the weirdest answer.
The Challenge
Beginner/Learner Challenge
Don't freak out... Ok freak out a little bit cause WE ARE BEING HAUNTED! And they are after our code! We have tried everything but we cant seem to get it right!
Somehow they keep manipulating the objects set this snippet of code. Take a look and see if you can force the ghosts to stop moving things around.
Intermediate/Advanced Challenge
You've been roped into helping out the halloween puppy parade, it was such a distracting even that you did the minimum possible to spend as much time watching the show.
Now it's over, you figure it's time to clean up your code and try get it type-safe.
Submissions
Be sure to submit your solution by using the Share button in the TypeScript playground.
Then go to Twitter, and create a tweet about the challenge, add the link to your code and mention the TypeScript page (@typescript)
Need Extra Help?
If you need additional help you can utilize the following:
- The TypeScript Handbook
- TypeScript Discord Page
- The comments on each Dev.to posts!
Happy Typing :)
Top comments (6)
Is this an acceptable answer to yesterday's beginner problem?
Yep - it's a solid answer too!
Thanks!
My intermediate/advanced solution: typescriptlang.org/play?ts=4.1.0-b...
Cool to play around with beta features!
This is awesome π