\section{Union/Intersection} \begin{frame}[fragile]{Union típusok -- "vagy ez, vagy az"} \footnotesize Egy \textbf{union} típus (\texttt{|} jellel) azt fejezi ki, hogy egy érték \emph{többféle} típus egyike lehet. Ez az egyik legtöbbet használt eszköz a valós TypeScript kódban. \begin{lstlisting}[language=JavaScript,style=NodeJS] type Id = string | number; function printId(id: Id) { console.log(`Az azonosito: ${id}`); } printId(123); // OK printId('abc-123'); // OK is \end{lstlisting} \begin{block}{Gyakori példa} \texttt{type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';} -- ilyenkor a fordító nem enged elgépelt, érvénytelen metódusnevet. \end{block} \end{frame} \begin{frame}[fragile]{Type narrowing -- a típus leszűkítése} \footnotesize Ha egy változó union típusú, a fordító csak azokat a műveleteket engedi rajta, amik \emph{minden} lehetséges típusnál érvényesek -- amíg nem szűkítjük le (narrowing), melyik konkrét típusról van szó. \begin{lstlisting}[language=JavaScript,style=NodeJS] function printId(id: string | number) { if (typeof id === 'string') { console.log(id.toUpperCase()); // itt mar biztos string } else { console.log(id.toFixed(2)); // itt mar biztos number } } \end{lstlisting} \begin{itemize} \item \texttt{typeof} -- primitív típusok megkülönböztetésére (\texttt{string}, \texttt{number}, stb.) \item \texttt{instanceof} -- osztálypéldányok megkülönböztetésére \item \texttt{in} -- egy adott mező meglétének ellenőrzésére egy objektumon \end{itemize} \end{frame} \begin{frame}[fragile]{Intersection típusok -- "ez is, az is"} \footnotesize Az \textbf{intersection} típus (\texttt{\&} jellel) ennek épp az ellentéte: egy érték \emph{egyszerre} feleljen meg több típusnak is -- a mezők összeadódnak. \begin{lstlisting}[language=JavaScript,style=NodeJS] interface HasId { id: number; } interface HasName { name: string; } type Entity = HasId & HasName; const user: Entity = { id: 1, name: 'Anna' }; \end{lstlisting} Az \texttt{Entity} típusú értéknek \emph{mindkét} interfész mezőit tartalmaznia kell -- ez hasznos, ha kisebb, újrafelhasználható "építőelemekből" rakunk össze nagyobb típusokat. \end{frame} \begin{frame}[fragile]{Literal típusok} \footnotesize A TypeScript-ben nemcsak \texttt{string} vagy \texttt{number} lehet egy típus, hanem egy \emph{konkrét érték} is -- ezt hívjuk literal típusnak. Union-nal kombinálva rendkívül kifejező, önmagát dokumentáló kódot kapunk. \begin{lstlisting}[language=JavaScript,style=NodeJS] type Status = 'pending' | 'active' | 'closed'; function setStatus(status: Status) { // csak a harom felsorolt string-et fogadja el } setStatus('active'); // OK setStatus('done'); // Hiba! nincs ilyen Status \end{lstlisting} \end{frame} \begin{frame}{Összefoglalás -- Union és Intersection} \footnotesize \begin{block}{Union és Intersection típusok} \begin{itemize} \item Union (\texttt{|}): "vagy ez, vagy az" -- egy érték többféle típus egyike lehet \item Type narrowing: \texttt{typeof}/\texttt{instanceof}/\texttt{in} -- leszűkítjük, melyik konkrét típusról van szó \item Intersection (\texttt{\&}): "ez is, az is" -- több típus mezői összeadódnak \item Literal típusok: konkrét értékek típusként, gyakran union-nal kombinálva (pl. HTTP metódusok) \end{itemize} \end{block} \end{frame}