O mnieBlogGitHub

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".

© 2021, Built with Gatsby