For Frontend practice

This commit is contained in:
magdo
2026-03-21 20:39:18 +01:00
parent 8b8c08be1b
commit ad1e783472
68 changed files with 3817 additions and 0 deletions
Binary file not shown.
Binary file not shown.
+230
View File
@@ -0,0 +1,230 @@
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[magyar]{babel}
\usepackage{indentfirst}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{fancyvrb}
\usepackage{amssymb}
\usepackage{pifont}
\usepackage{newunicodechar}
% Unicode szimbólumok definiálása
\newcommand{\cmark}{\ding{51}} % ✓ check mark
\newcommand{\xmark}{\ding{55}} % ✗ ballot x
\newunicodechar{✓}{\cmark}
\newunicodechar{✗}{\xmark}
\newunicodechar{❌}{\textcolor{red}{\xmark}}
% Globális verbatim beállítás - tiny betűméret minden verbatim blokkhoz
\fvset{fontsize=\tiny}
\usepackage{listingsutf8}
\usepackage{textcomp}
\usepackage{eurosym}
\usepackage{mathtools}
\lstset{literate=
{á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
{Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
{à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
{À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
{ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
{Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
{â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
{Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
{œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
{ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
{€}{{\EUR}}1 {£}{{\pounds}}1 {ő}{{\H{o}}}1 {ű}{{\H{u}}}1
}
% Docker nyelvdefiníció
\lstdefinelanguage{Docker}{
keywords={FROM, RUN, CMD, LABEL, MAINTAINER, EXPOSE, ENV, ADD, COPY,
ENTRYPOINT, VOLUME, USER, WORKDIR, ARG, ONBUILD, STOPSIGNAL,
HEALTHCHECK, SHELL, AS},
keywordstyle=\color{blue}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{\#},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]"
}
% JavaScript nyelvdefiníció
\lstdefinelanguage{JavaScript}{
keywords={typeof, new, true, false, catch, function, return, null, catch,
switch, var, const, let, if, in, while, do, else, case, break, async,
await, class, export, import, extends, super, this, throw, try, default},
keywordstyle=\color{blue}\bfseries,
ndkeywords={class, export, boolean, throw, implements, import, this},
ndkeywordstyle=\color{darkgray}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]"
}
% YAML nyelvdefiníció
\lstdefinelanguage{yaml}{
keywords={true,false,null,y,n},
keywordstyle=\color{darkgray}\bfseries,
sensitive=false,
comment=[l]{\#},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]",
basicstyle=\ttfamily\scriptsize,
breaklines=true,
columns=fullflexible,
keepspaces=true,
showstringspaces=false
}
\lstdefinestyle{HTML}{
language=HTML,
breaklines=true,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
stringstyle=\ttfamily,
inputencoding=utf8,
morekeywords={header, time, nav, main, article, section, aside, role,
footer, details, open, summary, srcdoc, list, datalist, placeholder,
pattern, required, min, max, step, enctype, formaction, formmethod,
formnovalidate, formtarget, output}
}
\lstdefinestyle{JavaScript}{
basicstyle=\ttfamily\scriptsize,
breaklines=true,
columns=fullflexible,
keepspaces=true,
showstringspaces=false,
literate={}
}
\lstdefinestyle{NodeJS}{
basicstyle=\ttfamily\scriptsize,
breaklines=true,
columns=fullflexible,
keepspaces=true,
showstringspaces=false,
literate={}
}
\lstdefinestyle{Express}{
basicstyle=\ttfamily\scriptsize,
breaklines=true,
columns=fullflexible,
keepspaces=true,
showstringspaces=false,
literate={}
}
\lstdefinestyle{Prisma}{
basicstyle=\ttfamily\scriptsize,
breaklines=true,
columns=fullflexible,
keepspaces=true,
showstringspaces=false,
literate={}
}
\usepackage{hyperref}
\usepackage{attachfile}
\usepackage{multirow}
% Navigációs pöttyök hozzáadása subsection nélküli fejezetekhez
\usepackage{remreset}
\makeatletter
\@removefromreset{subsection}{section}
\makeatother
\setcounter{subsection}{1}
%%%%%
\attachfilesetup{color={1.0 0.6 0.0},author={MD},description={Kattintson duplán a minta %
megtekintéséhez!},icon=Paperclip}
% Széchenyi Egyetem arculati színek
\definecolor{szenavy}{RGB}{44,62,80} % Sötét kék (fejléc)
\definecolor{szecyan}{RGB}{0,168,225} % Világos kék (kiemelés, logó)
\definecolor{szezold}{RGB}{139,195,74} % Élénk zöld (akcentus)
\definecolor{szeszurke}{RGB}{96,96,96} % Sötét szürke
% Kompatibilitás a régi parancsokkal
\definecolor{kiemelesszin}{RGB}{0,168,225} % Kék kiemelés (szecyan)
\definecolor{kiemelesszinZ}{RGB}{139,195,74} % Zöld kiemelés (szezold)
\definecolor{kiemelesszinN}{RGB}{44,62,80} % Navy kiemelés (szenavy)
\definecolor{hivatkozasszin}{RGB}{0,168,225} % Kék hivatkozás
\newcommand{\kiemel}[1]{{\color{kiemelesszin}#1}}
\newcommand{\kiemelZ}[1]{{\color{kiemelesszinZ}#1}}
\newcommand{\kiemelN}[1]{{\color{kiemelesszinN}#1}}
\newcommand{\hiv}[1]{{\color{hivatkozasszin}#1}}
\newcommand{\logoalul}{
\begin{picture}(0,0)
\put(120,-0){\hbox{\includegraphics[scale=.5]{./common/sze_logo.pdf}}}
\put(205,-6){\hbox{\includegraphics[scale=.4]{./common/it_logo.pdf}}}
\end{picture}
}
\frenchspacing
\usetheme[compress]{Berlin}
\useoutertheme[subsection=false]{miniframes}
\setbeamerfont{section in head/foot}{size=\tiny}
\setbeamerfont{subsection in head/foot}{size=\tiny}
% Adaptív, kattintható navigáció:
% sok section esetén az aktuális marad nagy és szöveges,
% a többi section lekicsinyített sorszámként jelenik meg.
\newcommand{\sectioncompactthreshold}{11}
\makeatletter
\providecommand{\totalsectionscount}{0}
\AtEndDocument{%
\immediate\write\@auxout{\string\gdef\string\totalsectionscount{\arabic{section}}}%
}
\makeatother
\setbeamertemplate{section in head/foot}{%
{\fontsize{6}{7}\selectfont\bfseries\insertsectionhead}%
}
\setbeamertemplate{section in head/foot shaded}{%
\ifnum\totalsectionscount>\sectioncompactthreshold
{\fontsize{4.5}{5.5}\selectfont\insertsectionheadnumber}%
\else
{\fontsize{5}{6}\selectfont\insertsectionhead}%
\fi
}
\setbeamertemplate{headline}
{
\leavevmode%
\hbox{%
\begin{beamercolorbox}[wd=\paperwidth,ht=2.5ex,dp=1.125ex]{section in head/foot}%
\insertsectionnavigationhorizontal{\paperwidth}{}{\hskip0pt plus1filll}
\end{beamercolorbox}%
}
\vskip0pt%
}
% Kisebb betűméret a slide-okhoz
\setbeamerfont{frametitle}{size=\normalsize}
\setbeamerfont{framesubtitle}{size=\small}
\setbeamerfont{block title}{size=\small}
\setbeamerfont{block body}{size=\footnotesize}
\setbeamerfont{itemize/enumerate body}{size=\footnotesize}
\setbeamerfont{itemize/enumerate subbody}{size=\scriptsize}
% Beamer színséma testreszabása Széchenyi arculathoz
\setbeamercolor{structure}{fg=szecyan}
\setbeamercolor{palette primary}{bg=szenavy,fg=white}
\setbeamercolor{palette secondary}{bg=szecyan,fg=white}
\setbeamercolor{palette tertiary}{bg=szezold,fg=white}
\setbeamercolor{palette quaternary}{bg=szeszurke,fg=white}
\setbeamercolor{titlelike}{parent=palette primary}
\setbeamercolor{frametitle}{bg=szenavy,fg=white}
\setbeamercolor{frametitle right}{bg=szenavy}
\setbeamercolor{block title}{bg=szecyan,fg=white}
\setbeamercolor{block body}{bg=szecyan!10,fg=black}
\setbeamercolor{block title alerted}{bg=szezold,fg=white}
\setbeamercolor{block body alerted}{bg=szezold!10,fg=black}
\setbeamercolor{item}{fg=szecyan}
\setbeamercolor{subitem}{fg=szezold}
\author{Magda Donát}
\institute{Széchenyi István Egyetem, Győr}
\date{\hiv{\href{https://git.mdnd-it.cc/Donat/GKNB_MSTM071}{https://git.mdnd-it.cc/Donat/GKNB_MSTM071}}\\ \today}
@@ -0,0 +1,86 @@
\section{Alapok}
\begin{frame}[fragile]{Mi a TypeScript?}
\begin{itemize}
\item A TypeScript a JavaScript \kiemel{típusos kiterjesztése}.
\item Fejlesztés közben jelez hibákat, mielőtt futna a kód.
\item A fordítás után sima JavaScript fut a böngészőben vagy Node.js alatt.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Hogyan gondolkodj róla kezdőként?}
\begin{itemize}
\item A JavaScript megmondja, \kiemel{hogyan} fusson a program.
\item A TypeScript megmutatja, \kiemel{milyen adatokkal} futhat biztonságosan.
\item A típusok dokumentációként is működnek, így a következő fejlesztő gyorsabban megérti a kódot.
\item A cél nem a bonyolult típusok gyártása, hanem a hibák korai kiszűrése.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Miért jó kezdőknek?}
\begin{itemize}
\item Könnyebb megérteni, milyen adatot vár egy függvény.
\item Biztonságosabb a refaktorálás.
\item Jobb IDE-támogatást kapsz (autocomplete, hibajelzések).
\item Kisebb az esélye a futásidejű meglepetéseknek.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Mire figyelj a tanulás elején?}
\begin{itemize}
\item Először a JavaScript alapokat erősítsd meg: változók, függvények, objektumok, tömbök.
\item Utána vezesd be a TypeScriptet kis lépésekben: előbb paraméter- és visszatérési típusokkal.
\item Ne használd túl korán az any típust, mert ezzel elveszíted a TypeScript fő előnyét.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Telepítés és első projekt}
\begin{lstlisting}[style=NodeJS]
mkdir ts-course
cd ts-course
npm init -y
npm install -D typescript ts-node @types/node
npx tsc --init
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Egyszerű tsconfig.json}
\begin{lstlisting}[style=JavaScript]
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"rootDir": "src",
"outDir": "dist",
"esModuleInterop": true
},
"include": ["src"]
}
\end{lstlisting}
\begin{itemize}
\item strict: szigorúbb ellenőrzés, kevesebb rejtett hiba.
\item rootDir/outDir: tisztán elválasztja a forráskódot és a fordított kódot.
\item module NodeNext: modern ES-modulok Node környezetben.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Első TypeScript-kód}
\begin{lstlisting}[style=JavaScript]
// src/index.ts
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("TypeScript"));
\end{lstlisting}
\begin{lstlisting}[style=NodeJS]
npx tsc
node dist/index.js
\end{lstlisting}
\begin{itemize}
\item Először a tsc fordító fut le, ez ellenőrzi a típusokat.
\item Ezután már JavaScript fut, vagyis a végrehajtás mindig JS-ben történik.
\end{itemize}
\end{frame}
@@ -0,0 +1,63 @@
\section{Típusok}
\begin{frame}[fragile]{Primitív típusok}
\begin{lstlisting}[style=JavaScript]
let userName: string = "Anna";
let age: number = 20;
let isStudent: boolean = true;
let value: null = null;
let missing: undefined = undefined;
\end{lstlisting}
\begin{itemize}
\item Ezek a legalapvetőbb építőelemek, minden összetettebb típus ezekre épül.
\item A null és undefined kezelése kulcsfontosságú a stabil alkalmazásokhoz.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Típusinferencia}
\begin{lstlisting}[style=JavaScript]
let city = "Gyor"; // string
let points = 10; // number
const role = "admin"; // "admin" literal
\end{lstlisting}
\begin{itemize}
\item Nem kell mindig kiírni a típust.
\item Akkor érdemes explicit típust adni, ha nő tőle az olvashatóság.
\item Jó egyensúly: ahol egyértelmű, hagyd inferálni; ahol kétértelmű, írj explicit típust.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Tömbök és tuple}
\begin{lstlisting}[style=JavaScript]
const nums: number[] = [1, 2, 3];
const tags: Array<string> = ["ts", "js"];
const point: [number, number] = [10, 20];
const personRow: [id: number, name: string] = [1, "Bela"];
\end{lstlisting}
\begin{itemize}
\item Tömb: tetszőleges elemszám, azonos elemtípus.
\item Tuple: fix elemszám, pozíciónként meghatározott típus.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Objektumtípusok}
\begin{lstlisting}[style=JavaScript]
const user: { id: number; name: string; active: boolean } = {
id: 1,
name: "Kata",
active: true,
};
\end{lstlisting}
\begin{itemize}
\item Objektumoknál a típus gyorsan hosszúvá válhat, ezért a következő lépés a type/interface használata.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Tipikus kezdő hibák típusoknál}
\begin{itemize}
\item Összekeverni a number és string értékeket (pl. "10" + 5).
\item Elfelejteni, hogy a const literál-típust is adhat.
\item Nem kezelni a null lehetőségét külső adatoknál.
\end{itemize}
\end{frame}
@@ -0,0 +1,69 @@
\section{Függvények}
\begin{frame}[fragile]{Függvénytípusok}
\begin{lstlisting}[style=JavaScript]
function add(a: number, b: number): number {
return a + b;
}
const multiply = (a: number, b: number): number => a * b;
\end{lstlisting}
\begin{itemize}
\item Mindig típusold a bemenetet, és lehetőség szerint a visszatérési értéket is.
\item Ettől egyértelműbb lesz a függvény szerződése.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Opcionális és alapértelmezett paraméter}
\begin{lstlisting}[style=JavaScript]
function greet(name: string, title?: string): string {
return title ? `${title} ${name}` : name;
}
function power(base: number, exp = 2): number {
return base ** exp;
}
\end{lstlisting}
\begin{itemize}
\item Opcionális paraméter csak a paraméterlista végén legyen.
\item Az alapértelmezett paraméter csökkenti a hívó kód bonyolultságát.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Union típusok}
\begin{lstlisting}[style=JavaScript]
let id: string | number;
id = "A12";
id = 12;
type Direction = "up" | "down" | "left" | "right";
let move: Direction = "left";
\end{lstlisting}
\begin{itemize}
\item A union azt jelenti, hogy az adat többféle típusból érkezhet.
\item Literál unionnal szűk, előre ismert értékkészletet adhatsz meg.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Típusszűkítés (narrowing)}
\begin{lstlisting}[style=JavaScript]
function printId(value: string | number) {
if (typeof value === "string") {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(0));
}
}
\end{lstlisting}
\begin{itemize}
\item Narrowing nélkül a fordító nem engedné string- vagy number-specifikus metódusok hívását.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Gondolkodási minta union esetén}
\begin{itemize}
\item 1. lépés: sorold fel, milyen típusok jöhetnek.
\item 2. lépés: minden esetre írj megfelelő ellenőrzést.
\item 3. lépés: minden ágban csak az adott típushoz illő műveletet végezz.
\end{itemize}
\end{frame}
@@ -0,0 +1,61 @@
\section{Típusaliasok és interfészek}
\begin{frame}[fragile]{Type alias}
\begin{lstlisting}[style=JavaScript]
type User = {
id: number;
name: string;
email?: string;
};
const u: User = { id: 1, name: "Dora" };
\end{lstlisting}
\begin{itemize}
\item A type kulcsszó jó választás, ha később unionöket vagy utility típusokat is használsz.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Interface}
\begin{lstlisting}[style=JavaScript]
interface Product {
sku: string;
price: number;
discount?: number;
}
const p: Product = { sku: "A-1", price: 100 };
\end{lstlisting}
\begin{itemize}
\item Az interface különösen hasznos API-szerződéseknél és osztályoknál.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Type vs interface (gyakorlat)}
\begin{itemize}
\item Interface: objektumszerződésekhez.
\item Type: unionokhoz, metszetekhez, utility típusokhoz.
\item Mindkettő használható objektumokhoz, a csapatdöntés a fontos.
\item A legfontosabb: kódbázison belül maradj következetes.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Readonly és opcionálisság}
\begin{lstlisting}[style=JavaScript]
type Settings = {
readonly appName: string;
theme?: "light" | "dark";
};
\end{lstlisting}
\begin{itemize}
\item readonly: a property létrehozás után nem módosítható.
\item ?: az adott mezőt nem kötelező minden esetben megadni.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Mikor válts type aliasról interface-re?}
\begin{itemize}
\item Ha objektumszerződést publikus API-ként szeretnél kommunikálni.
\item Ha osztály implementálja a szerződést.
\item Ha a csapatod konvenciója ezt preferálja.
\end{itemize}
\end{frame}
@@ -0,0 +1,65 @@
\section{Középhaladó: Generikus típusok}
\begin{frame}[fragile]{Generic alap}
\begin{lstlisting}[style=JavaScript]
function identity<T>(value: T): T {
return value;
}
const a = identity(42); // number
const b = identity("hello"); // string
\end{lstlisting}
\begin{itemize}
\item A generic lehetővé teszi, hogy ugyanaz a függvény több típusra is működjön.
\item A T helyére a fordító a hívás alapján következteti a típust.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Generic constraint}
\begin{lstlisting}[style=JavaScript]
function firstItem<T extends any[]>(items: T) {
return items[0];
}
const first = firstItem([10, 20, 30]);
\end{lstlisting}
\begin{itemize}
\item A constraint (extends) korlátozza, milyen típus adható a generic paraméternek.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Utility tipusok}
\begin{lstlisting}[style=JavaScript]
type User = { id: number; name: string; email: string };
type UserPatch = Partial<User>;
type UserPublic = Pick<User, "id" | "name">;
type UserWithoutEmail = Omit<User, "email">;
\end{lstlisting}
\begin{itemize}
\item Utility típusokkal gyorsan előállíthatsz új típusokat manuális másolás nélkül.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Record es Readonly}
\begin{lstlisting}[style=JavaScript]
type ScoreByName = Record<string, number>;
type Config = Readonly<{
apiUrl: string;
retries: number;
}>;
\end{lstlisting}
\begin{itemize}
\item Record: kulcs-érték struktúra típusosan.
\item Readonly: megakadályozza a véletlen módosításokat.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{A genericek tanulási sorrendje}
\begin{enumerate}
\item Először használj kész generic API-kat (pl. Promise<T>, Array<T>).
\item Utána írj egyszerű saját generic függvényt.
\item Végül vezesd be a constraintet és utility típusokat.
\end{enumerate}
\end{frame}
@@ -0,0 +1,70 @@
\section{Középhaladó: Modulok és aszinkron működés}
\begin{frame}[fragile]{Modulok: export/import}
\begin{lstlisting}[style=JavaScript]
// math.ts
export function add(a: number, b: number) {
return a + b;
}
// app.ts
import { add } from "./math.js";
console.log(add(2, 3));
\end{lstlisting}
\begin{itemize}
\item Modulokra bontással átláthatóbb és újrafelhasználhatóbb kódot kapsz.
\item NodeNext módban importnál gyakran .js kiterjesztést használsz.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Async/Await tipusokkal}
\begin{lstlisting}[style=JavaScript]
type User = { id: number; name: string };
async function fetchUser(id: number): Promise<User> {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error("Request failed");
return res.json();
}
\end{lstlisting}
\begin{itemize}
\item A Promise<User> egyértelműen jelzi a hívó kódnak a várt eredményt.
\item Hibakezelés nélkül API-hívásnál nehezen diagnosztizálható hibák jelennek meg.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Kulso csomagok tipizalasa}
\begin{lstlisting}[style=NodeJS]
npm install lodash
npm install -D @types/lodash
\end{lstlisting}
\begin{itemize}
\item Sok csomag már tartalmaz beépített típusokat.
\item Ha nem, akkor @types csomagot kell telepíteni.
\item Típusok nélkül külső csomag használata gyorsan any-hoz vezet.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Axios pelda valasz-tipussal}
\begin{lstlisting}[style=JavaScript]
import axios from "axios";
type Todo = { id: number; title: string; done: boolean };
async function getTodo(id: number): Promise<Todo> {
const r = await axios.get<Todo>(`/api/todos/${id}`);
return r.data;
}
\end{lstlisting}
\begin{itemize}
\item A <Todo> generic paraméterrel a válasz struktúrája már a hívás helyén ellenőrizhető.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Gyakorlati minta API-khoz}
\begin{itemize}
\item Definiálj külön típusokat a kérésekhez: Request DTO, Response DTO.
\item A hálózati réteget különítsd el service függvényekbe.
\item A komponensek csak a már tipizált adatot kapják.
\end{itemize}
\end{frame}
@@ -0,0 +1,67 @@
\section{Validáció}
\begin{frame}[fragile]{any vs unknown}
\begin{lstlisting}[style=JavaScript]
let loose: any = 123;
loose = "bármi"; // nincs ellenőrzés
let safe: unknown = JSON.parse('{"id":1}');
if (typeof safe === "object" && safe !== null) {
// itt már szűkíthető
}
\end{lstlisting}
\begin{itemize}
\item Az any kikapcsolja a típusellenőrzést, ezért csak átmeneti esetben használd.
\item Az unknown biztonságosabb, mert használat előtt kötelező ellenőrizni.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Futásidejű validáció Type Guarddal}
\begin{lstlisting}[style=JavaScript]
function isUser(v: unknown): v is { id: number; name: string } {
return (
typeof v === "object" &&
v !== null &&
"id" in v &&
"name" in v
);
}
\end{lstlisting}
\begin{itemize}
\item A TypeScript nem helyettesíti a futásidejű validációt.
\item Külső adatnál (API, localStorage, URL-paraméter) mindig ellenőrizz.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Strict mód bekapcsolása}
\begin{lstlisting}[style=JavaScript]
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}
\end{lstlisting}
\begin{itemize}
\item Ezek a beállítások kezdetben több hibát mutatnak, de hosszabb távon stabilabb kódot adnak.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Gyakori hibák}
\begin{itemize}
\item Túl sok any használata.
\item Null/undefined esetek figyelmen kívül hagyása.
\item Túl bonyolult típusok írása stabil alapok nélkül.
\item Típusok másolása utility típusok használata helyett.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Bevált gyakorlat röviden}
\begin{itemize}
\item Alapértelmezésben legyen bekapcsolva a strict mód.
\item Külső adatot mindig validálj.
\item Bonyolult típus helyett használj több kicsi, beszédes típust.
\item Legyen következetes kódstílus és linterbeállítás.
\end{itemize}
\end{frame}
@@ -0,0 +1,53 @@
\section{Tanulási Segédlet}
\begin{frame}[fragile]{4 hetes tanulási terv}
\begin{enumerate}
\item 1. hét: típusok, tömbök, objektumok, függvények.
\item 2. hét: unionök, narrowing, aliasok, interfészek.
\item 3. hét: generics, utility típusok, modulok.
\item 4. hét: aszinkron kód, API-típusok, futásidejű validáció.
\end{enumerate}
\begin{itemize}
\item Napi 45-60 perc folyamatos gyakorlás már jól látható fejlődést ad.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Projektötletek kezdőknek}
\begin{itemize}
\item Teendőlista-alkalmazás (CRUD) típusosan.
\item Egyszerű REST API-kliens.
\item Jegyzetelő CLI fájlba mentéssel.
\end{itemize}
\begin{itemize}
\item Cél: az alaptípusok és a függvényszerződések rutinszerű használata.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Projektötletek középhaladóknak}
\begin{itemize}
\item Modulokra bontott mini backend.
\item Validációs réteggel rendelkező API-kliens.
\item Kis NPM-csomag saját típusdefiníciókkal.
\end{itemize}
\begin{itemize}
\item Cél: valós, projekt-szerű struktúrában gondolkodni.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Mit erdemes mindenkepp megtanulni?}
\begin{itemize}
\item A típusinferencia értése.
\item A union + narrowing magabiztos használata.
\item A generics és utility típusok alapjai.
\item Futásidejű validáció külső adat esetén.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Önellenőrző kérdések minden modul után}
\begin{itemize}
\item Meg tudom magyarázni, mit vár és mit ad vissza a függvényem?
\item Használtam-e any-t ott, ahol az unknown biztonságosabb lenne?
\item Tudok-e példát mondani a union + narrowing együtt használatára?
\item Validáltam-e a külső adatot, mielőtt használtam?
\end{itemize}
\end{frame}
@@ -0,0 +1,57 @@
\section{Haladó Típuskezelés}
\begin{frame}[fragile]{keyof és indexed access}
\begin{lstlisting}[style=JavaScript]
type User = {
id: number;
name: string;
active: boolean;
};
type UserKey = keyof User; // "id" | "name" | "active"
type NameType = User["name"]; // string
\end{lstlisting}
\begin{itemize}
\item A keyof segítségével dinamikusan hivatkozhatsz egy típus kulcsaira.
\item Az indexed access típus pontosan kiolvassa egy mező típusát.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Mapped type alapminta}
\begin{lstlisting}[style=JavaScript]
type Optional<T> = {
[K in keyof T]?: T[K];
};
type ReadOnly<T> = {
readonly [K in keyof T]: T[K];
};
\end{lstlisting}
\begin{itemize}
\item Mapped type-pal meglévő típusból generálhatsz új, következetes szerkezetet.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Conditional type és infer}
\begin{lstlisting}[style=JavaScript]
type ElementType<T> = T extends (infer U)[] ? U : T;
type A = ElementType<string[]>; // string
type B = ElementType<number>; // number
\end{lstlisting}
\begin{itemize}
\item A conditional type típus-szintű "if" logikát ad.
\item Az infer kulcsszóval résztípusokat tudsz kinyerni.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Mikor használd ezeket?}
\begin{itemize}
\item Ha sok hasonló DTO típust kell karbantartanod.
\item Ha könyvtárszintű, újrafelhasználható típus-API-t építesz.
\item Ha ismétlődő kézi típusmásolást látsz a projektben.
\end{itemize}
\begin{alertblock}{Szabály}
Haladó típust csak akkor vezess be, ha egyszerűbbé teszi a használatot.
\end{alertblock}
\end{frame}
@@ -0,0 +1,60 @@
\section{Osztályok és Architekturális Minták}
\begin{frame}[fragile]{Osztályok TypeScriptben}
\begin{lstlisting}[style=JavaScript]
class Account {
constructor(
public owner: string,
private balance: number
) {}
deposit(amount: number): void {
this.balance += amount;
}
getBalance(): number {
return this.balance;
}
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Interface + osztály együtt}
\begin{lstlisting}[style=JavaScript]
interface Logger {
log(message: string): void;
}
class ConsoleLogger implements Logger {
log(message: string): void {
console.log(message);
}
}
\end{lstlisting}
\begin{itemize}
\item Az interface szerződés, az osztály ennek konkrét megvalósítása.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Rétegezett felépítés röviden}
\begin{itemize}
\item domain: üzleti logika és modellek
\item service: alkalmazási műveletek
\item infrastructure: API, adatbázis, külső kapcsolatok
\item ui/controller: bemenet-kimenet kezelése
\end{itemize}
\begin{block}{Előny}
A jól rétegzett struktúra könnyebben tesztelhető és bővíthető.
\end{block}
\end{frame}
\begin{frame}[fragile]{Gyakori tervezési hiba}
\begin{itemize}
\item Minden logika egyetlen fájlban van.
\item Az API-hívás közvetlenül a komponensben történik típusos határ nélkül.
\item A validáció és üzleti szabályok keverednek.
\end{itemize}
\begin{itemize}
\item Megoldás: rétegek szétválasztása és tiszta típushatárok.
\end{itemize}
\end{frame}
@@ -0,0 +1,42 @@
\section{Hibakeresés és Fordítói Üzenetek}
\begin{frame}[fragile]{Hogyan olvasd a TypeScript hibákat?}
\begin{itemize}
\item Először a hiba kódját nézd (pl. TS2322).
\item Utána nézd meg: "mit kaptam" és "mit vár a típus".
\item A hiba gyakran a hívási pontnál jelenik meg, de az ok lehet korábban.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Tipikus hiba: TS2322}
\begin{lstlisting}[style=JavaScript]
let count: number;
count = "10"; // TS2322
\end{lstlisting}
\begin{itemize}
\item Jelentés: nem kompatibilis típus-hozzárendelés.
\item Javítás: konvertálj (Number("10")) vagy javítsd az adatforrást.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Tipikus hiba: TS2532}
\begin{lstlisting}[style=JavaScript]
type User = { name?: string };
const u: User = {};
console.log(u.name.toUpperCase()); // TS2532
\end{lstlisting}
\begin{itemize}
\item Jelentés: az érték lehet undefined.
\item Javítás: ellenőrzés (if), optional chaining (u.name?.toUpperCase()).
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Gyakorlati hibakeresési rutin}
\begin{enumerate}
\item Szűkítsd a hibát a legkisebb reprodukálható példára.
\item Ellenőrizd a bemenet tényleges futásidejű értékét.
\item Egyeztesd a runtime adatot a deklarált típussal.
\item Írj tesztet, hogy a hiba ne térjen vissza.
\end{enumerate}
\end{frame}
@@ -0,0 +1,50 @@
\section{Gyakorlóműhely}
\begin{frame}[fragile]{Feladat 1: Típusos szűrés}
\begin{block}{Feladat}
Készíts függvényt, amely egy vegyes (string | number) tömbből csak a számokat adja vissza.
\end{block}
\begin{lstlisting}[style=JavaScript]
function onlyNumbers(values: Array<string | number>): number[] {
return values.filter((v): v is number => typeof v === "number");
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Feladat 2: Generic API válasz}
\begin{block}{Feladat}
Definiálj újrafelhasználható API-válasz típust data, ok és error mezőkkel.
\end{block}
\begin{lstlisting}[style=JavaScript]
type ApiResponse<T> = {
data: T;
ok: boolean;
error?: string;
};
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Feladat 3: Runtime validáció}
\begin{block}{Feladat}
Írj type guardot, amely ellenőrzi, hogy az adat Todo-e.
\end{block}
\begin{lstlisting}[style=JavaScript]
type Todo = { id: number; title: string; done: boolean };
function isTodo(v: unknown): v is Todo {
return (
typeof v === "object" && v !== null &&
"id" in v && "title" in v && "done" in v
);
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Értékelési szempontok}
\begin{itemize}
\item Típusbiztonság: nincs felesleges any.
\item Olvashatóság: beszédes típus- és függvénynév.
\item Hibatűrés: külső adat validálása.
\item Bővíthetőség: új mező esetén is tiszta marad a kód.
\end{itemize}
\end{frame}
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
\documentclass[usenames,dvipsnames,aspectratio=169]{beamer}
\usepackage{./common/webfejl}
% Automatikus frame törés engedélyezése túl hosszú tartalomnál
\setbeamertemplate{frametitle continuation}[from second][\insertcontinuationcountroman]
\title[Webtechnológia és webalkalmazás-fejlesztés - TypeScript]{Webtechnológia és webalkalmazás-fejlesztés - TypeScript}
\subtitle{TypeScript}
\begin{document}
\begin{frame}[plain]
\titlepage
\logoalul
\end{frame}
\input{typescript_content.tex}
\end{document}
+15
View File
@@ -0,0 +1,15 @@
% TypeScript tananyag index fajl
% Ez a fajl csak osszefuzi a szekciokat kezdotol kozepes szintig.
\input{sections/01_intro_and_setup.tex}
\input{sections/02_basic_types.tex}
\input{sections/03_functions_and_unions.tex}
\input{sections/04_alias_interface_objects.tex}
\input{sections/05_generics_and_utility_types.tex}
\input{sections/06_modules_async_and_api.tex}
\input{sections/07_validation_and_best_practices.tex}
\input{sections/08_learning_path_and_practice.tex}
\input{sections/09_advanced_types.tex}
\input{sections/10_oop_and_architecture.tex}
\input{sections/11_debugging_and_error_reading.tex}
\input{sections/12_practice_workshop.tex}