Ciekawostki Typescript #4 - typowanie strukturalne
28 October, 2020 - 2 min read
Jesteśmy przyzwyczajeni, że JS jest liberalny, dzięki stosowanemu przezeń typowaniu kaczemu ("jeśli coś chodzi jak kaczka i kwacze jak kaczka..."). Innymi słowy - póki nazwy pól się zgadzają, możemy obiekty stosować wymiennie:
const dog = {
name: "Rex",
age: 3,
breed: "German shepherd",
}
const cat = {
name: "Filemon",
age: 1,
}
const sayLoveTo = ({ name }) => {
console.log(`I love you, ${name}!`)
}
sayLoveTo(dog)
sayLoveTo(cat)Gdy jednak do tego wszystkiego dodamy typy, sprawy się komplikują - wydawać by się mogło, że obikety dog i cat (jeśli są różnych typów, np. Dog i Cat) muszą mieć wspólny typ bazowy, żeby można było je przekazać do metody. Okazuje się jednak - że nie:
interface Dog {
name: string
age: number
breed: string
}
interface Cat {
name: string
age: number
}
interface SomeoneToLove {
name: string
}
const sayLoveTo = (someone: SomeoneToLove): string => {
console.log(`I love you, ${someone.name}!`)
}Jak widać, nie ma żadnej relacji pomiędzy typami Dog, Cat i SomeoneToLove - i właśnie nie musi być! Wszak TS idzie to w ślad (i musi iść) JS, de facto stosując typowanie kacze.
Taka cecha języka może być niespodzianką i czasami prowadzić do pułapek, ale z drugiej strony w wielu miejscach ułatawia pisanie, na przykład w testach jednostkowych.
Ten wpis jest częścią serii o TypeScripcie, inspirowaną lekturą książki D. Vanderkama pt. "TypeScript. Skuteczne programowanie".