Auch am vierten Tag, gibt es wieder zwei coole Challenges. Werfen wir einen Blick auf die Ausgangssituation, die ‚getBowl‘ Funktion verliert den Typen und wir müssen einen Compiler-Fehler erzeugen.
Im zweiten Teil der Challenge, müssen wir die Funktion ‚fillBowls‘ so erweitern, dass die Typen ein String Literal ergeben anstelle eines ’string;‘
// You've got yourself bunch of bowls of candy, but the bowls are
// just "generic" bowls. You can put anything in them, and get anything
// back out of them.
function getBowl(items: any) {
return { items }
}
const chewyMixBowl = getBowl({ colors: ["red", "green", "blue"], strawberries: "some" })
// ^?
const candiedApplesBowl = getBowl({ types: ["Tanghulu", "Maçã do amor", "Toffee Apples"] })
// ^?
// This is a shame, because ideally this would raise a compiler arror:
candiedApplesBowl.items.type[0]
// Can you think of a way to let the parameter of `getBowl` keep the type
// of `items` through the function?
// You've got yourself bunch of bowls of candy, but the bowls are
// just "generic" bowls. You grab a few fancy branded :tm: bowls and
// fill the bowls with their candy.
function fillBowl<T>(candy: T) {
return { candy }
}
const marsBowl = fillBowl("mars")
const snickersBowl = fillBowl("snickers")
const skittlesBowl = fillBowl("skittles")
// It turns out that a few kids are picky though,
// and only want to get one type of candy from each bowl.
const giveOutSnickers = (str: "snickers") => { }
const giveOutSkittles = (str: "skittles") => { }
const giveOutMarsBars = (str: "mars") => { }
// This means you will need to extend the `fillBowl` to
// handle passing a specific string literal through the
// the function. You will only need to add two words to
// the function to make this work.
giveOutSnickers(snickersBowl.candy)
giveOutSkittles(skittlesBowl.candy)
giveOutMarsBars(marsBowl.candy)
Die Funktion ‚getBowl‘ kann einfach mit Generics erweitert werden und der erste Teil der Aufgabe ist gelöst.
function getBowl<T>(items: T) {
return { items }
}
Die Funktion ‚fillBowl‘ kann mit nur zwei Worten erweitert werden und damit die Aufgabe lösen. Damit TypeScript die String Literale korrekt behält erweitern wir die Funktion mit ‚extends string‘
function fillBowl<T extends string>(candy: T) {
return { candy }
}
Intermediate Challenge
Die Intermediate Challenge ist auch schnell gelöst, sofern man verstanden hat woran es hängt. Das Competitor Interface hat natürlich nicht die Eigenschaften eines DecorativeCompetition Interfaces. Demnach müssen wir es ermöglichen, dass der Compiler weiß, dass es sich dabei um eine konkreteres Interface handelt.
Die ursprüngliche Implementierung der Check Method ist folgende:
const check = (data: Competitor[]) => {
return data.map(competitor => {
if (competitor.weight > 2121.5) throw new Error("Stop the show, world record hit!")
return { ...competitor, judge: (...args: unknown[]) => { } }
})
}
Der Parameter ‚data‘ wird zu einem Generic Array und unser Generic muss explizit vom Typ ‚Competitor‘ erben.
const check = <T extends Competitor>(data: T[]) => {
return data.map(competitor => {
if (competitor.weight > 2121.5) throw new Error("Stop the show, world record hit!")
return { ...competitor, judge: (...args: unknown[]) => { } }
})
}