Files
2026-09-08 09:36:02 +02:00

90 lines
3.3 KiB
TeX

\section{Generikusok}
\begin{frame}[fragile]{A probléma, amit a generikák oldanak meg}
\footnotesize
Képzeljünk el egy függvényt, ami egy tömb első elemét adja vissza -- de szeretnénk, hogy \emph{bármilyen} típusú tömbre működjön, miközben megőrizzük a típusinformációt.
\begin{lstlisting}[language=JavaScript,style=NodeJS]
function firstOfNumbers(arr: number[]): number {
return arr[0];
}
function firstOfStrings(arr: string[]): string {
return arr[0];
}
// ...es igy tovabb minden tipusra kulon fuggveny?
\end{lstlisting}
\begin{alertblock}{A probléma}
\texttt{any}-jal megoldhatnánk, de akkor elveszítenénk a típusbiztonságot: a fordító többé nem tudná, mit ad vissza a függvény.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Generikus függvények}
\footnotesize
A \textbf{generikus típus} egy "típusparamétert" (jellemzően \texttt{T}) vezet be, amit a híváskor a konkrét típus tölt ki -- így egyetlen függvény működik bármilyen típusra, típusbiztonság elvesztése nélkül.
\begin{lstlisting}[language=JavaScript,style=NodeJS]
function first<T>(arr: T[]): T {
return arr[0];
}
const n = first([1, 2, 3]); // T = number
const s = first(['a', 'b', 'c']); // T = string
\end{lstlisting}
A TypeScript minden híváskor kikövetkezteti, mi legyen \texttt{T} -- a visszatérési érték típusa mindig pontosan illeszkedik a bemenethez.
\end{frame}
\begin{frame}[fragile]{Generikus interfészek}
\footnotesize
Nemcsak függvények, hanem interfészek (és típusok) is lehetnek generikusak -- ez az alapja például annak, ahogy a legtöbb adatbázis-eredmény vagy API válasz típus felépül.
\begin{lstlisting}[language=JavaScript,style=NodeJS]
interface Box<T> {
value: T;
}
const numberBox: Box<number> = { value: 42 };
const stringBox: Box<string> = { value: 'hello' };
interface ApiResponse<T> {
data: T;
success: boolean;
}
\end{lstlisting}
Egy \texttt{ApiResponse<User>} pontosan jelzi, hogy a \texttt{data} mező egy \texttt{User} objektumot fog tartalmazni -- ezt fogjuk a későbbi heteken az Express válaszainknál is használni.
\end{frame}
\begin{frame}[fragile]{Constraints -- a generikus típus korlátozása}
\footnotesize
Néha nem szeretnénk \emph{bármilyen} típust elfogadni -- csak olyanokat, amiknek van egy adott mezőjük vagy tulajdonságuk. Erre valók a \texttt{extends} kulcsszóval megadott \textbf{constraint}-ek.
\begin{lstlisting}[language=JavaScript,style=NodeJS]
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(item: T): T {
console.log(item.length);
return item;
}
logLength('hello'); // OK - a string-nek van length-je
logLength([1, 2, 3]); // OK - a tombnek is
logLength(42); // Hiba! a number-nek nincs length-je
\end{lstlisting}
\end{frame}
\begin{frame}{Összefoglalás -- Generikus típusok}
\footnotesize
\begin{block}{Generikus típusok}
\begin{itemize}
\item A generikák elkerülik a kódduplikációt anélkül, hogy fel kellene adnunk a típusbiztonságot
\item \texttt{function first<T>(arr: T[]): T} -- a típusparamétert a hívás tölti ki
\item Interfészek/típusok is lehetnek generikusak, pl. \texttt{Box<T>}, \texttt{ApiResponse<T>}
\item \texttt{T extends ...} -- a generikus típus korlátozása egy adott "alakra"
\end{itemize}
\end{block}
\end{frame}