[{"data":1,"prerenderedAt":19753},["ShallowReactive",2],{"navigation_docs":3,"-web-development-typescript-advanced-interfaces-classes":3728,"-web-development-typescript-advanced-interfaces-classes-surround":19748},[4,1707,1912,2366,2547,2673,2880,3002,3052,3109,3143,3269,3346,3360,3495,3512,3525,3671,3724],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"C#","i-devicon-csharp","\u002Fcsharp","01.csharp",[10,13,60,90,120,202,219,253,379,404,457,650,1364,1654,1703],{"title":11,"path":7,"stem":12},"C# та .NET","01.csharp\u002Findex",{"title":14,"icon":15,"path":16,"stem":17,"children":18,"page":59},"Fundamentals","i-lucide-book-open","\u002Fcsharp\u002Ffundamentals","01.csharp\u002F01.fundamentals",[19,23,27,31,35,39,43,47,51,55],{"title":20,"path":21,"stem":22},"Вступ до екосистеми .NET","\u002Fcsharp\u002Ffundamentals\u002Fintroduction-to-ecosystem","01.csharp\u002F01.fundamentals\u002F01.introduction-to-ecosystem",{"title":24,"path":25,"stem":26},"Структура програми на C#","\u002Fcsharp\u002Ffundamentals\u002Fprogram-structure","01.csharp\u002F01.fundamentals\u002F02.program-structure",{"title":28,"path":29,"stem":30},"Змінні та Типи Даних","\u002Fcsharp\u002Ffundamentals\u002Fvariables-data-types","01.csharp\u002F01.fundamentals\u002F03.variables-data-types",{"title":32,"path":33,"stem":34},"Масиви","\u002Fcsharp\u002Ffundamentals\u002Farrays","01.csharp\u002F01.fundamentals\u002F04.arrays",{"title":36,"path":37,"stem":38},"Strings & Text Handling","\u002Fcsharp\u002Ffundamentals\u002Fstrings-text-handling","01.csharp\u002F01.fundamentals\u002F05.strings-text-handling",{"title":40,"path":41,"stem":42},"Дати і Час","\u002Fcsharp\u002Ffundamentals\u002Fdates-time-handling","01.csharp\u002F01.fundamentals\u002F06.dates-time-handling",{"title":44,"path":45,"stem":46},"Потік Керування","\u002Fcsharp\u002Ffundamentals\u002Fcontrol-flow","01.csharp\u002F01.fundamentals\u002F07.control-flow",{"title":48,"path":49,"stem":50},"Методи","\u002Fcsharp\u002Ffundamentals\u002Fmethods","01.csharp\u002F01.fundamentals\u002F08.methods",{"title":52,"path":53,"stem":54},"Основи Відлагодження","\u002Fcsharp\u002Ffundamentals\u002Fdebugging-basics","01.csharp\u002F01.fundamentals\u002F09.debugging-basics",{"title":56,"path":57,"stem":58},"Інтерактивна Консоль (Classic)","\u002Fcsharp\u002Ffundamentals\u002Finteractive-console","01.csharp\u002F01.fundamentals\u002F10.interactive-console",false,{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":59},"OOP","i-lucide-box","\u002Fcsharp\u002Foop","01.csharp\u002F02.oop",[66,70,74,78,82,86],{"title":67,"path":68,"stem":69},"Package Management (Управління Пакетами)","\u002Fcsharp\u002Foop\u002Fpackage-management","01.csharp\u002F02.oop\u002F01.package-management",{"title":71,"path":72,"stem":73},"Класи та Об'єкти","\u002Fcsharp\u002Foop\u002Fclasses-objects","01.csharp\u002F02.oop\u002F02.classes-objects",{"title":75,"path":76,"stem":77},"Властивості та Поля","\u002Fcsharp\u002Foop\u002Fproperties-fields","01.csharp\u002F02.oop\u002F03.properties-fields",{"title":79,"path":80,"stem":81},"Стовпи ООП","\u002Fcsharp\u002Foop\u002Foop-pillars","01.csharp\u002F02.oop\u002F04.oop-pillars",{"title":83,"path":84,"stem":85},"Advanced Types","\u002Fcsharp\u002Foop\u002Fadvanced-types","01.csharp\u002F02.oop\u002F05.advanced-types",{"title":87,"path":88,"stem":89},"Namespaces (Простори Імен)","\u002Fcsharp\u002Foop\u002Fnamespaces","01.csharp\u002F02.oop\u002F06.namespaces",{"title":91,"icon":92,"path":93,"stem":94,"children":95,"page":59},"Advanced Core","i-lucide-zap","\u002Fcsharp\u002Fadvanced-core","01.csharp\u002F03.advanced-core",[96,100,104,108,112,116],{"title":97,"path":98,"stem":99},"Generics (Узагальнення)","\u002Fcsharp\u002Fadvanced-core\u002Fgenerics","01.csharp\u002F03.advanced-core\u002F01.generics",{"title":101,"path":102,"stem":103},"Делегати, Події та Лямбда-вирази","\u002Fcsharp\u002Fadvanced-core\u002Fdelegates-events-lambdas","01.csharp\u002F03.advanced-core\u002F02.delegates-events-lambdas",{"title":105,"path":106,"stem":107},"Interfaces Deep Dive (Інтерфейси: Поглиблений Розгляд)","\u002Fcsharp\u002Fadvanced-core\u002Finterfaces-deep-dive","01.csharp\u002F03.advanced-core\u002F03.interfaces-deep-dive",{"title":109,"path":110,"stem":111},"Обробка Винятків","\u002Fcsharp\u002Fadvanced-core\u002Fexception-handling","01.csharp\u002F03.advanced-core\u002F04.exception-handling",{"title":113,"path":114,"stem":115},"Pattern Matching","\u002Fcsharp\u002Fadvanced-core\u002Fpattern-matching","01.csharp\u002F03.advanced-core\u002F05.pattern-matching",{"title":117,"path":118,"stem":119},"Додаткові Можливості C#","\u002Fcsharp\u002Fadvanced-core\u002Fadditional-features","01.csharp\u002F03.advanced-core\u002F06.additional-features",{"title":121,"icon":122,"path":123,"stem":124,"children":125,"page":59},"Architecture Best Practices","i-lucide-building-2","\u002Fcsharp\u002Farchitecture-best-practices","01.csharp\u002F04.architecture-best-practices",[126,130,149,153,157,161,165,169],{"title":127,"path":128,"stem":129},"Software Design Principles (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fsoftware-design-principles","01.csharp\u002F04.architecture-best-practices\u002F01.software-design-principles",{"title":131,"icon":132,"path":133,"stem":134,"children":135,"page":59},"Design Patterns","i-lucide-folder","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns",[136],{"title":137,"icon":132,"path":138,"stem":139,"children":140,"page":59},"Creational","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational",[141,145],{"title":142,"path":143,"stem":144},"Singleton (Одинак)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fsingleton","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F01.singleton",{"title":146,"path":147,"stem":148},"Builder (Будівельник)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fbuilder","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F02.builder",{"title":150,"path":151,"stem":152},"Building Professional CLIs","\u002Fcsharp\u002Farchitecture-best-practices\u002Fbuilding-professional-clis","01.csharp\u002F04.architecture-best-practices\u002F03.building-professional-clis",{"title":154,"path":155,"stem":156},"Validation & Flow Control","\u002Fcsharp\u002Farchitecture-best-practices\u002Fvalidation-flow-control","01.csharp\u002F04.architecture-best-practices\u002F04.validation-flow-control",{"title":158,"path":159,"stem":160},"The Modern .NET Host (Microsoft.Extensions)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fmodern-dotnet-host","01.csharp\u002F04.architecture-best-practices\u002F05.modern-dotnet-host",{"title":162,"path":163,"stem":164},"Data Mapper: Repository та DAO патерни (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part1","01.csharp\u002F04.architecture-best-practices\u002F06.data-mapper-part1",{"title":166,"path":167,"stem":168},"Data Mapper: Repository та DAO патерни (Частина 2)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part2","01.csharp\u002F04.architecture-best-practices\u002F07.data-mapper-part2",{"title":170,"icon":132,"path":171,"stem":172,"children":173,"page":59},"Di Ioc","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc",[174,178,182,186,190,194,198],{"title":175,"path":176,"stem":177},"Проблема залежностей та Інверсія Контролю","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fthe-dependency-problem","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F01.the-dependency-problem",{"title":179,"path":180,"stem":181},"Будуємо власний Service Container","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fbuild-your-own-container","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F02.build-your-own-container",{"title":183,"path":184,"stem":185},"Service Locator: Паттерн та Анти-паттерн","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-locator-pattern","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F03.service-locator-pattern",{"title":187,"path":188,"stem":189},"Паттерни Dependency Injection","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdependency-injection-patterns","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F04.dependency-injection-patterns",{"title":191,"path":192,"stem":193},"Microsoft DI: IServiceCollection та IServiceProvider","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fmicrosoft-di-deep-dive","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F05.microsoft-di-deep-dive",{"title":195,"path":196,"stem":197},"Service Lifetimes та Scopes","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-lifetimes-and-scopes","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F06.service-lifetimes-and-scopes",{"title":199,"path":200,"stem":201},"DI Анти-паттерни та Найкращі Практики","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdi-anti-patterns-and-best-practices","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F07.di-anti-patterns-and-best-practices",{"title":203,"icon":132,"path":204,"stem":205,"children":206,"page":59},"Standard Library","\u002Fcsharp\u002Fstandard-library","01.csharp\u002F05.standard-library",[207,211,215],{"title":208,"path":209,"stem":210},"Collections (Колекції)","\u002Fcsharp\u002Fstandard-library\u002Fcollections","01.csharp\u002F05.standard-library\u002F01.collections",{"title":212,"path":213,"stem":214},"High Performance Types (Високопродуктивні Типи)","\u002Fcsharp\u002Fstandard-library\u002Fhigh-performance-types","01.csharp\u002F05.standard-library\u002F02.high-performance-types",{"title":216,"path":217,"stem":218},"LINQ (Language Integrated Query)","\u002Fcsharp\u002Fstandard-library\u002Flinq","01.csharp\u002F05.standard-library\u002F03.linq",{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":59},"System Internals Concurrency","i-lucide-server","\u002Fcsharp\u002Fsystem-internals-concurrency","01.csharp\u002F06.system-internals-concurrency",[225,229,233,237,241,245,249],{"title":226,"path":227,"stem":228},"Memory Management","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmemory-management","01.csharp\u002F06.system-internals-concurrency\u002F01.memory-management",{"title":230,"path":231,"stem":232},"Reflection API: System.Type та Метадані","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Freflection-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F02.reflection-fundamentals",{"title":234,"path":235,"stem":236},"Attributes та Dynamic Language Runtime","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fattributes-dynamic","01.csharp\u002F06.system-internals-concurrency\u002F03.attributes-dynamic",{"title":238,"path":239,"stem":240},"Expression Trees: Швидка Альтернатива Рефлексії","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fexpression-trees-compiled","01.csharp\u002F06.system-internals-concurrency\u002F04.expression-trees-compiled",{"title":242,"path":243,"stem":244},"Source Generators: Compile-Time Code Generation","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsource-generators","01.csharp\u002F06.system-internals-concurrency\u002F05.source-generators",{"title":246,"path":247,"stem":248},"Multithreading Fundamentals","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmultithreading-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F06.multithreading-fundamentals",{"title":250,"path":251,"stem":252},"Synchronization Primitives","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsynchronization-primitives","01.csharp\u002F06.system-internals-concurrency\u002F07.synchronization-primitives",{"title":254,"icon":255,"path":256,"stem":257,"children":258,"page":59},"System Programming Windows","i-lucide-cpu","\u002Fcsharp\u002Fsystem-programming-windows","01.csharp\u002F07.system-programming-windows",[259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335,339,343,347,351,355,359,363,367,371,375],{"title":260,"path":261,"stem":262},"Як Працює Операційна Система","\u002Fcsharp\u002Fsystem-programming-windows\u002Fhow-os-works","01.csharp\u002F07.system-programming-windows\u002F01.how-os-works",{"title":264,"path":265,"stem":266},"Процеси в .NET — API та Запуск","\u002Fcsharp\u002Fsystem-programming-windows\u002Fprocesses-in-dotnet","01.csharp\u002F07.system-programming-windows\u002F02.processes-in-dotnet",{"title":268,"path":269,"stem":270},"Процеси в .NET — IPC та Міжпроцесна Комунікація","\u002Fcsharp\u002Fsystem-programming-windows\u002F02a.processes-ipc","01.csharp\u002F07.system-programming-windows\u002F02a.processes-ipc",{"title":272,"path":273,"stem":274},"Application Domains та Збірки — AppDomain і AssemblyLoadContext","\u002Fcsharp\u002Fsystem-programming-windows\u002Fappdomains-assemblies","01.csharp\u002F07.system-programming-windows\u002F03.appdomains-assemblies",{"title":276,"path":277,"stem":278},"Application Domains та Збірки — Plug-in Система з Hot-Reload","\u002Fcsharp\u002Fsystem-programming-windows\u002F03a.appdomains-plugin-system","01.csharp\u002F07.system-programming-windows\u002F03a.appdomains-plugin-system",{"title":280,"path":281,"stem":282},"Потоки — Основи та API Thread","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-fundamentals","01.csharp\u002F07.system-programming-windows\u002F04.thread-fundamentals",{"title":284,"path":285,"stem":286},"Потоки — Lifecycle, Пріоритети та Безпечне Завершення","\u002Fcsharp\u002Fsystem-programming-windows\u002F04a.thread-lifecycle-priorities","01.csharp\u002F07.system-programming-windows\u002F04a.thread-lifecycle-priorities",{"title":288,"path":289,"stem":290},"Проблеми Спільного Стану — Race Condition та Data Race","\u002Fcsharp\u002Fsystem-programming-windows\u002Fshared-state-problems","01.csharp\u002F07.system-programming-windows\u002F05.shared-state-problems",{"title":292,"path":293,"stem":294},"Проблеми Спільного Стану — Memory Model та volatile","\u002Fcsharp\u002Fsystem-programming-windows\u002F05a.shared-state-memory-model","01.csharp\u002F07.system-programming-windows\u002F05a.shared-state-memory-model",{"title":296,"path":297,"stem":298},"Синхронізація — Monitor, lock та еволюція примітивів","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-fundamentals","01.csharp\u002F07.system-programming-windows\u002F06.synchronization-fundamentals",{"title":300,"path":301,"stem":302},"Синхронізація — Наскрізний Приклад та Deadlock Detection","\u002Fcsharp\u002Fsystem-programming-windows\u002F06a.synchronization-walkthrough","01.csharp\u002F07.system-programming-windows\u002F06a.synchronization-walkthrough",{"title":304,"path":305,"stem":306},"Синхронізація — Mutex, Semaphore та Event-Based Primitives","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-advanced","01.csharp\u002F07.system-programming-windows\u002F07.synchronization-advanced",{"title":308,"path":309,"stem":310},"Синхронізація — Interlocked, Volatile та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002F07a.synchronization-advanced-walkthrough","01.csharp\u002F07.system-programming-windows\u002F07a.synchronization-advanced-walkthrough",{"title":312,"path":313,"stem":314},"Interlocked, CAS та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002Finterlocked-cas-lockfree","01.csharp\u002F07.system-programming-windows\u002F08.interlocked-cas-lockfree",{"title":316,"path":317,"stem":318},"Volatile, Memory Model та Spinning","\u002Fcsharp\u002Fsystem-programming-windows\u002F08a.volatile-memory-model","01.csharp\u002F07.system-programming-windows\u002F08a.volatile-memory-model",{"title":320,"path":321,"stem":322},"ThreadPool — Пул Потоків для Ефективного Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-pool","01.csharp\u002F07.system-programming-windows\u002F09.thread-pool",{"title":324,"path":325,"stem":326},"ThreadPool — Просунуті Сценарії та Внутрішня Будова","\u002Fcsharp\u002Fsystem-programming-windows\u002F09a.thread-pool-advanced","01.csharp\u002F07.system-programming-windows\u002F09a.thread-pool-advanced",{"title":328,"path":329,"stem":330},"Concurrent та Immutable Collections","\u002Fcsharp\u002Fsystem-programming-windows\u002Fconcurrent-collections","01.csharp\u002F07.system-programming-windows\u002F10.concurrent-collections",{"title":332,"path":333,"stem":334},"TPL, Task та Композиція — Від Thread до Task","\u002Fcsharp\u002Fsystem-programming-windows\u002Ftpl-parallel-plinq","01.csharp\u002F07.system-programming-windows\u002F11.tpl-parallel-plinq",{"title":336,"path":337,"stem":338},"Parallel Class та PLINQ — Data Parallelism","\u002Fcsharp\u002Fsystem-programming-windows\u002F11a.tpl-parallel-plinq-advanced","01.csharp\u002F07.system-programming-windows\u002F11a.tpl-parallel-plinq-advanced",{"title":340,"path":341,"stem":342},"Async\u002FAwait — Фундамент Асинхронного Програмування","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-fundamentals","01.csharp\u002F07.system-programming-windows\u002F12.async-fundamentals",{"title":344,"path":345,"stem":346},"SynchronizationContext та ConfigureAwait — Контекст Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-context-configureawait","01.csharp\u002F07.system-programming-windows\u002F13.async-context-configureawait",{"title":348,"path":349,"stem":350},"Async — Просунуті Паттерни","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-advanced","01.csharp\u002F07.system-programming-windows\u002F14.async-advanced",{"title":352,"path":353,"stem":354},"System.Threading.Channels — Async Producer-Consumer","\u002Fcsharp\u002Fsystem-programming-windows\u002Fchannels","01.csharp\u002F07.system-programming-windows\u002F15.channels",{"title":356,"path":357,"stem":358},"Асинхронна Синхронізація","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-synchronization","01.csharp\u002F07.system-programming-windows\u002F16.async-synchronization",{"title":360,"path":361,"stem":362},"Unsafe Code та Вказівники","\u002Fcsharp\u002Fsystem-programming-windows\u002Funsafe-code","01.csharp\u002F07.system-programming-windows\u002F17.unsafe-code",{"title":364,"path":365,"stem":366},"P\u002FInvoke та Windows API — Міст між .NET та Native Code","\u002Fcsharp\u002Fsystem-programming-windows\u002Fpinvoke-winapi","01.csharp\u002F07.system-programming-windows\u002F18.pinvoke-winapi",{"title":368,"path":369,"stem":370},"Реєстр Windows — Центральна База Конфігурації Системи","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-registry","01.csharp\u002F07.system-programming-windows\u002F19.windows-registry",{"title":372,"path":373,"stem":374},"Windows Hooks, Hotkeys та Services — Глибока Інтеграція з ОС","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-hooks-services","01.csharp\u002F07.system-programming-windows\u002F20.windows-hooks-services",{"title":376,"path":377,"stem":378},"Системне Програмування C# (Windows) — 07.system-programming-windows","\u002Fcsharp\u002Fsystem-programming-windows\u002Fimplementation_plan","01.csharp\u002F07.system-programming-windows\u002Fimplementation_plan",{"title":380,"icon":132,"path":381,"stem":382,"children":383,"page":59},"Io","\u002Fcsharp\u002Fio","01.csharp\u002F08.io",[384,388,392,396,400],{"title":385,"path":386,"stem":387},"8.1.1. Основи роботи з файловою системою","\u002Fcsharp\u002Fio\u002Ffile-system-basics","01.csharp\u002F08.io\u002F01.file-system-basics",{"title":389,"path":390,"stem":391},"8.1.2. Потоки (Streams) та Серіалізація Даних","\u002Fcsharp\u002Fio\u002Fstreams-serialization","01.csharp\u002F08.io\u002F02.streams-serialization",{"title":393,"path":394,"stem":395},"8.2.1. JSON Serialization з System.Text.Json","\u002Fcsharp\u002Fio\u002Fjson-serialization","01.csharp\u002F08.io\u002F03.json-serialization",{"title":397,"path":398,"stem":399},"8.2.2. XML Serialization та LINQ to XML","\u002Fcsharp\u002Fio\u002Fxml-serialization","01.csharp\u002F08.io\u002F04.xml-serialization",{"title":401,"path":402,"stem":403},"8.2.3. Binary Serialization: MessagePack та Protocol Buffers","\u002Fcsharp\u002Fio\u002Fbinary-serialization","01.csharp\u002F08.io\u002F05.binary-serialization",{"title":405,"icon":132,"path":406,"stem":407,"children":408,"page":59},"Ado Net","\u002Fcsharp\u002Fado-net","01.csharp\u002F09.ado-net",[409,413,417,421,425,429,433,437,441,445,449,453],{"title":410,"path":411,"stem":412},"9.1. Введення в ADO.NET","\u002Fcsharp\u002Fado-net\u002Fintroduction-to-adonet","01.csharp\u002F09.ado-net\u002F01.introduction-to-adonet",{"title":414,"path":415,"stem":416},"9.2. Клас DbConnection — з'єднання з базою даних","\u002Fcsharp\u002Fado-net\u002Fconnection","01.csharp\u002F09.ado-net\u002F02.connection",{"title":418,"path":419,"stem":420},"9.3. Клас DbCommand — виконання SQL-запитів","\u002Fcsharp\u002Fado-net\u002Fcommand-and-queries","01.csharp\u002F09.ado-net\u002F03.command-and-queries",{"title":422,"path":423,"stem":424},"9.4. Клас DbDataReader — ефективне читання даних","\u002Fcsharp\u002Fado-net\u002Fdatareader","01.csharp\u002F09.ado-net\u002F04.datareader",{"title":426,"path":427,"stem":428},"9.5. Параметризовані запити та захист від SQL Injection","\u002Fcsharp\u002Fado-net\u002Fparameters-and-sql-injection","01.csharp\u002F09.ado-net\u002F05.parameters-and-sql-injection",{"title":430,"path":431,"stem":432},"9.6. Транзакції в ADO.NET","\u002Fcsharp\u002Fado-net\u002Ftransactions","01.csharp\u002F09.ado-net\u002F06.transactions",{"title":434,"path":435,"stem":436},"9.7. DbProviderFactory — провайдер-незалежний код","\u002Fcsharp\u002Fado-net\u002Fprovider-factory","01.csharp\u002F09.ado-net\u002F07.provider-factory",{"title":438,"path":439,"stem":440},"9.8. Асинхронний доступ до даних","\u002Fcsharp\u002Fado-net\u002Fasync-data-access","01.csharp\u002F09.ado-net\u002F08.async-data-access",{"title":442,"path":443,"stem":444},"9.9. Від'єднаний режим: DataSet, DataTable, DataRow","\u002Fcsharp\u002Fado-net\u002Fdisconnected-mode-dataset","01.csharp\u002F09.ado-net\u002F09.disconnected-mode-dataset",{"title":446,"path":447,"stem":448},"9.10. DataAdapter — міст між DataSet та базою даних","\u002Fcsharp\u002Fado-net\u002Fdata-adapter","01.csharp\u002F09.ado-net\u002F10.data-adapter",{"title":450,"path":451,"stem":452},"9.11. Data Mapper та Repository: Архітектура доступу до даних","\u002Fcsharp\u002Fado-net\u002Fdata-mapper-repository","01.csharp\u002F09.ado-net\u002F11.data-mapper-repository",{"title":454,"path":455,"stem":456},"9.12. Identity Map, Unit of Work та Specification Pattern","\u002Fcsharp\u002Fado-net\u002Fadvanced-patterns","01.csharp\u002F09.ado-net\u002F12.advanced-patterns",{"title":458,"icon":255,"path":459,"stem":460,"children":461,"page":59},"Ef Core","\u002Fcsharp\u002Fef-core","01.csharp\u002F10.ef-core",[462,466,470,474,478,482,486,490,494,498,502,506,510,514,518,522,526,532,538,542,546,550,554,558,562,566,570,574,578,582,586,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646],{"title":463,"path":464,"stem":465},"Що таке ORM? Від SQL до об'єктів","\u002Fcsharp\u002Fef-core\u002Fwhat-is-orm","01.csharp\u002F10.ef-core\u002F01.what-is-orm",{"title":467,"path":468,"stem":469},"Перший проєкт — від нуля до CRUD","\u002Fcsharp\u002Fef-core\u002Ffirst-project","01.csharp\u002F10.ef-core\u002F02.first-project",{"title":471,"path":472,"stem":473},"DbContext — Серце EF Core","\u002Fcsharp\u002Fef-core\u002Fdbcontext-deep-dive","01.csharp\u002F10.ef-core\u002F03.dbcontext-deep-dive",{"title":475,"path":476,"stem":477},"Провайдери баз даних — Архітектура та Вибір СУБД","\u002Fcsharp\u002Fef-core\u002Fdatabase-providers","01.csharp\u002F10.ef-core\u002F04.database-providers",{"title":479,"path":480,"stem":481},"Конвенції EF Core — Магія без конфігурації","\u002Fcsharp\u002Fef-core\u002Fconventions","01.csharp\u002F10.ef-core\u002F05.conventions",{"title":483,"path":484,"stem":485},"Fluent API та Data Annotations — Явна конфігурація моделі","\u002Fcsharp\u002Fef-core\u002Ffluent-api-vs-annotations","01.csharp\u002F10.ef-core\u002F06.fluent-api-vs-annotations",{"title":487,"path":488,"stem":489},"Зв'язки — One-to-One та One-to-Many","\u002Fcsharp\u002Fef-core\u002Frelationships-basics","01.csharp\u002F10.ef-core\u002F07.relationships-basics",{"title":491,"path":492,"stem":493},"Зв'язки Advanced — Many-to-Many та Складні Сценарії","\u002Fcsharp\u002Fef-core\u002Frelationships-advanced","01.csharp\u002F10.ef-core\u002F08.relationships-advanced",{"title":495,"path":496,"stem":497},"Властивості — Типи, Конвертери, Компаратори (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part1","01.csharp\u002F10.ef-core\u002F09.property-configuration-part1",{"title":499,"path":500,"stem":501},"Властивості — Value Comparers, Generators, Shadow Properties (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part2","01.csharp\u002F10.ef-core\u002F09.property-configuration-part2",{"title":503,"path":504,"stem":505},"Складні типи — Owned Types та Complex Types (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part1","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part1",{"title":507,"path":508,"stem":509},"Складні типи — Complex Types, Keyless Entities, Порівняння (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part2","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part2",{"title":511,"path":512,"stem":513},"JSON Columns — Складні дані у JSON (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part1","01.csharp\u002F10.ef-core\u002F11.json-columns-part1",{"title":515,"path":516,"stem":517},"JSON Columns — Value Comparers, Індекси, Провайдери (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part2","01.csharp\u002F10.ef-core\u002F11.json-columns-part2",{"title":519,"path":520,"stem":521},"Успадкування — Абстрактні класи та TPH (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finheritance-part1","01.csharp\u002F10.ef-core\u002F12.inheritance-part1",{"title":523,"path":524,"stem":525},"Успадкування — TPT, TPC та Порівняння Стратегій (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finheritance-part2","01.csharp\u002F10.ef-core\u002F12.inheritance-part2",{"title":527,"path":528,"stem":529,"children":530},"Індекси, Обмеження та Схема (Частина 1)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part1","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part1",[531],{"title":527,"path":528,"stem":529},{"title":533,"path":534,"stem":535,"children":536},"Індекси, Обмеження та Схема (Частина 2)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part2","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part2",[537],{"title":533,"path":534,"stem":535},{"title":539,"path":540,"stem":541},"Seed Data — Початкові Дані (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fseeding-part1","01.csharp\u002F10.ef-core\u002F14.seeding-part1",{"title":543,"path":544,"stem":545},"Seed Data — SQL-скрипти, Bogus та Стратегії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fseeding-part2","01.csharp\u002F10.ef-core\u002F14.seeding-part2",{"title":547,"path":548,"stem":549},"Global Query Filters — Глобальні Фільтри (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part1","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part1",{"title":551,"path":552,"stem":553},"Global Query Filters — Підводні камені та Інтеграція (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part2","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part2",{"title":555,"path":556,"stem":557},"LINQ-запити в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part1","01.csharp\u002F10.ef-core\u002F16.linq-queries-part1",{"title":559,"path":560,"stem":561},"LINQ-запити в EF Core (Частина 2)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part2","01.csharp\u002F10.ef-core\u002F16.linq-queries-part2",{"title":563,"path":564,"stem":565},"Завантаження Пов'язаних Даних (Частина 1)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part1","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part1",{"title":567,"path":568,"stem":569},"Завантаження Пов'язаних Даних (Частина 2)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part2","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part2",{"title":571,"path":572,"stem":573},"Raw SQL, Views та Stored Procedures (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part1","01.csharp\u002F10.ef-core\u002F18.raw-sql-part1",{"title":575,"path":576,"stem":577},"Raw SQL — Stored Procedures, DbFunction та Bulk Operations (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part2","01.csharp\u002F10.ef-core\u002F18.raw-sql-part2",{"title":579,"path":580,"stem":581},"Продвинуті Запити — Compiled Queries, Bulk та Оптимізація (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part1","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part1",{"title":583,"path":584,"stem":585},"Продвинуті Запити — Query Tags, Bulk та Interceptors (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part2","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part2",{"title":587,"path":588,"stem":589},"Change Tracker — Відстеження Змін (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part1","01.csharp\u002F10.ef-core\u002F20.change-tracking-part1",{"title":591,"path":592,"stem":593},"Change Tracker — Графи Об'єктів та Disconnected (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part2","01.csharp\u002F10.ef-core\u002F20.change-tracking-part2",{"title":595,"path":596,"stem":597},"Збереження Даних та Транзакції (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part1","01.csharp\u002F10.ef-core\u002F21.saving-data-part1",{"title":599,"path":600,"stem":601},"Збереження Даних — Concurrency та Outbox (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part2","01.csharp\u002F10.ef-core\u002F21.saving-data-part2",{"title":603,"path":604,"stem":605},"Конкурентність та Блокування (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part1","01.csharp\u002F10.ef-core\u002F22.concurrency-part1",{"title":607,"path":608,"stem":609},"Конкурентність — Дедлоки та Queue Processing (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part2","01.csharp\u002F10.ef-core\u002F22.concurrency-part2",{"title":611,"path":612,"stem":613},"Міграції в EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part1","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part1",{"title":615,"path":616,"stem":617},"Міграції в EF Core — Основи (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part2","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part2",{"title":619,"path":620,"stem":621},"Міграції — Просунуті Сценарії (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part1","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part1",{"title":623,"path":624,"stem":625},"Міграції — Просунуті Сценарії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part2","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part2",{"title":627,"path":628,"stem":629},"Управління Схемою та Database-First (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part1","01.csharp\u002F10.ef-core\u002F25.schema-management-part1",{"title":631,"path":632,"stem":633},"Управління Схемою та Database-First (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part2","01.csharp\u002F10.ef-core\u002F25.schema-management-part2",{"title":635,"path":636,"stem":637},"Продуктивність EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fperformance-fundamentals-part1","01.csharp\u002F10.ef-core\u002F26.performance-fundamentals-part1",{"title":639,"path":640,"stem":641},"Interceptors в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part1","01.csharp\u002F10.ef-core\u002F29.interceptors-part1",{"title":643,"path":644,"stem":645},"Interceptors в EF Core — Connection, Transaction та Materialization (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part2","01.csharp\u002F10.ef-core\u002F29.interceptors-part2",{"title":647,"path":648,"stem":649},"План вивчення Entity Framework Core — Повний курс","\u002Fcsharp\u002Fef-core\u002Fimplementation_plan","01.csharp\u002F10.ef-core\u002Fimplementation_plan",{"title":651,"icon":652,"path":653,"stem":654,"children":655,"page":59},"ASP.NET","i-devicon-dotnetcore","\u002Fcsharp\u002Faspnet","01.csharp\u002F11.aspnet",[656,730,791,869,927,941,967,1057,1111,1182,1212,1289,1346],{"title":657,"icon":658,"path":659,"stem":660,"children":661,"page":59},"Minimal API","i-lucide-network","\u002Fcsharp\u002Faspnet\u002Fminimal-api","01.csharp\u002F11.aspnet\u002F01.minimal-api",[662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726],{"title":663,"path":664,"stem":665},"Вступ до ASP.NET та еволюція фреймворку","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fintroduction","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F01.introduction",{"title":667,"path":668,"stem":669},"Перший додаток на ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Ffirst-application","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F02.first-application",{"title":671,"path":672,"stem":673},"WebApplication, Builder та Dependency Injection","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fwebapplication-builder","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F03.webapplication-builder",{"title":675,"path":676,"stem":677},"Конвеєр запитів та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frequest-pipeline-middleware","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F04.request-pipeline-middleware",{"title":679,"path":680,"stem":681},"Маршрутизація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F05.routing-basics",{"title":683,"path":684,"stem":685},"Маршрутизація в ASP.NET Core: Розширені можливості","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F06.routing-advanced",{"title":687,"path":688,"stem":689},"Статичні файли в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-files","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F07.static-files",{"title":691,"path":692,"stem":693},"Статичні Активи: MapStaticAssets (ASP.NET Core 9.0)","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-assets","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F08.static-assets",{"title":695,"path":696,"stem":697},"Конфігурація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-fundamentals","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F09.configuration-fundamentals",{"title":699,"path":700,"stem":701},"Конфігурація: Паттерн Options","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-options","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F10.configuration-options",{"title":703,"path":704,"stem":705},"Логування в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F11.logging-basics",{"title":707,"path":708,"stem":709},"Логування: Serilog та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F12.logging-advanced",{"title":711,"path":712,"stem":713},"Управління станом: HttpContext.Items та Cookies","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstate-management","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F13.state-management",{"title":715,"path":716,"stem":717},"Стан сесії: Sessions","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fsession-state","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F14.session-state",{"title":719,"path":720,"stem":721},"Структура проєкту: від хаосу до архітектури","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fproject-structure","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F15.project-structure",{"title":723,"path":724,"stem":725},"Scalar у Minimal API: повний проєкт і Fluent OpenAPI","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fscalar-openapi-fluent","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F16.scalar-openapi-fluent",{"title":727,"path":728,"stem":729},"Swagger \u002F Swashbuckle у Minimal API: окремий класичний шлях","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fswagger-swashbuckle","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F17.swagger-swashbuckle",{"title":731,"icon":658,"path":732,"stem":733,"children":734,"page":59},"API","\u002Fcsharp\u002Faspnet\u002Fapi","01.csharp\u002F11.aspnet\u002F02.api",[735,739,743,747,751,755,759,763,767,771,775,779,783,787],{"title":736,"path":737,"stem":738},"Що таке API. Клієнт-серверна архітектура","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fwhat-is-api","01.csharp\u002F11.aspnet\u002F02.api\u002F01.what-is-api",{"title":740,"path":741,"stem":742},"Формати даних: JSON, XML, TOML та бінарні формати","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fdata-formats","01.csharp\u002F11.aspnet\u002F02.api\u002F02.data-formats",{"title":744,"path":745,"stem":746},"Парадигми API та концепція REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-paradigms-rest","01.csharp\u002F11.aspnet\u002F02.api\u002F03.api-paradigms-rest",{"title":748,"path":749,"stem":750},"HTTP-методи, статус-коди та заголовки","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fhttp-methods-status-codes","01.csharp\u002F11.aspnet\u002F02.api\u002F04.http-methods-status-codes",{"title":752,"path":753,"stem":754},"Організація HTTP API за принципами REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Frest-organizing","01.csharp\u002F11.aspnet\u002F02.api\u002F05.rest-organizing",{"title":756,"path":757,"stem":758},"Номенклатура URL та CRUD-операції","\u002Fcsharp\u002Faspnet\u002Fapi\u002Furl-nomenclature-crud","01.csharp\u002F11.aspnet\u002F02.api\u002F06.url-nomenclature-crud",{"title":760,"path":761,"stem":762},"Правила дизайну: іменування та стандарти","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-naming","01.csharp\u002F11.aspnet\u002F02.api\u002F07.api-design-naming",{"title":764,"path":765,"stem":766},"Валідація, ліміти та обробка помилок","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-validation","01.csharp\u002F11.aspnet\u002F02.api\u002F08.api-design-validation",{"title":768,"path":769,"stem":770},"Обробка помилок у Minimal API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Ferror-handling-http","01.csharp\u002F11.aspnet\u002F02.api\u002F09.error-handling-http",{"title":772,"path":773,"stem":774},"Ідемпотентність та синхронізація стану","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fidempotency-sync","01.csharp\u002F11.aspnet\u002F02.api\u002F10.idempotency-sync",{"title":776,"path":777,"stem":778},"Пагінація та організація списків","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fpagination-lists","01.csharp\u002F11.aspnet\u002F02.api\u002F11.pagination-lists",{"title":780,"path":781,"stem":782},"Безпека API, кешування та інтернаціоналізація","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fsecurity-auth","01.csharp\u002F11.aspnet\u002F02.api\u002F12.security-auth",{"title":784,"path":785,"stem":786},"Процес проєктування API та документування","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-process","01.csharp\u002F11.aspnet\u002F02.api\u002F13.api-design-process",{"title":788,"path":789,"stem":790},"OpenAPI: контракт, специфікація та документація API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fopenapi","01.csharp\u002F11.aspnet\u002F02.api\u002F14.openapi",{"title":792,"icon":793,"path":794,"stem":795,"children":796,"page":59},"Auth","i-lucide-shield-check","\u002Fcsharp\u002Faspnet\u002Fauth","01.csharp\u002F11.aspnet\u002F03.auth",[797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865],{"title":798,"path":799,"stem":800},"Основи аутентифікації та авторизації","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauth-fundamentals","01.csharp\u002F11.aspnet\u002F03.auth\u002F01.auth-fundamentals",{"title":802,"path":803,"stem":804},"JWT-аутентифікація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fjwt-authentication","01.csharp\u002F11.aspnet\u002F03.auth\u002F02.jwt-authentication",{"title":806,"path":807,"stem":808},"Авторизація: ролі, політики та resource-based доступ","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauthorization-policies","01.csharp\u002F11.aspnet\u002F03.auth\u002F03.authorization-policies",{"title":810,"path":811,"stem":812},"Cookie-аутентифікація та ASP.NET Core Identity","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcookie-auth-identity","01.csharp\u002F11.aspnet\u002F03.auth\u002F04.cookie-auth-identity",{"title":814,"path":815,"stem":816},"JWT + Refresh Tokens (HttpOnly Cookie)","\u002Fcsharp\u002Faspnet\u002Fauth\u002F04b.identity-auth-jwt","01.csharp\u002F11.aspnet\u002F03.auth\u002F04b.identity-auth-jwt",{"title":818,"path":819,"stem":820},"Identity: Підтвердження Email та Скидання Пароля","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-email-confirmation","01.csharp\u002F11.aspnet\u002F03.auth\u002F05.identity-email-confirmation",{"title":822,"path":823,"stem":824},"Identity: Двофакторна Аутентифікація (2FA)","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-two-factor","01.csharp\u002F11.aspnet\u002F03.auth\u002F06.identity-two-factor",{"title":826,"path":827,"stem":828},"Identity: Внутрішня Архітектура та Кастомізація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-internals","01.csharp\u002F11.aspnet\u002F03.auth\u002F07.identity-internals",{"title":830,"path":831,"stem":832},"OAuth 2.0 та зовнішні провайдери","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-external-providers","01.csharp\u002F11.aspnet\u002F03.auth\u002F08.oauth-external-providers",{"title":834,"path":835,"stem":836},"Безпека на практиці: CORS, HTTPS та захист від атак","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fsecurity-hardening","01.csharp\u002F11.aspnet\u002F03.auth\u002F09.security-hardening",{"title":838,"path":839,"stem":840},"Теорія OAuth 2.0: Поняття, Аналогії та Флоу","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-theory","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oauth-theory",{"title":842,"path":843,"stem":844},"OIDC, OAuth 2.0 та Keycloak в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foidc-keycloak","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oidc-keycloak",{"title":846,"path":847,"stem":848},"API Keys аутентифікація в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fapi-keys","01.csharp\u002F11.aspnet\u002F03.auth\u002F11.api-keys",{"title":850,"path":851,"stem":852},"Rate Limiting та Throttling в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frate-limiting","01.csharp\u002F11.aspnet\u002F03.auth\u002F12.rate-limiting",{"title":854,"path":855,"stem":856},"Refresh Token Rotation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frefresh-token-rotation","01.csharp\u002F11.aspnet\u002F03.auth\u002F13.refresh-token-rotation",{"title":858,"path":859,"stem":860},"Certificate Authentication та mTLS в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcertificate-auth","01.csharp\u002F11.aspnet\u002F03.auth\u002F14.certificate-auth",{"title":862,"path":863,"stem":864},"RBAC, ABAC та ReBAC в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frbac-abac-rebac","01.csharp\u002F11.aspnet\u002F03.auth\u002F15.rbac-abac-rebac",{"title":866,"path":867,"stem":868},"Multi-tenancy та ізоляція даних в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fmulti-tenancy","01.csharp\u002F11.aspnet\u002F03.auth\u002F16.multi-tenancy",{"title":870,"icon":871,"path":872,"stem":873,"children":874,"page":59},"Нотифікації","i-lucide-bell","\u002Fcsharp\u002Faspnet\u002Fnotifications","01.csharp\u002F11.aspnet\u002F04.notifications",[875,879,883,887,891,895,899,903,907,911,915,919,923],{"title":876,"path":877,"stem":878},"In-App нотифікації через базу даних","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fin-app-database-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F01.in-app-database-notifications",{"title":880,"path":881,"stem":882},"Polling: Регулярний запит оновлень","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fpolling","01.csharp\u002F11.aspnet\u002F04.notifications\u002F02.polling",{"title":884,"path":885,"stem":886},"Server-Sent Events: Однострімовий push від сервера","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fserver-sent-events","01.csharp\u002F11.aspnet\u002F04.notifications\u002F03.server-sent-events",{"title":888,"path":889,"stem":890},"WebSockets: Двостороннє з'єднання в реальному часі","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fwebsockets","01.csharp\u002F11.aspnet\u002F04.notifications\u002F04.websockets",{"title":892,"path":893,"stem":894},"SignalR: Абстракція над транспортами реального часу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fsignalr","01.csharp\u002F11.aspnet\u002F04.notifications\u002F05.signalr",{"title":896,"path":897,"stem":898},"Background Services: Фонові задачі в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fbackground-services","01.csharp\u002F11.aspnet\u002F04.notifications\u002F06.background-services",{"title":900,"path":901,"stem":902},"Web Push нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fweb-push","01.csharp\u002F11.aspnet\u002F04.notifications\u002F07.web-push",{"title":904,"path":905,"stem":906},"Email нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Femail-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F08.email-notifications",{"title":908,"path":909,"stem":910},"Порівняння підходів: Як вибрати правильну технологію нотифікацій","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fchoosing-the-right-approach","01.csharp\u002F11.aspnet\u002F04.notifications\u002F09.choosing-the-right-approach",{"title":912,"path":913,"stem":914},"Hangfire: Надійне планування фонових задач","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire","01.csharp\u002F11.aspnet\u002F04.notifications\u002F10.hangfire",{"title":916,"path":917,"stem":918},"Практика: Конвертація зображень у WebP через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-image-webp","01.csharp\u002F11.aspnet\u002F04.notifications\u002F11.hangfire-image-webp",{"title":920,"path":921,"stem":922},"Практика: Підготовка відео до HLS-стрімінгу через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-video-hls","01.csharp\u002F11.aspnet\u002F04.notifications\u002F12.hangfire-video-hls",{"title":924,"path":925,"stem":926},"Telegram-нотифікації: від одного повідомлення до масових розсилок і мульти-канального підходу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Ftelegram-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F13.telegram-notifications",{"title":928,"icon":929,"path":930,"stem":931,"children":932,"page":59},"Інтернаціоналізація","i-lucide-languages","\u002Fcsharp\u002Faspnet\u002Fi18n","01.csharp\u002F11.aspnet\u002F05.i18n",[933,937],{"title":934,"path":935,"stem":936},"Інтернаціоналізація (i18n) у Minimal API: від A до Я","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Finternationalization","01.csharp\u002F11.aspnet\u002F05.i18n\u002F01.internationalization",{"title":938,"path":939,"stem":940},"Humanizer: людиномовні рядки у .NET","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Fhumanizer","01.csharp\u002F11.aspnet\u002F05.i18n\u002F02.humanizer",{"title":942,"icon":943,"path":944,"stem":945,"children":946,"page":59},"Кешування","i-lucide-layers","\u002Fcsharp\u002Faspnet\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching",[947,951,955,959,963],{"title":948,"path":949,"stem":950},"Огляд кешування: чотири рівні і коли що обирати","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching\u002F01.caching",{"title":952,"path":953,"stem":954},"IMemoryCache: кеш в оперативній пам'яті","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fmemory-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F02.memory-cache",{"title":956,"path":957,"stem":958},"IDistributedCache і Redis: розподілений кеш","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fdistributed-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F03.distributed-cache",{"title":960,"path":961,"stem":962},"Response Cache: HTTP-кешування через Cache-Control","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fresponse-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F04.response-cache",{"title":964,"path":965,"stem":966},"Output Cache: серверний кеш HTTP-відповідей (.NET 7+)","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Foutput-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F05.output-cache",{"title":968,"icon":969,"path":970,"stem":971,"children":972,"page":59},"Тестування","i-lucide-test-tube","\u002Fcsharp\u002Faspnet\u002Ftesting","01.csharp\u002F11.aspnet\u002F07.testing",[973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1021,1025,1029,1033,1037,1041,1045,1049,1053],{"title":974,"path":975,"stem":976},"Що таке тестування? Від інтуїції до науки","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-is-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F01.what-is-testing",{"title":978,"path":979,"stem":980},"Піраміда тестування — Стратегія, а не Догма","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-pyramid","01.csharp\u002F11.aspnet\u002F07.testing\u002F02.testing-pyramid",{"title":982,"path":983,"stem":984},"Дві Школи Тестування — Лондон проти Детройту","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-schools","01.csharp\u002F11.aspnet\u002F07.testing\u002F03.testing-schools",{"title":986,"path":987,"stem":988},"TDD та BDD — Тести як Дизайн-інструмент","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftdd-and-bdd","01.csharp\u002F11.aspnet\u002F07.testing\u002F04.tdd-and-bdd",{"title":990,"path":991,"stem":992},"Що саме тестувати — Техніки аналізу та Циклomatична складність","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-to-test","01.csharp\u002F11.aspnet\u002F07.testing\u002F05.what-to-test",{"title":994,"path":995,"stem":996},"Тестові Фреймворки — Навіщо вони і що всередині","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftest-frameworks","01.csharp\u002F11.aspnet\u002F07.testing\u002F06.test-frameworks",{"title":998,"path":999,"stem":1000},"xUnit — Факти, Теорії та Lifecycle тестів","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-basics","01.csharp\u002F11.aspnet\u002F07.testing\u002F07.xunit-basics",{"title":1002,"path":1003,"stem":1004},"xUnit Advanced — Fixtures, Кастомізація та Розширення","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F08.xunit-advanced",{"title":1006,"path":1007,"stem":1008},"Moq — Глибоке занурення в мокування","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fmocking-with-moq","01.csharp\u002F11.aspnet\u002F07.testing\u002F09.mocking-with-moq",{"title":1010,"path":1011,"stem":1012},"Тестування Баз Даних — EF Core, SQLite та Testcontainers","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fdatabase-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F10.database-testing",{"title":1014,"path":1015,"stem":1016},"Integration Testing — Частина 1 [Теорія та WebApplicationFactory]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F11.integration-testing",{"title":1018,"path":1019,"stem":1020},"Інтеграційне тестування — Практика","\u002Fcsharp\u002Faspnet\u002Ftesting\u002F11a.integration-testing-practice","01.csharp\u002F11.aspnet\u002F07.testing\u002F11a.integration-testing-practice",{"title":1022,"path":1023,"stem":1024},"Integration Testing — Частина 2 [Просунуті Сценарії та Testcontainers]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F12.integration-testing-advanced",{"title":1026,"path":1027,"stem":1028},"Професійний Postman: Колекції, Змінні та GitHub Інтеграція","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fpostman-professional","01.csharp\u002F11.aspnet\u002F07.testing\u002F13.postman-professional",{"title":1030,"path":1031,"stem":1032},"HttpClient у Тестах Частина 1: Архітектура та MockHttpMessageHandler","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fhttpclient-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F14.httpclient-testing",{"title":1034,"path":1035,"stem":1036},"HttpClient у Тестах Частина 2: WireMock.Net та Resilience","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwiremock-net","01.csharp\u002F11.aspnet\u002F07.testing\u002F15.wiremock-net",{"title":1038,"path":1039,"stem":1040},"Патерни та Анти-патерни Тестування: Test Smells","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-patterns","01.csharp\u002F11.aspnet\u002F07.testing\u002F16.testing-patterns",{"title":1042,"path":1043,"stem":1044},"Просунуті інструменти: Time, Snapshots та Властивості","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fadvanced-testing-tools","01.csharp\u002F11.aspnet\u002F07.testing\u002F17.advanced-testing-tools",{"title":1046,"path":1047,"stem":1048},"Тестування Архітектури з NetArchTest","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Farchitecture-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F18.architecture-testing",{"title":1050,"path":1051,"stem":1052},"Тестування Продуктивності: BenchmarkDotNet, NBomber та k6","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fperformance-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F19.performance-testing",{"title":1054,"path":1055,"stem":1056},"Залишок плану для курсу \"Тестування ASP.NET Minimal API\"","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fremaining_plan","01.csharp\u002F11.aspnet\u002F07.testing\u002Fremaining_plan",{"title":1058,"icon":1059,"path":1060,"stem":1061,"children":1062,"page":59},"Платежі","i-lucide-credit-card","\u002Fcsharp\u002Faspnet\u002Fpayments","01.csharp\u002F11.aspnet\u002F08.payments",[1063,1067,1071,1075,1079,1083,1087,1091,1095,1099,1103,1107],{"title":1064,"path":1065,"stem":1066},"Основи платіжної інфраструктури","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-fundamentals","01.csharp\u002F11.aspnet\u002F08.payments\u002F01.payment-fundamentals",{"title":1068,"path":1069,"stem":1070},"Методи оплати в Україні","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-methods-ukraine","01.csharp\u002F11.aspnet\u002F08.payments\u002F02.payment-methods-ukraine",{"title":1072,"path":1073,"stem":1074},"PCI DSS та безпека платежів","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpci-dss-security","01.csharp\u002F11.aspnet\u002F08.payments\u002F03.pci-dss-security",{"title":1076,"path":1077,"stem":1078},"Архітектура платіжної підсистеми","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-architecture","01.csharp\u002F11.aspnet\u002F08.payments\u002F04.payment-architecture",{"title":1080,"path":1081,"stem":1082},"Інтеграція LiqPay (ПриватБанк)","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fliqpay-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F05.liqpay-integration",{"title":1084,"path":1085,"stem":1086},"Інтеграція Monobank Acquiring API","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fmonobank-acquiring","01.csharp\u002F11.aspnet\u002F08.payments\u002F06.monobank-acquiring",{"title":1088,"path":1089,"stem":1090},"Інтеграція Stripe","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fstripe-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F07.stripe-integration",{"title":1092,"path":1093,"stem":1094},"Webhooks — глибоке занурення","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fwebhooks-deep-dive","01.csharp\u002F11.aspnet\u002F08.payments\u002F08.webhooks-deep-dive",{"title":1096,"path":1097,"stem":1098},"Підписки та рекурентні платежі","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fsubscriptions-recurring","01.csharp\u002F11.aspnet\u002F08.payments\u002F09.subscriptions-recurring",{"title":1100,"path":1101,"stem":1102},"Повернення коштів та диспути","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Frefunds-disputes","01.csharp\u002F11.aspnet\u002F08.payments\u002F10.refunds-disputes",{"title":1104,"path":1105,"stem":1106},"Тестування платіжних інтеграцій","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Ftesting-payments","01.csharp\u002F11.aspnet\u002F08.payments\u002F11.testing-payments",{"title":1108,"path":1109,"stem":1110},"Чекліст виходу в Production","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fproduction-checklist","01.csharp\u002F11.aspnet\u002F08.payments\u002F12.production-checklist",{"title":1112,"icon":1113,"items":1114,"path":1127,"stem":1128,"children":1129,"page":59},"Популярні бібліотеки","lucide:box",[1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126],"01.fluent-validation","02.mapster","03.erroror-result-pattern","04.serilog","05.mediatr","06.polly","07.health-checks","08.feature-management","09.fluent-email","10.quest-pdf","11.bogus","12.humanizer-guard","\u002Fcsharp\u002Faspnet\u002Flibraries","01.csharp\u002F11.aspnet\u002F09.libraries",[1130,1134,1138,1142,1146,1150,1154,1158,1162,1166,1170,1174,1178],{"title":1131,"path":1132,"stem":1133},"Валідація з FluentValidation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-validation","01.csharp\u002F11.aspnet\u002F09.libraries\u002F01.fluent-validation",{"title":1135,"path":1136,"stem":1137},"Маппінг об","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmapster","01.csharp\u002F11.aspnet\u002F09.libraries\u002F02.mapster",{"title":1139,"path":1140,"stem":1141},"Обробка помилок з ErrorOr та Result Pattern в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ferroror-result-pattern","01.csharp\u002F11.aspnet\u002F09.libraries\u002F03.erroror-result-pattern",{"title":1143,"path":1144,"stem":1145},"Структуроване логування з Serilog в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fserilog","01.csharp\u002F11.aspnet\u002F09.libraries\u002F04.serilog",{"title":1147,"path":1148,"stem":1149},"CQRS та Mediator з MediatR в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmediatr","01.csharp\u002F11.aspnet\u002F09.libraries\u002F05.mediatr",{"title":1151,"path":1152,"stem":1153},"Відмовостійкість з Polly в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fpolly","01.csharp\u002F11.aspnet\u002F09.libraries\u002F06.polly",{"title":1155,"path":1156,"stem":1157},"Health Checks в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F09.libraries\u002F07.health-checks",{"title":1159,"path":1160,"stem":1161},"Feature Management та Feature Flags в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffeature-management","01.csharp\u002F11.aspnet\u002F09.libraries\u002F08.feature-management",{"title":1163,"path":1164,"stem":1165},"Відправка Email з FluentEmail в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-email","01.csharp\u002F11.aspnet\u002F09.libraries\u002F09.fluent-email",{"title":1167,"path":1168,"stem":1169},"Генерація PDF з QuestPDF в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fquest-pdf","01.csharp\u002F11.aspnet\u002F09.libraries\u002F10.quest-pdf",{"title":1171,"path":1172,"stem":1173},"Генерація тестових даних з Bogus в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fbogus","01.csharp\u002F11.aspnet\u002F09.libraries\u002F11.bogus",{"title":1175,"path":1176,"stem":1177},"Humanizer та Guard Clauses в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhumanizer-guard","01.csharp\u002F11.aspnet\u002F09.libraries\u002F12.humanizer-guard",{"title":1179,"path":1180,"stem":1181},"План модуля 10.libraries — Популярні бібліотеки ASP.NET","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fplan","01.csharp\u002F11.aspnet\u002F09.libraries\u002Fplan",{"title":1183,"icon":1184,"path":1185,"stem":1186,"children":1187,"page":59},"Razor Pages","i-lucide-layout-template","\u002Fcsharp\u002Faspnet\u002Frazor-pages","01.csharp\u002F11.aspnet\u002F10.razor-pages",[1188,1192,1196,1200,1204,1208],{"title":1189,"path":1190,"stem":1191},"Від Minimal API до Razor Pages: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ffrom-minimal-api","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F01.from-minimal-api",{"title":1193,"path":1194,"stem":1195},"PageModel: логіка сторінки Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fpage-model","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F02.page-model",{"title":1197,"path":1198,"stem":1199},"Razor синтаксис: шаблонізатор у .cshtml","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Frazor-syntax","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F03.razor-syntax",{"title":1201,"path":1202,"stem":1203},"Tag Helpers: типізований HTML","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ftag-helpers","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F04.tag-helpers",{"title":1205,"path":1206,"stem":1207},"Форми і валідація: повний цикл обробки даних","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fforms-validation","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F05.forms-validation",{"title":1209,"path":1210,"stem":1211},"Практичний проєкт: TaskManager на Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fproject-task-manager","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F06.project-task-manager",{"title":1213,"path":1214,"stem":1215,"children":1216,"page":59},"ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc","01.csharp\u002F11.aspnet\u002F11.mvc",[1217,1221,1225,1229,1233,1237,1241,1245,1249,1253,1257,1261,1265,1269,1273,1277,1281,1285],{"title":1218,"path":1219,"stem":1220},"Патерн MVC: архітектура, що змінила веб","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-pattern","01.csharp\u002F11.aspnet\u002F11.mvc\u002F01.mvc-pattern",{"title":1222,"path":1223,"stem":1224},"Від Razor Pages до MVC: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffrom-razor-pages","01.csharp\u002F11.aspnet\u002F11.mvc\u002F02.from-razor-pages",{"title":1226,"path":1227,"stem":1228},"Controllers та Actions: серце MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fcontrollers-actions","01.csharp\u002F11.aspnet\u002F11.mvc\u002F03.controllers-actions",{"title":1230,"path":1231,"stem":1232},"Маршрутизація в MVC: Convention vs Attribute Routing","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Frouting-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F04.routing-mvc",{"title":1234,"path":1235,"stem":1236},"Model Binding: від HTTP до C#","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmodel-binding","01.csharp\u002F11.aspnet\u002F11.mvc\u002F05.model-binding",{"title":1238,"path":1239,"stem":1240},"Views, ViewData, ViewBag, TempData і ViewModel","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fviews-viewdata-tempdata","01.csharp\u002F11.aspnet\u002F11.mvc\u002F06.views-viewdata-tempdata",{"title":1242,"path":1243,"stem":1244},"Filters: аспектно-орієнтоване програмування в MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffilters","01.csharp\u002F11.aspnet\u002F11.mvc\u002F07.filters",{"title":1246,"path":1247,"stem":1248},"Areas: структурування великих застосунків","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fareas","01.csharp\u002F11.aspnet\u002F11.mvc\u002F08.areas",{"title":1250,"path":1251,"stem":1252},"View Components: повторювані незалежні блоки UI","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fview-components","01.csharp\u002F11.aspnet\u002F11.mvc\u002F09.view-components",{"title":1254,"path":1255,"stem":1256},"Display та Editor Templates","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fdisplay-editor-templates","01.csharp\u002F11.aspnet\u002F11.mvc\u002F10.display-editor-templates",{"title":1258,"path":1259,"stem":1260},"Валідація: IValidatableObject та FluentValidation","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fvalidation-advanced","01.csharp\u002F11.aspnet\u002F11.mvc\u002F11.validation-advanced",{"title":1262,"path":1263,"stem":1264},"HTMX: інтерактивність через HTML-атрибути","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx","01.csharp\u002F11.aspnet\u002F11.mvc\u002F12.htmx",{"title":1266,"path":1267,"stem":1268},"HTMX у ASP.NET Core MVC: серверна інтеграція","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fajax-htmx-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F13.ajax-htmx-mvc",{"title":1270,"path":1271,"stem":1272},"Практичний проєкт: Каталог товарів з HTMX","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F14.htmx-project",{"title":1274,"path":1275,"stem":1276},"Завантаження та обробка файлів","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffile-upload","01.csharp\u002F11.aspnet\u002F11.mvc\u002F15.file-upload",{"title":1278,"path":1279,"stem":1280},"Глобалізація та Локалізація MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fglobalization-localization","01.csharp\u002F11.aspnet\u002F11.mvc\u002F16.globalization-localization",{"title":1282,"path":1283,"stem":1284},"Підсумковий проєкт: Блог-платформа","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F17.mvc-project",{"title":1286,"path":1287,"stem":1288},"План курсу: ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fplan","01.csharp\u002F11.aspnet\u002F11.mvc\u002Fplan",{"title":1290,"path":1291,"stem":1292,"children":1293,"page":59},"Web Api","\u002Fcsharp\u002Faspnet\u002Fweb-api","01.csharp\u002F11.aspnet\u002F12.web-api",[1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1342],{"title":1295,"path":1296,"stem":1297},"Від Minimal API до Controller-based API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffrom-minimal-api-to-controllers","01.csharp\u002F11.aspnet\u002F12.web-api\u002F01.from-minimal-api-to-controllers",{"title":1299,"path":1300,"stem":1301},"ControllerBase, ActionResult\u003CT> та Response Types","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontroller-base-actionresult","01.csharp\u002F11.aspnet\u002F12.web-api\u002F02.controller-base-actionresult",{"title":1303,"path":1304,"stem":1305},"Content Negotiation - JSON, XML та власні форматери","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontent-negotiation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F03.content-negotiation",{"title":1307,"path":1308,"stem":1309},"Версіонування API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-versioning","01.csharp\u002F11.aspnet\u002F12.web-api\u002F04.api-versioning",{"title":1311,"path":1312,"stem":1313},"ProblemDetails та структурована обробка помилок","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fproblemdetails-error-handling","01.csharp\u002F11.aspnet\u002F12.web-api\u002F05.problemdetails-error-handling",{"title":1315,"path":1316,"stem":1317},"Фільтри у Web API контексті","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffilters-for-api","01.csharp\u002F11.aspnet\u002F12.web-api\u002F06.filters-for-api",{"title":1319,"path":1320,"stem":1321},"Пагінація, фільтрація та сортування","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fpagination-filtering-sorting","01.csharp\u002F11.aspnet\u002F12.web-api\u002F07.pagination-filtering-sorting",{"title":1323,"path":1324,"stem":1325},"HATEOAS та Resource Expansion","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhateoas-resource-expansion","01.csharp\u002F11.aspnet\u002F12.web-api\u002F08.hateoas-resource-expansion",{"title":1327,"path":1328,"stem":1329},"Гібридна архітектура - Minimal API + Controllers","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fminimal-api-vs-controllers-hybrid","01.csharp\u002F11.aspnet\u002F12.web-api\u002F09.minimal-api-vs-controllers-hybrid",{"title":1331,"path":1332,"stem":1333},"Документація API - Swashbuckle, NSwag та генерація клієнтів","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-documentation-generation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F10.api-documentation-generation",{"title":1335,"path":1336,"stem":1337},"Health Checks та моніторинг API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhealth-checks-monitoring","01.csharp\u002F11.aspnet\u002F12.web-api\u002F11.health-checks-monitoring",{"title":1339,"path":1340,"stem":1341},"Підсумковий проєкт - Production-Ready REST API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fweb-api-project","01.csharp\u002F11.aspnet\u002F12.web-api\u002F12.web-api-project",{"title":1343,"path":1344,"stem":1345},"План курсу: ASP.NET Core Web API (Controllers)","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fplan","01.csharp\u002F11.aspnet\u002F12.web-api\u002Fplan",{"title":1347,"icon":1348,"path":1349,"stem":1350,"children":1351,"page":59},"Моніторинг","i-lucide-activity","\u002Fcsharp\u002Faspnet\u002Fmonitoring","01.csharp\u002F11.aspnet\u002F13.monitoring",[1352,1356,1360],{"title":1353,"path":1354,"stem":1355},"Спостережуваність: від console.log до production-систем","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fobservability-intro","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F01.observability-intro",{"title":1357,"path":1358,"stem":1359},"Health Checks: перший рівень observability","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F02.health-checks",{"title":1361,"path":1362,"stem":1363},"Вбудовані метрики .NET 10 та System.Diagnostics.Metrics","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fdotnet-metrics","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F03.dotnet-metrics",{"title":1365,"icon":1366,"path":1367,"stem":1368,"children":1369,"page":59},"Desktop UI","i-lucide-app-window","\u002Fcsharp\u002Fdesktop-ui","01.csharp\u002F12.desktop-ui",[1370,1374,1378,1382,1386,1390,1394,1398,1402,1406,1410,1414,1418,1422,1426,1430,1434,1438,1442,1446,1450,1454,1458,1462,1466,1470,1474,1478,1482,1486,1490,1494,1498,1502,1506,1510,1514,1518,1522,1526,1530,1534,1538,1542,1546,1550,1554,1558,1562,1566,1570,1574,1578,1582,1586,1590,1594,1598,1602,1606,1610,1614,1618,1622,1626,1630,1634,1638,1642,1646,1650],{"title":1371,"path":1372,"stem":1373},"Що таке десктопна розробка?","\u002Fcsharp\u002Fdesktop-ui\u002Fwhat-is-desktop-dev","01.csharp\u002F12.desktop-ui\u002F01.what-is-desktop-dev",{"title":1375,"path":1376,"stem":1377},"Архітектура WPF — як влаштований графічний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-architecture","01.csharp\u002F12.desktop-ui\u002F02.wpf-architecture",{"title":1379,"path":1380,"stem":1381},"Перший WPF-проєкт — від нуля до вікна","\u002Fcsharp\u002Fdesktop-ui\u002Ffirst-wpf-app","01.csharp\u002F12.desktop-ui\u002F03.first-wpf-app",{"title":1383,"path":1384,"stem":1385},"Перший Avalonia-проєкт: WPF для всіх платформ","\u002Fcsharp\u002Fdesktop-ui\u002F03a.first-avalonia-app","01.csharp\u002F12.desktop-ui\u002F03a.first-avalonia-app",{"title":1387,"path":1388,"stem":1389},"XAML: декларативний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-basics","01.csharp\u002F12.desktop-ui\u002F04.xaml-basics",{"title":1391,"path":1392,"stem":1393},"Fluent UI у WPF — сучасний дизайн Windows 11","\u002Fcsharp\u002Fdesktop-ui\u002F04a.wpf-fluent-ui","01.csharp\u002F12.desktop-ui\u002F04a.wpf-fluent-ui",{"title":1395,"path":1396,"stem":1397},"WPF UI — сучасна бібліотека Fluent контролів","\u002Fcsharp\u002Fdesktop-ui\u002F04b.wpf-ui-library","01.csharp\u002F12.desktop-ui\u002F04b.wpf-ui-library",{"title":1399,"path":1400,"stem":1401},"HandyControl — велика бібліотека UI контролів для WPF","\u002Fcsharp\u002Fdesktop-ui\u002F04c.handycontrol-library","01.csharp\u002F12.desktop-ui\u002F04c.handycontrol-library",{"title":1403,"path":1404,"stem":1405},"Простори імен та ресурси XAML","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-namespaces-resources","01.csharp\u002F12.desktop-ui\u002F05.xaml-namespaces-resources",{"title":1407,"path":1408,"stem":1409},"XAML в Avalonia: ключові відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F05a.avalonia-xaml-differences","01.csharp\u002F12.desktop-ui\u002F05a.avalonia-xaml-differences",{"title":1411,"path":1412,"stem":1413},"Розширення розмітки XAML (Markup Extensions)","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-markup-extensions","01.csharp\u002F12.desktop-ui\u002F06.xaml-markup-extensions",{"title":1415,"path":1416,"stem":1417},"Панелі Layout: StackPanel, WrapPanel, DockPanel","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part1","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part1",{"title":1419,"path":1420,"stem":1421},"Grid, Canvas, UniformGrid","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part2","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part2",{"title":1423,"path":1424,"stem":1425},"Просунуті техніки Layout","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-advanced","01.csharp\u002F12.desktop-ui\u002F08.layout-advanced",{"title":1427,"path":1428,"stem":1429},"Адаптивний Layout та найкращі практики","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-responsive","01.csharp\u002F12.desktop-ui\u002F09.layout-responsive",{"title":1431,"path":1432,"stem":1433},"Layout в Avalonia: відмінності та нові можливості","\u002Fcsharp\u002Fdesktop-ui\u002F09a.layout-avalonia","01.csharp\u002F12.desktop-ui\u002F09a.layout-avalonia",{"title":1435,"path":1436,"stem":1437},"Button, Image, ProgressBar та інші базові контроли","\u002Fcsharp\u002Fdesktop-ui\u002Fbasic-controls","01.csharp\u002F12.desktop-ui\u002F10.basic-controls",{"title":1439,"path":1440,"stem":1441},"Контроли в Avalonia: відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F10a.controls-avalonia","01.csharp\u002F12.desktop-ui\u002F10a.controls-avalonia",{"title":1443,"path":1444,"stem":1445},"Текстові контроли — TextBlock, TextBox, RichTextBox","\u002Fcsharp\u002Fdesktop-ui\u002Ftext-controls","01.csharp\u002F12.desktop-ui\u002F11.text-controls",{"title":1447,"path":1448,"stem":1449},"Контроли вибору — CheckBox, RadioButton, ComboBox, ListBox, DatePicker","\u002Fcsharp\u002Fdesktop-ui\u002Fselection-controls","01.csharp\u002F12.desktop-ui\u002F12.selection-controls",{"title":1451,"path":1452,"stem":1453},"Content Model — GroupBox, Expander, TabControl, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fcontent-controls","01.csharp\u002F12.desktop-ui\u002F13.content-controls",{"title":1455,"path":1456,"stem":1457},"UI\u002FUX принципи десктопних застосунків","\u002Fcsharp\u002Fdesktop-ui\u002F13a.ui-ux-principles","01.csharp\u002F12.desktop-ui\u002F13a.ui-ux-principles",{"title":1459,"path":1460,"stem":1461},"Dependency Properties — Концепція та Value Resolution","\u002Fcsharp\u002Fdesktop-ui\u002Fdependency-properties-part1","01.csharp\u002F12.desktop-ui\u002F14.dependency-properties-part1",{"title":1463,"path":1464,"stem":1465},"Avalonia Property System — StyledProperty та DirectProperty","\u002Fcsharp\u002Fdesktop-ui\u002F14a.avalonia-property-system","01.csharp\u002F12.desktop-ui\u002F14a.avalonia-property-system",{"title":1467,"path":1468,"stem":1469},"Attached Properties — Властивості без меж","\u002Fcsharp\u002Fdesktop-ui\u002Fattached-properties","01.csharp\u002F12.desktop-ui\u002F15.attached-properties",{"title":1471,"path":1472,"stem":1473},"Routed Events — Маршрутизація подій у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Frouted-events","01.csharp\u002F12.desktop-ui\u002F16.routed-events",{"title":1475,"path":1476,"stem":1477},"Data Binding — Від Code-Behind до Декларативності","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part1","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part1",{"title":1479,"path":1480,"stem":1481},"INotifyPropertyChanged — Живе оновлення UI","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part2","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part2",{"title":1483,"path":1484,"stem":1485},"Compiled Bindings в Avalonia — Безпека на етапі компіляції","\u002Fcsharp\u002Fdesktop-ui\u002F17a.avalonia-compiled-bindings","01.csharp\u002F12.desktop-ui\u002F17a.avalonia-compiled-bindings",{"title":1487,"path":1488,"stem":1489},"Просунутий Data Binding — ElementName, RelativeSource, MultiBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-advanced","01.csharp\u002F12.desktop-ui\u002F18.data-binding-advanced",{"title":1491,"path":1492,"stem":1493},"Value Converters — Перетворення типів даних у Data Binding","\u002Fcsharp\u002Fdesktop-ui\u002Fvalue-converters","01.csharp\u002F12.desktop-ui\u002F19.value-converters",{"title":1495,"path":1496,"stem":1497},"Data Templates — Візуалізація об'єктів у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-templates","01.csharp\u002F12.desktop-ui\u002F20.data-templates",{"title":1499,"path":1500,"stem":1501},"Collections Binding Part 1 — ObservableCollection та ItemsControl","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part1","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part1",{"title":1503,"path":1504,"stem":1505},"Collections Binding Part 2 — ICollectionView, Filtering, Sorting та Virtualization","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part2","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part2",{"title":1507,"path":1508,"stem":1509},"MVVM Pattern — Від Spaghetti Code до архітектури","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-pattern","01.csharp\u002F12.desktop-ui\u002F22.mvvm-pattern",{"title":1511,"path":1512,"stem":1513},"ViewModel Implementation — Від BaseViewModel до валідації","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-implementation","01.csharp\u002F12.desktop-ui\u002F23.viewmodel-implementation",{"title":1515,"path":1516,"stem":1517},"Commands — Від event handlers до декларативних команд","\u002Fcsharp\u002Fdesktop-ui\u002Fcommands","01.csharp\u002F12.desktop-ui\u002F24.commands",{"title":1519,"path":1520,"stem":1521},"MVVM Toolkit — MVVM без boilerplate через Source Generators","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-toolkit","01.csharp\u002F12.desktop-ui\u002F25.mvvm-toolkit",{"title":1523,"path":1524,"stem":1525},"Messenger Pattern — Комунікація між ViewModel без прямих посилань","\u002Fcsharp\u002Fdesktop-ui\u002Fmessenger-pattern","01.csharp\u002F12.desktop-ui\u002F26.messenger-pattern",{"title":1527,"path":1528,"stem":1529},"Стилі WPF — CSS для десктопу","\u002Fcsharp\u002Fdesktop-ui\u002Fstyles-basics","01.csharp\u002F12.desktop-ui\u002F27.styles-basics",{"title":1531,"path":1532,"stem":1533},"CSS-like стилі Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F27a.avalonia-css-styling","01.csharp\u002F12.desktop-ui\u002F27a.avalonia-css-styling",{"title":1535,"path":1536,"stem":1537},"Control Templates — Частина 1. Концепція та TemplateBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part1","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part1",{"title":1539,"path":1540,"stem":1541},"Control Templates — Частина 2. Named Parts та ContentPresenter","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part2","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part2",{"title":1543,"path":1544,"stem":1545},"Control Themes в Avalonia — нова ера стилізації","\u002Fcsharp\u002Fdesktop-ui\u002F28a.avalonia-control-themes","01.csharp\u002F12.desktop-ui\u002F28a.avalonia-control-themes",{"title":1547,"path":1548,"stem":1549},"Triggers та Visual State Manager у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Ftriggers-visual-states","01.csharp\u002F12.desktop-ui\u002F29.triggers-visual-states",{"title":1551,"path":1552,"stem":1553},"Pseudo-classes в Avalonia — замість WPF Triggers","\u002Fcsharp\u002Fdesktop-ui\u002F29a.avalonia-pseudo-classes","01.csharp\u002F12.desktop-ui\u002F29a.avalonia-pseudo-classes",{"title":1555,"path":1556,"stem":1557},"Теми та ресурсні словники у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fresources-themes","01.csharp\u002F12.desktop-ui\u002F30.resources-themes",{"title":1559,"path":1560,"stem":1561},"Avalonia Themes — Fluent Design та система тематизації","\u002Fcsharp\u002Fdesktop-ui\u002F30a.avalonia-themes-fluent","01.csharp\u002F12.desktop-ui\u002F30a.avalonia-themes-fluent",{"title":1563,"path":1564,"stem":1565},"Контроли колекцій — глибоке занурення","\u002Fcsharp\u002Fdesktop-ui\u002Fcollection-controls","01.csharp\u002F12.desktop-ui\u002F31.collection-controls",{"title":1567,"path":1568,"stem":1569},"DataGrid — колонки та базове відображення","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part1","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part1",{"title":1571,"path":1572,"stem":1573},"DataGrid — сортування, фільтрація, редагування","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part2","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part2",{"title":1575,"path":1576,"stem":1577},"TreeView та GridView","\u002Fcsharp\u002Fdesktop-ui\u002Ftreeview-listview","01.csharp\u002F12.desktop-ui\u002F33.treeview-listview",{"title":1579,"path":1580,"stem":1581},"Меню, Toolbar, ContextMenu, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fmenus-toolbars","01.csharp\u002F12.desktop-ui\u002F34.menus-toolbars",{"title":1583,"path":1584,"stem":1585},"Навігація та керування вікнами. Частина 1: вікна та сторінки","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part1","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part1",{"title":1587,"path":1588,"stem":1589},"Навігація та керування вікнами. Частина 2: MVVM-навігація","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part2","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part2",{"title":1591,"path":1592,"stem":1593},"Avalonia — Навігація та діалоги","\u002Fcsharp\u002Fdesktop-ui\u002F35a.avalonia-navigation-dialogs","01.csharp\u002F12.desktop-ui\u002F35a.avalonia-navigation-dialogs",{"title":1595,"path":1596,"stem":1597},"Діалоги та File Pickers у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdialogs-file-pickers","01.csharp\u002F12.desktop-ui\u002F36.dialogs-file-pickers",{"title":1599,"path":1600,"stem":1601},"UserControl: компонентний підхід у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fuser-controls","01.csharp\u002F12.desktop-ui\u002F37.user-controls",{"title":1603,"path":1604,"stem":1605},"Custom Controls: Lookless Controls у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fcustom-controls","01.csharp\u002F12.desktop-ui\u002F38.custom-controls",{"title":1607,"path":1608,"stem":1609},"Avalonia TemplatedControl — Lookless Controls","\u002Fcsharp\u002Fdesktop-ui\u002F38a.avalonia-templated-controls","01.csharp\u002F12.desktop-ui\u002F38a.avalonia-templated-controls",{"title":1611,"path":1612,"stem":1613},"Анімації у WPF: Storyboard та Easing Functions","\u002Fcsharp\u002Fdesktop-ui\u002Fanimations-transitions","01.csharp\u002F12.desktop-ui\u002F39.animations-transitions",{"title":1615,"path":1616,"stem":1617},"Анімації в Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F39a.avalonia-animations","01.csharp\u002F12.desktop-ui\u002F39a.avalonia-animations",{"title":1619,"path":1620,"stem":1621},"2D Графіка та Мультимедіа у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fmedia-graphics","01.csharp\u002F12.desktop-ui\u002F40.media-graphics",{"title":1623,"path":1624,"stem":1625},"Dependency Injection у WPF та Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Fdi-integration","01.csharp\u002F12.desktop-ui\u002F41.di-integration",{"title":1627,"path":1628,"stem":1629},"SQLite та EF Core у десктопних додатках","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part1","01.csharp\u002F12.desktop-ui\u002F42.data-persistence-part1",{"title":1631,"path":1632,"stem":1633},"Repository Pattern та Unit of Work","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part2","01.csharp\u002F12.desktop-ui\u002F43.data-persistence-part2",{"title":1635,"path":1636,"stem":1637},"Тестування ViewModels","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-testing","01.csharp\u002F12.desktop-ui\u002F44.viewmodel-testing",{"title":1639,"path":1640,"stem":1641},"Avalonia Headless Testing — тестування UI без вікон","\u002Fcsharp\u002Fdesktop-ui\u002F44a.avalonia-headless-testing","01.csharp\u002F12.desktop-ui\u002F44a.avalonia-headless-testing",{"title":1643,"path":1644,"stem":1645},"Кросплатформна розробка з Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-cross-platform","01.csharp\u002F12.desktop-ui\u002F45.avalonia-cross-platform",{"title":1647,"path":1648,"stem":1649},"Пакування та розгортання Avalonia додатків","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F46.avalonia-packaging-deployment",{"title":1651,"path":1652,"stem":1653},"Розгортання WPF застосунків","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F47.wpf-packaging-deployment",{"title":1655,"icon":658,"path":1656,"stem":1657,"children":1658,"page":59},"Network Programming","\u002Fcsharp\u002Fnetwork-programming","01.csharp\u002F13.network-programming",[1659,1663,1667,1671,1675,1679,1683,1687,1691,1695,1699],{"title":1660,"path":1661,"stem":1662},"Основи комп'ютерних мереж","\u002Fcsharp\u002Fnetwork-programming\u002Ffoundations","01.csharp\u002F13.network-programming\u002F01.foundations",{"title":1664,"path":1665,"stem":1666},"Модель OSI та стек TCP\u002FIP","\u002Fcsharp\u002Fnetwork-programming\u002Fosi-model","01.csharp\u002F13.network-programming\u002F02.osi-model",{"title":1668,"path":1669,"stem":1670},"IP-протокол та адресація","\u002Fcsharp\u002Fnetwork-programming\u002Fip-addressing","01.csharp\u002F13.network-programming\u002F03.ip-addressing",{"title":1672,"path":1673,"stem":1674},"UDP — протокол без з'єднання","\u002Fcsharp\u002Fnetwork-programming\u002Fudp","01.csharp\u002F13.network-programming\u002F05.udp",{"title":1676,"path":1677,"stem":1678},"UDP Broadcast та Multicast","\u002Fcsharp\u002Fnetwork-programming\u002Fudp-broadcast-multicast","01.csharp\u002F13.network-programming\u002F06.udp-broadcast-multicast",{"title":1680,"path":1681,"stem":1682},"HTTP — протокол вебу","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-fundamentals","01.csharp\u002F13.network-programming\u002F07.http-fundamentals",{"title":1684,"path":1685,"stem":1686},"HttpListener — вбудований HTTP-сервер .NET","\u002Fcsharp\u002Fnetwork-programming\u002F07a.http-listener","01.csharp\u002F13.network-programming\u002F07a.http-listener",{"title":1688,"path":1689,"stem":1690},"HTTP Advanced — cookies, аутентифікація та HTTPS","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-advanced","01.csharp\u002F13.network-programming\u002F08.http-advanced",{"title":1692,"path":1693,"stem":1694},"SMTP та протоколи електронної пошти","\u002Fcsharp\u002Fnetwork-programming\u002Fsmtp","01.csharp\u002F13.network-programming\u002F09.smtp",{"title":1696,"path":1697,"stem":1698},"WebSocket — повнодуплексний протокол реального часу","\u002Fcsharp\u002Fnetwork-programming\u002Fwebsockets","01.csharp\u002F13.network-programming\u002F10.websockets",{"title":1700,"path":1701,"stem":1702},"TLS\u002FSSL — криптографічний захист мережевих з'єднань","\u002Fcsharp\u002Fnetwork-programming\u002Ftls-ssl","01.csharp\u002F13.network-programming\u002F11.tls-ssl",{"title":1704,"path":1705,"stem":1706},"C# & .NET: The Ultimate Roadmap","\u002Fcsharp\u002Froadmap","01.csharp\u002Froadmap",{"title":1708,"icon":1709,"path":1710,"stem":1711,"children":1712,"page":59},"C++","i-devicon-cplusplus","\u002Fcpp","02.cpp",[1713,1717,1721,1725,1729,1733,1737,1741,1745,1748,1752,1756,1760,1764,1768,1772,1776,1780,1784,1788,1792,1796,1800,1804,1808,1812,1816,1820,1824,1828,1832,1836,1840,1844,1848,1852,1856,1860,1864,1868,1872,1876,1880,1884,1888,1892,1896,1900,1904,1908],{"title":1714,"path":1715,"stem":1716},"Вступ у програмування та алгоритми","\u002Fcpp\u002Fintro-algorithms","02.cpp\u002F01.intro-algorithms",{"title":1718,"path":1719,"stem":1720},"Code Style: угоди про оформлення коду","\u002Fcpp\u002Fcode-style","02.cpp\u002F02.code-style",{"title":1722,"path":1723,"stem":1724},"Середовище розробки та перший проєкт","\u002Fcpp\u002Fide-setup","02.cpp\u002F03.ide-setup",{"title":1726,"path":1727,"stem":1728},"Вивід даних на екран","\u002Fcpp\u002Fdata-output","02.cpp\u002F04.data-output",{"title":1730,"path":1731,"stem":1732},"Типи даних, змінні та константи","\u002Fcpp\u002Fdata-types-variables","02.cpp\u002F05.data-types-variables",{"title":1734,"path":1735,"stem":1736},"Ввід даних з клавіатури","\u002Fcpp\u002Fdata-input","02.cpp\u002F06.data-input",{"title":1738,"path":1739,"stem":1740},"Оператори, перетворення типів та логічні операції","\u002Fcpp\u002Foperators-type-conversion","02.cpp\u002F07.operators-type-conversion",{"title":1742,"path":1743,"stem":1744},"Цикли","\u002Fcpp\u002Floops","02.cpp\u002F08.loops",{"title":32,"path":1746,"stem":1747},"\u002Fcpp\u002Farrays","02.cpp\u002F09.arrays",{"title":1749,"path":1750,"stem":1751},"Алгоритми сортування та аналіз складності","\u002Fcpp\u002Fsorting","02.cpp\u002F10.sorting",{"title":1753,"path":1754,"stem":1755},"Алгоритми пошуку","\u002Fcpp\u002Fsearching","02.cpp\u002F11.searching",{"title":1757,"path":1758,"stem":1759},"Функції: основи","\u002Fcpp\u002Ffunctions-basics","02.cpp\u002F12.functions-basics",{"title":1761,"path":1762,"stem":1763},"Функції: прототипи, область видимості та додаткові можливості","\u002Fcpp\u002Ffunctions-scope","02.cpp\u002F13.functions-scope",{"title":1765,"path":1766,"stem":1767},"Функції: перевантаження та шаблони","\u002Fcpp\u002Ffunctions-overloading-templates","02.cpp\u002F14.functions-overloading-templates",{"title":1769,"path":1770,"stem":1771},"Вказівники: основи","\u002Fcpp\u002Fpointers-basics","02.cpp\u002F15.pointers-basics",{"title":1773,"path":1774,"stem":1775},"Посилання (References)","\u002Fcpp\u002Freferences","02.cpp\u002F16.references",{"title":1777,"path":1778,"stem":1779},"Вказівники, const і масиви","\u002Fcpp\u002Fpointers-const-arrays","02.cpp\u002F17.pointers-const-arrays",{"title":1781,"path":1782,"stem":1783},"Адресна арифметика","\u002Fcpp\u002Fpointer-arithmetic","02.cpp\u002F18.pointer-arithmetic",{"title":1785,"path":1786,"stem":1787},"Динамічна пам'ять","\u002Fcpp\u002Fdynamic-memory","02.cpp\u002F19.dynamic-memory",{"title":1789,"path":1790,"stem":1791},"Вказівники типу void","\u002Fcpp\u002Fvoid-pointers","02.cpp\u002F20.void-pointers",{"title":1793,"path":1794,"stem":1795},"Вказівники на вказівники","\u002Fcpp\u002Fpointers-to-pointers","02.cpp\u002F21.pointers-to-pointers",{"title":1797,"path":1798,"stem":1799},"Оператор доступу до членів через вказівник (->)","\u002Fcpp\u002Fmember-access-operator","02.cpp\u002F22.member-access-operator",{"title":1801,"path":1802,"stem":1803},"Цикл for-each (Range-based for)","\u002Fcpp\u002Fforeach-loop","02.cpp\u002F23.foreach-loop",{"title":1805,"path":1806,"stem":1807},"Вказівники на функції","\u002Fcpp\u002Ffunction-pointers","02.cpp\u002F24.function-pointers",{"title":1809,"path":1810,"stem":1811},"Лямбда-вирази","\u002Fcpp\u002Flambdas","02.cpp\u002F25.lambdas",{"title":1813,"path":1814,"stem":1815},"Лямбда-захоплення","\u002Fcpp\u002Flambda-captures","02.cpp\u002F26.lambda-captures",{"title":1817,"path":1818,"stem":1819},"Еліпсис","\u002Fcpp\u002Fellipsis","02.cpp\u002F27.ellipsis",{"title":1821,"path":1822,"stem":1823},"Безпечні альтернативи еліпсису","\u002Fcpp\u002F27a.ellipsis","02.cpp\u002F27a.ellipsis",{"title":1825,"path":1826,"stem":1827},"Аргументи командного рядка","\u002Fcpp\u002Fcommand-line-arguments","02.cpp\u002F28.command-line-arguments",{"title":1829,"path":1830,"stem":1831},"Перерахування (enum)","\u002Fcpp\u002Fenum","02.cpp\u002F29.enum",{"title":1833,"path":1834,"stem":1835},"Класи-перерахування (enum class)","\u002Fcpp\u002Fenum-class","02.cpp\u002F30.enum-class",{"title":1837,"path":1838,"stem":1839},"Псевдоніми типів (typedef і using)","\u002Fcpp\u002Ftype-aliases","02.cpp\u002F31.type-aliases",{"title":1841,"path":1842,"stem":1843},"Системи числення та двійкова арифметика","\u002Fcpp\u002Fnumber-systems","02.cpp\u002F32.number-systems",{"title":1845,"path":1846,"stem":1847},"Структури (struct): агрегування даних","\u002Fcpp\u002Fstruct","02.cpp\u002F33.struct",{"title":1849,"path":1850,"stem":1851},"Структури у функціях","\u002Fcpp\u002Fstruct-functions","02.cpp\u002F34.struct-functions",{"title":1853,"path":1854,"stem":1855},"Масиви структур і вкладені структури","\u002Fcpp\u002Fstruct-arrays","02.cpp\u002F35.struct-arrays",{"title":1857,"path":1858,"stem":1859},"Патерни struct та межі застосування","\u002Fcpp\u002Fstruct-patterns","02.cpp\u002F36.struct-patterns",{"title":1861,"path":1862,"stem":1863},"Символи та таблиця ASCII","\u002Fcpp\u002Fascii-characters","02.cpp\u002F37.ascii-characters",{"title":1865,"path":1866,"stem":1867},"Unicode та кодування UTF","\u002Fcpp\u002Funicode-utf","02.cpp\u002F38.unicode-utf",{"title":1869,"path":1870,"stem":1871},"C-style рядки","\u002Fcpp\u002Fc-strings","02.cpp\u002F39.c-strings",{"title":1873,"path":1874,"stem":1875},"Вступ до std::string","\u002Fcpp\u002Fstd-string-intro","02.cpp\u002F40.std-string-intro",{"title":1877,"path":1878,"stem":1879},"Довжина, ємність та доступ до символів std::string","\u002Fcpp\u002Fstd-string-capacity-access","02.cpp\u002F41.std-string-capacity-access",{"title":1881,"path":1882,"stem":1883},"Модифікація std::string: присвоювання, додавання, вставка, видалення та заміна","\u002Fcpp\u002Fstd-string-modification","02.cpp\u002F42.std-string-modification",{"title":1885,"path":1886,"stem":1887},"Пошук у std::string: find, npos та практичні патерни","\u002Fcpp\u002Fstd-string-search","02.cpp\u002F43.std-string-search",{"title":1889,"path":1890,"stem":1891},"std::string_view: невласницький погляд на рядок без копіювання","\u002Fcpp\u002Fstd-string-view","02.cpp\u002F44.std-string-view",{"title":1893,"path":1894,"stem":1895},"Об'єднання (union): один блок пам'яті, кілька інтерпретацій","\u002Fcpp\u002Funion","02.cpp\u002F45.union",{"title":1897,"path":1898,"stem":1899},"Організація коду: файли, препроцесор, простори імен","\u002Fcpp\u002Fmultifile-programs","02.cpp\u002F46.multifile-programs",{"title":1901,"path":1902,"stem":1903},"Робота з файлами: C-стиль (stdio.h)","\u002Fcpp\u002Fc-style-files","02.cpp\u002F47.c-style-files",{"title":1905,"path":1906,"stem":1907},"Робота з файлами: C++-стиль (fstream)","\u002Fcpp\u002Fcpp-style-files","02.cpp\u002F48.cpp-style-files",{"title":1909,"path":1910,"stem":1911},"План навчання: Курс C++ — Продовження (Статті 29–60+)","\u002Fcpp\u002Fcurriculum-plan","02.cpp\u002Fcurriculum-plan",{"title":1913,"icon":1914,"path":1915,"stem":1916,"children":1917,"page":59},"JavaScript","i-devicon-javascript","\u002Fjavascript","03.javascript",[1918,1944,1998,2020,2324,2362],{"title":1919,"icon":1920,"path":1921,"stem":1922,"children":1923,"page":59},"Events","i-lucide-mouse-pointer-click","\u002Fjavascript\u002Fevents","03.javascript\u002F01.events",[1924,1928,1932,1936,1940],{"title":1925,"path":1926,"stem":1927},"Вступ до подій браузера","\u002Fjavascript\u002Fevents\u002Fintro","03.javascript\u002F01.events\u002F01.intro",{"title":1929,"path":1930,"stem":1931},"Бульбашковий механізм (Bubbling) та занурення (Capturing)","\u002Fjavascript\u002Fevents\u002Fbubbling-capturing","03.javascript\u002F01.events\u002F02.bubbling-capturing",{"title":1933,"path":1934,"stem":1935},"Делегування подій (Event Delegation)","\u002Fjavascript\u002Fevents\u002Fdelegate-events","03.javascript\u002F01.events\u002F03.delegate-events",{"title":1937,"path":1938,"stem":1939},"Типові дії браузера та preventDefault()","\u002Fjavascript\u002Fevents\u002Fprevent-default","03.javascript\u002F01.events\u002F04.prevent-default",{"title":1941,"path":1942,"stem":1943},"Запуск користувацьких подій (Custom Events)","\u002Fjavascript\u002Fevents\u002Fcustom-events","03.javascript\u002F01.events\u002F05.custom-events",{"title":1945,"icon":1946,"path":1947,"stem":1948,"children":1949,"page":59},"Network","i-lucide-globe","\u002Fjavascript\u002Fnetwork","03.javascript\u002F02.network",[1950,1954,1958,1962,1966,1970,1974,1978,1982,1986,1990,1994],{"title":1951,"path":1952,"stem":1953},"Fetch API - Сучасний підхід до HTTP-запитів","\u002Fjavascript\u002Fnetwork\u002F01-fetch-api","03.javascript\u002F02.network\u002F01-fetch-api",{"title":1955,"path":1956,"stem":1957},"FormData - Робота з формами та файлами","\u002Fjavascript\u002Fnetwork\u002F02-formdata","03.javascript\u002F02.network\u002F02-formdata",{"title":1959,"path":1960,"stem":1961},"Відстеження прогресу завантаження","\u002Fjavascript\u002Fnetwork\u002F03-download-progress","03.javascript\u002F02.network\u002F03-download-progress",{"title":1963,"path":1964,"stem":1965},"Переривання fetch-запитів","\u002Fjavascript\u002Fnetwork\u002F04-abort-requests","03.javascript\u002F02.network\u002F04-abort-requests",{"title":1967,"path":1968,"stem":1969},"CORS - Запити між різними джерелами","\u002Fjavascript\u002Fnetwork\u002F05-cors","03.javascript\u002F02.network\u002F05-cors",{"title":1971,"path":1972,"stem":1973},"Fetch API - Повний довідник опцій","\u002Fjavascript\u002Fnetwork\u002F06-fetch-options","03.javascript\u002F02.network\u002F06-fetch-options",{"title":1975,"path":1976,"stem":1977},"URL Objects - Робота з посиланнями","\u002Fjavascript\u002Fnetwork\u002F07-url-objects","03.javascript\u002F02.network\u002F07-url-objects",{"title":1979,"path":1980,"stem":1981},"XMLHttpRequest - AJAX та низькорівневі запити","\u002Fjavascript\u002Fnetwork\u002F08-xmlhttprequest","03.javascript\u002F02.network\u002F08-xmlhttprequest",{"title":1983,"path":1984,"stem":1985},"Відновлюване завантаження файлів","\u002Fjavascript\u002Fnetwork\u002F09-resumable-upload","03.javascript\u002F02.network\u002F09-resumable-upload",{"title":1987,"path":1988,"stem":1989},"Cookies, document.cookie та світ після \"Cookiepocalypse\"","\u002Fjavascript\u002Fnetwork\u002F10-cookies","03.javascript\u002F02.network\u002F10-cookies",{"title":1991,"path":1992,"stem":1993},"js-cookie: Керування Cookies без Болю","\u002Fjavascript\u002Fnetwork\u002F11-js-cookie","03.javascript\u002F02.network\u002F11-js-cookie",{"title":1995,"path":1996,"stem":1997},"Axios: Потужний HTTP-клієнт для JavaScript","\u002Fjavascript\u002Fnetwork\u002F12-axios","03.javascript\u002F02.network\u002F12-axios",{"title":1999,"icon":2000,"path":2001,"stem":2002,"children":2003,"page":59},"Bom","i-lucide-monitor","\u002Fjavascript\u002Fbom","03.javascript\u002F03.bom",[2004,2008,2012,2016],{"title":2005,"path":2006,"stem":2007},"LocalStorage, SessionStorage та patterns збереження даних","\u002Fjavascript\u002Fbom\u002F01-localstorage","03.javascript\u002F03.bom\u002F01-localstorage",{"title":2009,"path":2010,"stem":2011},"Location Object - Керування адресою сторінки","\u002Fjavascript\u002Fbom\u002F02-location-object","03.javascript\u002F03.bom\u002F02-location-object",{"title":2013,"path":2014,"stem":2015},"History API - Керування історією браузера","\u002Fjavascript\u002Fbom\u002F03-history-api","03.javascript\u002F03.bom\u002F03-history-api",{"title":2017,"path":2018,"stem":2019},"Navigator Object - Ідентифікація та Можливості Пристрою","\u002Fjavascript\u002Fbom\u002F04-navigator-object","03.javascript\u002F03.bom\u002F04-navigator-object",{"title":2021,"icon":2022,"path":2023,"stem":2024,"children":2025},"React","i-devicon-react","\u002Fjavascript\u002Freact","03.javascript\u002F04.react\u002Findex",[2026,2027,2031,2035,2039,2043,2106,2141,2293],{"title":2021,"path":2023,"stem":2024},{"title":2028,"path":2029,"stem":2030},"Робота з Формами в React","\u002Fjavascript\u002Freact\u002Freact-forms","03.javascript\u002F04.react\u002F01.react-forms",{"title":2032,"path":2033,"stem":2034},"React Hook Form: Професійна Робота з Формами","\u002Fjavascript\u002Freact\u002Freact-hook-form","03.javascript\u002F04.react\u002F02.react-hook-form",{"title":2036,"path":2037,"stem":2038},"React Hook Form: Глибоке Розуміння Архітектури та Оптимізації","\u002Fjavascript\u002Freact\u002Freact-hook-form-new","03.javascript\u002F04.react\u002F02.react-hook-form-new",{"title":2040,"path":2041,"stem":2042},"Axios та React: Професійна Архітектура Запитів","\u002Fjavascript\u002Freact\u002Fdata-fetching-axios","03.javascript\u002F04.react\u002F03.data-fetching-axios",{"title":2044,"icon":132,"path":2045,"stem":2046,"children":2047},"Tanstack Query","\u002Fjavascript\u002Freact\u002Ftanstack-query","03.javascript\u002F04.react\u002F04.tanstack-query\u002Findex",[2048,2050,2054,2058,2062,2066,2070,2074,2078,2082,2086,2090,2094,2098,2102],{"title":2049,"path":2045,"stem":2046},"TanStack Query: Майстерність Керування Станом Сервера",{"title":2051,"path":2052,"stem":2053},"Парадигма Server State: Чому useEffect недостатньо","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-state-paradigm","03.javascript\u002F04.react\u002F04.tanstack-query\u002F01.server-state-paradigm",{"title":2055,"path":2056,"stem":2057},"Встановлення та Налаштування: Фундамент","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Finstallation-and-devtools","03.javascript\u002F04.react\u002F04.tanstack-query\u002F02.installation-and-devtools",{"title":2059,"path":2060,"stem":2061},"Основи Запитів та Магія Ключів","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fquery-basics-and-keys","03.javascript\u002F04.react\u002F04.tanstack-query\u002F03.query-basics-and-keys",{"title":2063,"path":2064,"stem":2065},"Синхронізація Даних: Життєвий Цикл Запиту","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fdata-synchronization","03.javascript\u002F04.react\u002F04.tanstack-query\u002F04.data-synchronization",{"title":2067,"path":2068,"stem":2069},"Мутації та Інвалідація: Зміна Даних","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fmutations-and-invalidation","03.javascript\u002F04.react\u002F04.tanstack-query\u002F05.mutations-and-invalidation",{"title":2071,"path":2072,"stem":2073},"Оптимістичні Оновлення: Швидше за Світло","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Foptimistic-updates","03.javascript\u002F04.react\u002F04.tanstack-query\u002F06.optimistic-updates",{"title":2075,"path":2076,"stem":2077},"Пагінація та Infinite Scroll","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fpagination-and-load-more","03.javascript\u002F04.react\u002F04.tanstack-query\u002F07.pagination-and-load-more",{"title":2079,"path":2080,"stem":2081},"Просунуті Патерни та Оптимізація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F04.tanstack-query\u002F08.advanced-patterns",{"title":2083,"path":2084,"stem":2085},"Архітектура та Best Practices","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Farchitecture-and-best-practices","03.javascript\u002F04.react\u002F04.tanstack-query\u002F09.architecture-and-best-practices",{"title":2087,"path":2088,"stem":2089},"Server-Side Rendering (SSR) та Гідратація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-side-rendering","03.javascript\u002F04.react\u002F04.tanstack-query\u002F10.server-side-rendering",{"title":2091,"path":2092,"stem":2093},"Стратегії Тестування","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Ftesting-strategies","03.javascript\u002F04.react\u002F04.tanstack-query\u002F11.testing-strategies",{"title":2095,"path":2096,"stem":2097},"Аутентифікація та Обробка Помилок","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fauthentication-and-errors","03.javascript\u002F04.react\u002F04.tanstack-query\u002F12.authentication-and-errors",{"title":2099,"path":2100,"stem":2101},"React Suspense та Майбутнє","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Freact-suspense","03.javascript\u002F04.react\u002F04.tanstack-query\u002F13.react-suspense",{"title":2103,"path":2104,"stem":2105},"Глибоке Занурення в Продуктивність","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fperformance-deep-dive","03.javascript\u002F04.react\u002F04.tanstack-query\u002F14.performance-deep-dive",{"title":2107,"icon":2022,"path":2108,"stem":2109,"children":2110},"React Router","\u002Fjavascript\u002Freact\u002Freact-router","03.javascript\u002F04.react\u002F05.react-router\u002Findex",[2111,2113,2117,2121,2125,2129,2133,2137],{"title":2112,"path":2108,"stem":2109},"React Router: Навігаційна система сучасного вебу",{"title":2114,"path":2115,"stem":2116},"Налаштування та Базовий Роутинг","\u002Fjavascript\u002Freact\u002Freact-router\u002Fsetup-and-basic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F01.setup-and-basic-routing",{"title":2118,"path":2119,"stem":2120},"Динамічна Навігація","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnavigation-and-links","03.javascript\u002F04.react\u002F05.react-router\u002F02.navigation-and-links",{"title":2122,"path":2123,"stem":2124},"Вкладені Маршрути та Макети","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnested-routes-and-layouts","03.javascript\u002F04.react\u002F05.react-router\u002F03.nested-routes-and-layouts",{"title":2126,"path":2127,"stem":2128},"Динамічні Маршрути та Параметри","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdynamic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F04.dynamic-routing",{"title":2130,"path":2131,"stem":2132},"Data APIs: Loaders та Actions","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdata-loading","03.javascript\u002F04.react\u002F05.react-router\u002F05.data-loading",{"title":2134,"path":2135,"stem":2136},"Просунуті Патерни","\u002Fjavascript\u002Freact\u002Freact-router\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F05.react-router\u002F06.advanced-patterns",{"title":2138,"path":2139,"stem":2140},"Legacy Routing: Компонентний підхід","\u002Fjavascript\u002Freact\u002Freact-router\u002Flegacy-routing","03.javascript\u002F04.react\u002F05.react-router\u002F07.legacy-routing",{"title":2142,"icon":132,"path":2143,"stem":2144,"children":2145},"Redux","\u002Fjavascript\u002Freact\u002Fredux","03.javascript\u002F04.react\u002F06.redux\u002Findex",[2146,2148,2164,2193,2202,2223,2239,2268],{"title":2147,"path":2143,"stem":2144},"Redux: Еволюція управління станом",{"title":14,"icon":15,"path":2149,"stem":2150,"children":2151,"page":59},"\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals",[2152,2156,2160],{"title":2153,"path":2154,"stem":2155},"Вступ до State Management","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fintro-state-management","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F01.intro-state-management",{"title":2157,"path":2158,"stem":2159},"Філософія Redux та Три Принципи","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fredux-philosophy","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F02.redux-philosophy",{"title":2161,"path":2162,"stem":2163},"Чисті функції та Іммутабельність","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fpure-functions-immutability","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F03.pure-functions-immutability",{"title":2165,"icon":132,"path":2166,"stem":2167,"children":2168,"page":59},"Classic Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux",[2169,2173,2177,2181,2185,2189],{"title":2170,"path":2171,"stem":2172},"Створення Store (Classic Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fstore-setup","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F01.store-setup",{"title":2174,"path":2175,"stem":2176},"Actions, Constants та Action Creators","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Factions-constants","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F02.actions-constants",{"title":2178,"path":2179,"stem":2180},"Логіка Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freducers","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F03.reducers",{"title":2182,"path":2183,"stem":2184},"Комбінування Reducers (Root Reducer)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fdata-flow","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F04.data-flow",{"title":2186,"path":2187,"stem":2188},"Підключення до React (React-Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freact-redux-connection","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F05.react-redux-connection",{"title":2190,"path":2191,"stem":2192},"Middleware та Асинхронність (Redux Thunk)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fmiddleware-thunk","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F06.middleware-thunk",{"title":2194,"icon":132,"path":2195,"stem":2196,"children":2197,"page":59},"Transition To Rtk","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk",[2198],{"title":2199,"path":2200,"stem":2201},"Проблеми класичного Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk\u002Fproblems-with-classic","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk\u002F01.problems-with-classic",{"title":2203,"icon":132,"path":2204,"stem":2205,"children":2206,"page":59},"Redux Toolkit","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit",[2207,2211,2215,2219],{"title":2208,"path":2209,"stem":2210},"Налаштування Store з configureStore","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fconfigure-store","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F01.configure-store",{"title":2212,"path":2213,"stem":2214},"createSlice: Революція в Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fcreate-slice","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F02.create-slice",{"title":2216,"path":2217,"stem":2218},"Асинхронність з createAsyncThunk","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fasync-thunks","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F03.async-thunks",{"title":2220,"path":2221,"stem":2222},"04. Entity Adapter: Керування нормалізованим станом","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fentity-adapter","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F04.entity-adapter",{"title":2224,"icon":92,"path":2225,"stem":2226,"children":2227,"page":59},"Advanced","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced",[2228,2232,2236],{"title":2229,"path":2230,"stem":2231},"Мемоізація та Селектори: Повний Гайд по Reselect","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Fselectors-reselect","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F01.selectors-reselect",{"title":2233,"path":2234,"stem":2235},"RTK Query: Архітектура Серверного Кешу","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Frtk-query-intro","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F02.rtk-query-intro",{"title":2083,"path":2237,"stem":2238},"\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Farchitecture-best-practices","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F03.architecture-best-practices",{"title":2240,"icon":132,"path":2241,"stem":2242,"children":2243,"page":59},"Project Kanban","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban",[2244,2248,2252,2256,2260,2264],{"title":2245,"path":2246,"stem":2247},"Проєкт: Kanban Board (Trello Clone)","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fproject-overview","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F01.project-overview",{"title":2249,"path":2250,"stem":2251},"Налаштування та Типізація","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fsetup-and-types","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F02.setup-and-types",{"title":2253,"path":2254,"stem":2255},"Board Slice: Серце Дошки","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fboard-slice","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F03.board-slice",{"title":2257,"path":2258,"stem":2259},"Логіка Drag & Drop","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fdrag-and-drop-logic","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F04.drag-and-drop-logic",{"title":2261,"path":2262,"stem":2263},"Інтеграція з RTK Query","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Frtk-query-integration","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F05.rtk-query-integration",{"title":2265,"path":2266,"stem":2267},"Optimistic Updates","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Foptimistic-updates","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F06.optimistic-updates",{"title":2269,"icon":132,"path":2270,"stem":2271,"children":2272,"page":59},"Testing","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting","03.javascript\u002F04.react\u002F06.redux\u002F07.testing",[2273,2277,2281,2285,2289],{"title":2274,"path":2275,"stem":2276},"Тестування Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Fintro-testing","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F01.intro-testing",{"title":2278,"path":2279,"stem":2280},"Тестування Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-reducers","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F02.testing-reducers",{"title":2282,"path":2283,"stem":2284},"Тестування Селекторів","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-selectors","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F03.testing-selectors",{"title":2286,"path":2287,"stem":2288},"Тестування Компонентів (Integration)","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-components","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F04.testing-components",{"title":2290,"path":2291,"stem":2292},"Тестування Async Thunks","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-thunks","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F05.testing-thunks",{"title":2294,"icon":132,"path":2295,"stem":2296,"children":2297},"Ui Libraries","\u002Fjavascript\u002Freact\u002Fui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002Findex",[2298,2300,2304,2308,2312,2316,2320],{"title":2299,"path":2295,"stem":2296},"UI Бібліотеки в React",{"title":2301,"path":2302,"stem":2303},"Вступ до UI Бібліотек: Навіщо Винаходити Велосипед Двічі?","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fintroduction-to-ui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002F01.introduction-to-ui-libraries",{"title":2305,"path":2306,"stem":2307},"Філософія shadcn\u002Fui: \"Not a Component Library\"","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-philosophy","03.javascript\u002F04.react\u002F07.ui-libraries\u002F02.shadcn-philosophy",{"title":2309,"path":2310,"stem":2311},"Установка та Налаштування shadcn\u002Fui","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-installation","03.javascript\u002F04.react\u002F07.ui-libraries\u002F03.shadcn-installation",{"title":2313,"path":2314,"stem":2315},"Базові Компоненти shadcn\u002Fui: Фундамент Інтерфейсу","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-basics","03.javascript\u002F04.react\u002F07.ui-libraries\u002F04.shadcn-components-basics",{"title":2317,"path":2318,"stem":2319},"Компоненти Форм: Побудова Інтерактивних Form","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-forms","03.javascript\u002F04.react\u002F07.ui-libraries\u002F05.shadcn-components-forms",{"title":2321,"path":2322,"stem":2323},"Складні Компоненти: Dialog, Dropdown, Table та Command","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-advanced","03.javascript\u002F04.react\u002F07.ui-libraries\u002F06.shadcn-components-advanced",{"title":2325,"icon":2326,"path":2327,"stem":2328,"children":2329,"page":59},"TypeScript","i-devicon-typescript","\u002Fjavascript\u002Ftypescript","03.javascript\u002F05.typescript",[2330,2334,2338,2342,2346,2350,2354,2358],{"title":2331,"path":2332,"stem":2333},"TypeScript: Броня для вашого коду","\u002Fjavascript\u002Ftypescript\u002Fintro-and-basic-types","03.javascript\u002F05.typescript\u002F01.intro-and-basic-types",{"title":2335,"path":2336,"stem":2337},"Майстерність Моделювання Даних: Інтерфейси та Просунуті Типи","\u002Fjavascript\u002Ftypescript\u002Finterfaces-and-advanced-types","03.javascript\u002F05.typescript\u002F02.interfaces-and-advanced-types",{"title":2339,"path":2340,"stem":2341},"Алхімія Типів: Generics та Utility Types","\u002Fjavascript\u002Ftypescript\u002Fgenerics-and-utilities","03.javascript\u002F05.typescript\u002F03.generics-and-utilities",{"title":2343,"path":2344,"stem":2345},"Архітектура та Шаблони: Класи в TypeScript","\u002Fjavascript\u002Ftypescript\u002Fclasses-and-oop","03.javascript\u002F05.typescript\u002F04.classes-and-oop",{"title":2347,"path":2348,"stem":2349},"Продакшн та Екосистема: Advanced Config & Workflow","\u002Fjavascript\u002Ftypescript\u002Fadvanced-patterns-and-config","03.javascript\u002F05.typescript\u002F05.advanced-patterns-and-config",{"title":2351,"path":2352,"stem":2353},"TypeScript у світі React","\u002Fjavascript\u002Ftypescript\u002Freact-basics","03.javascript\u002F05.typescript\u002F06.react-basics",{"title":2355,"path":2356,"stem":2357},"React + TypeScript: Продвинуті патерни","\u002Fjavascript\u002Ftypescript\u002Freact-advanced","03.javascript\u002F05.typescript\u002F07.react-advanced",{"title":2359,"path":2360,"stem":2361},"React + TypeScript: Екосистема та бібліотеки","\u002Fjavascript\u002Ftypescript\u002Freact-ecosystem","03.javascript\u002F05.typescript\u002F08.react-ecosystem",{"title":2363,"path":2364,"stem":2365},"Atomic Design","\u002Fjavascript\u002Fatomic-design","03.javascript\u002F2.atomic-design",{"title":2367,"icon":2368,"path":2369,"stem":2370,"children":2371,"page":59},"Java","i-devicon-java","\u002Fjava","04.java",[2372,2375,2378,2382,2386,2390,2394],{"title":162,"path":2373,"stem":2374},"\u002Fjava\u002Fdata-mapper-part1","04.java\u002F01.data-mapper-part1",{"title":166,"path":2376,"stem":2377},"\u002Fjava\u002Fdata-mapper-part2","04.java\u002F02.data-mapper-part2",{"title":2379,"path":2380,"stem":2381},"Service Layer: Організація бізнес-логіки","\u002Fjava\u002Fservice-layer","04.java\u002F03.service-layer",{"title":2383,"path":2384,"stem":2385},"Rich Domain Model та State Pattern","\u002Fjava\u002Frich-domain-model","04.java\u002F04.rich-domain-model",{"title":2387,"path":2388,"stem":2389},"Патерни для складної бізнес-логіки","\u002Fjava\u002Fbusiness-logic-patterns","04.java\u002F05.business-logic-patterns",{"title":2391,"path":2392,"stem":2393},"Обробка помилок та валідація","\u002Fjava\u002Ferror-handling-validation","04.java\u002F06.error-handling-validation",{"title":2395,"path":2396,"stem":2397,"children":2398,"page":59},"Проектування баз даних","\u002Fjava\u002Fpr2","04.java\u002Fpr2",[2399,2403,2407,2411,2415,2419,2423,2427,2431,2435,2439,2443,2447,2451,2455,2459,2463,2467,2471,2475,2479,2483,2487,2491,2495,2499,2503,2507,2511,2515,2519,2523,2527,2531,2535,2539,2543],{"title":2400,"path":2401,"stem":2402},"Концептуальне моделювання: Мистецтво розуміння предметної області","\u002Fjava\u002Fpr2\u002Fconceptual-modeling","04.java\u002Fpr2\u002F01.conceptual-modeling",{"title":2404,"path":2405,"stem":2406},"Логічне моделювання: Від бізнес-ідей до структур даних","\u002Fjava\u002Fpr2\u002Flogical-modeling","04.java\u002Fpr2\u002F02.logical-modeling",{"title":2408,"path":2409,"stem":2410},"Нормалізація: Гігієна даних та боротьба з аномаліями","\u002Fjava\u002Fpr2\u002Fnormalization","04.java\u002Fpr2\u002F03.normalization",{"title":2412,"path":2413,"stem":2414},"Фізична схема: Від абстракції до DDL","\u002Fjava\u002Fpr2\u002Fphysical-schema","04.java\u002Fpr2\u002F04.physical-schema",{"title":2416,"path":2417,"stem":2418},"Архітектурна класифікація таблиць","\u002Fjava\u002Fpr2\u002Ftable-classification","04.java\u002Fpr2\u002F05.table-classification",{"title":2420,"path":2421,"stem":2422},"Database Migrations: Версіонування схеми з Flyway","\u002Fjava\u002Fpr2\u002Fdatabase-migrations","04.java\u002Fpr2\u002F06.database-migrations",{"title":2424,"path":2425,"stem":2426},"А що, якби це була не реляційна БД?","\u002Fjava\u002Fpr2\u002Fbeyond-relational","04.java\u002Fpr2\u002F07.beyond-relational",{"title":2428,"path":2429,"stem":2430},"Object-Relational Impedance Mismatch: Два світи, що не хочуть дружити","\u002Fjava\u002Fpr2\u002Fimpedance-mismatch","04.java\u002Fpr2\u002F09.impedance-mismatch",{"title":2432,"path":2433,"stem":2434},"JDBC: Перший контакт із базою даних","\u002Fjava\u002Fpr2\u002Fjdbc-fundamentals","04.java\u002Fpr2\u002F10.jdbc-fundamentals",{"title":2436,"path":2437,"stem":2438},"Якість коду: Spotless, SpotBugs та SonarQube","\u002Fjava\u002Fpr2\u002F10a.code-quality","04.java\u002Fpr2\u002F10a.code-quality",{"title":2440,"path":2441,"stem":2442},"Connection Pool: Патерн Object Pool для JDBC-з'єднань","\u002Fjava\u002Fpr2\u002Fconnection-pool","04.java\u002Fpr2\u002F11.connection-pool",{"title":2444,"path":2445,"stem":2446},"Row Data Gateway: Об'єкт як обгортка рядка таблиці","\u002Fjava\u002Fpr2\u002Frow-data-gateway","04.java\u002Fpr2\u002F12.row-data-gateway",{"title":2448,"path":2449,"stem":2450},"Table Data Gateway: Фасад таблиці як архітектурний відступ","\u002Fjava\u002Fpr2\u002Ftable-data-gateway","04.java\u002Fpr2\u002F13.table-data-gateway",{"title":2452,"path":2453,"stem":2454},"Repository + Data Mapper: Правильна шарова архітектура з JDBC","\u002Fjava\u002Fpr2\u002Frepository-data-mapper","04.java\u002Fpr2\u002F14.repository-data-mapper",{"title":2456,"path":2457,"stem":2458},"Identity Map: Кешування сутностей у рамках сесії","\u002Fjava\u002Fpr2\u002Fidentity-map","04.java\u002Fpr2\u002F15.identity-map",{"title":2460,"path":2461,"stem":2462},"Unit of Work: Відстеження змін і координація JDBC-транзакцій","\u002Fjava\u002Fpr2\u002Funit-of-work","04.java\u002Fpr2\u002F16.unit-of-work",{"title":2464,"path":2465,"stem":2466},"Strategy: Замінювані SQL-стратегії для підтримки різних СУБД","\u002Fjava\u002Fpr2\u002Fstrategy-sql","04.java\u002Fpr2\u002F17.strategy-sql",{"title":2468,"path":2469,"stem":2470},"Proxy: Lazy Loading для One-To-Many колекцій","\u002Fjava\u002Fpr2\u002Fproxy-lazy-loading","04.java\u002Fpr2\u002F18.proxy-lazy-loading",{"title":2472,"path":2473,"stem":2474},"Generic Repository через Java Reflection: анотації та динамічний SQL","\u002Fjava\u002Fpr2\u002Fgeneric-repository-reflection","04.java\u002Fpr2\u002F19.generic-repository-reflection",{"title":2476,"path":2477,"stem":2478},"Specification Pattern: Композиція бізнес-правил для складних запитів","\u002Fjava\u002Fpr2\u002Fspecification-pattern","04.java\u002Fpr2\u002F20.specification-pattern",{"title":2480,"path":2481,"stem":2482},"Розширені можливості Specification Pattern: підзапити, агрегації та гібридний підхід","\u002Fjava\u002Fpr2\u002F20a.advanced-specifications","04.java\u002Fpr2\u002F20a.advanced-specifications",{"title":2484,"path":2485,"stem":2486},"Асинхронність у JDBC: Від блокуючих викликів до CompletableFuture","\u002Fjava\u002Fpr2\u002Fasynchronous-jdbc","04.java\u002Fpr2\u002F21.asynchronous-jdbc",{"title":2488,"path":2489,"stem":2490},"Інтеграційне тестування JDBC-репозиторіїв: Embedded H2 та патерн AAA","\u002Fjava\u002Fpr2\u002Fintegration-testing-h2","04.java\u002Fpr2\u002F22.integration-testing-h2",{"title":2492,"path":2493,"stem":2494},"Testcontainers: Тестування з реальною PostgreSQL у Docker-контейнерах","\u002Fjava\u002Fpr2\u002Fintegration-testing-testcontainers","04.java\u002Fpr2\u002F23.integration-testing-testcontainers",{"title":2496,"path":2497,"stem":2498},"Google Guice: Впровадження залежностей у JavaFX-проєкті","\u002Fjava\u002Fpr2\u002Fdependency-injection-guice","04.java\u002Fpr2\u002F24.dependency-injection-guice",{"title":2500,"path":2501,"stem":2502},"JavaFX: Основи побудови графічних інтерфейсів","\u002Fjava\u002Fpr2\u002Fjavafx-fundamentals","04.java\u002Fpr2\u002F25.javafx-fundamentals",{"title":2504,"path":2505,"stem":2506},"Properties та Bindings: Реактивність у JavaFX","\u002Fjava\u002Fpr2\u002Fjavafx-properties-bindings","04.java\u002Fpr2\u002F26.javafx-properties-bindings",{"title":2508,"path":2509,"stem":2510},"MVC vs MVP vs MVVM: Еволюція архітектурних патернів UI","\u002Fjava\u002Fpr2\u002Fui-architecture-patterns","04.java\u002Fpr2\u002F27.ui-architecture-patterns",{"title":2512,"path":2513,"stem":2514},"MVVM на практиці: Побудова ViewModel","\u002Fjava\u002Fpr2\u002Fmvvm-viewmodel-implementation","04.java\u002Fpr2\u002F28.mvvm-viewmodel-implementation",{"title":2516,"path":2517,"stem":2518},"View та Controller: Зв'язування з ViewModel через FXML","\u002Fjava\u002Fpr2\u002Fmvvm-view-controller","04.java\u002Fpr2\u002F29.mvvm-view-controller",{"title":2520,"path":2521,"stem":2522},"Інтеграція MVVM з Guice: Автоматична ін'єкція залежностей","\u002Fjava\u002Fpr2\u002Fmvvm-guice-integration","04.java\u002Fpr2\u002F30.mvvm-guice-integration",{"title":2524,"path":2525,"stem":2526},"Валідація та обробка помилок у MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-validation-error-handling","04.java\u002Fpr2\u002F31.mvvm-validation-error-handling",{"title":2528,"path":2529,"stem":2530},"Навігація та управління екранами у JavaFX MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-navigation-screen-management","04.java\u002Fpr2\u002F32.mvvm-navigation-screen-management",{"title":2532,"path":2533,"stem":2534},"Тестування JavaFX MVVM-додатків","\u002Fjava\u002Fpr2\u002Fmvvm-testing","04.java\u002Fpr2\u002F33.mvvm-testing",{"title":2536,"path":2537,"stem":2538},"Стилізація та теми у JavaFX: CSS та User Experience","\u002Fjava\u002Fpr2\u002Fjavafx-styling-themes","04.java\u002Fpr2\u002F34.javafx-styling-themes",{"title":2540,"path":2541,"stem":2542},"AtlantaFX: Сучасні теми для JavaFX додатків","\u002Fjava\u002Fpr2\u002Fatlantafx-modern-themes","04.java\u002Fpr2\u002F35.atlantafx-modern-themes",{"title":2544,"path":2545,"stem":2546},"Пакування та розповсюдження JavaFX-додатків","\u002Fjava\u002Fpr2\u002Fjar-packaging-distribution","04.java\u002Fpr2\u002F36.jar-packaging-distribution",{"title":2548,"icon":2549,"path":2550,"stem":2551,"children":2552,"page":59},"Python","i-devicon-python","\u002Fpython","05.python",[2553,2557,2560,2564,2568,2572,2576,2580,2584,2588,2592,2596,2600,2604,2608,2669],{"title":2554,"path":2555,"stem":2556},"Модулі, Пакети та Віртуальні Середовища","\u002Fpython\u002Fmodules-packages-venv","05.python\u002F00.modules-packages-venv",{"title":71,"path":2558,"stem":2559},"\u002Fpython\u002Fclasses-objects","05.python\u002F01.classes-objects",{"title":2561,"path":2562,"stem":2563},"Інкапсуляція, Керування Доступом та Властивості","\u002Fpython\u002Fencapsulation","05.python\u002F02.encapsulation",{"title":2565,"path":2566,"stem":2567},"Наслідування, MRO та суперсила super()","\u002Fpython\u002Finheritance-mro","05.python\u002F03.inheritance-mro",{"title":2569,"path":2570,"stem":2571},"Абстракція — ABC проти Статичних Протоколів (PEP 544)","\u002Fpython\u002Fabstraction-protocols","05.python\u002F04.abstraction-protocols",{"title":2573,"path":2574,"stem":2575},"Магічні методи (Dunder) та Емуляція протоколів","\u002Fpython\u002Fdunder-methods","05.python\u002F05.dunder-methods",{"title":2577,"path":2578,"stem":2579},"Декоратори та Керування життєвим циклом методів","\u002Fpython\u002Fdecorators-static-class","05.python\u002F06.decorators-static-class",{"title":2581,"path":2582,"stem":2583},"Дескриптори — Магія доступу до атрибутів","\u002Fpython\u002Fdescriptors","05.python\u002F07.descriptors",{"title":2585,"path":2586,"stem":2587},"Метакласи — Динамічне створення класів під капотом CPython","\u002Fpython\u002Fmetaclasses","05.python\u002F08.metaclasses",{"title":2589,"path":2590,"stem":2591},"Dataclasses, NamedTuple та сучасні контейнери Python","\u002Fpython\u002Fmodern-containers","05.python\u002F09.modern-containers",{"title":2593,"path":2594,"stem":2595},"GIL та модель конкурентності CPython — фундамент перед потоками і процесами","\u002Fpython\u002Fgil-concurrency-intro","05.python\u002F11.gil-concurrency-intro",{"title":2597,"path":2598,"stem":2599},"Threading — конкурентність для I\u002FO-bound задач","\u002Fpython\u002Fthreading","05.python\u002F12.threading",{"title":2601,"path":2602,"stem":2603},"Multiprocessing — справжній паралелізм для CPU-bound задач","\u002Fpython\u002Fmultiprocessing","05.python\u002F13.multiprocessing",{"title":2605,"path":2606,"stem":2607},"asyncio — кооперативна конкурентність та event loop","\u002Fpython\u002Fasyncio","05.python\u002F14.asyncio",{"title":2609,"icon":92,"path":2610,"stem":2611,"children":2612,"page":59},"FastAPI","\u002Fpython\u002Ffastapi","05.python\u002Ffastapi",[2613,2617,2621,2625,2629,2633,2637,2641,2645,2649,2653,2657,2661,2665],{"title":2614,"path":2615,"stem":2616},"Глибокий Typing та Pydantic v2 — від анотацій до валідації","\u002Fpython\u002Ffastapi\u002Ftyping-pydantic","05.python\u002Ffastapi\u002F15.typing-pydantic",{"title":2618,"path":2619,"stem":2620},"WSGI, ASGI та Python Web-екосистема","\u002Fpython\u002Ffastapi\u002Fwsgi-asgi-ecosystem","05.python\u002Ffastapi\u002F16.wsgi-asgi-ecosystem",{"title":2622,"path":2623,"stem":2624},"FastAPI: Перший додаток, Uvicorn та OpenAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-intro","05.python\u002Ffastapi\u002F17.fastapi-intro",{"title":2626,"path":2627,"stem":2628},"Маршрутизація, параметри запитів та APIRouter","\u002Fpython\u002Ffastapi\u002Ffastapi-routing-params","05.python\u002Ffastapi\u002F18.fastapi-routing-params",{"title":2630,"path":2631,"stem":2632},"Pydantic v2 у FastAPI — схеми, валідація та серіалізація","\u002Fpython\u002Ffastapi\u002Ffastapi-pydantic-schemas","05.python\u002Ffastapi\u002F19.fastapi-pydantic-schemas",{"title":2634,"path":2635,"stem":2636},"Dependency Injection — серце архітектури FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-dependency-injection","05.python\u002Ffastapi\u002F20.fastapi-dependency-injection",{"title":2638,"path":2639,"stem":2640},"Обробка помилок, Middleware та CORS у FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-errors-middleware","05.python\u002Ffastapi\u002F21.fastapi-errors-middleware",{"title":2642,"path":2643,"stem":2644},"SQLAlchemy 2.0 — ORM, Core та Async Engine","\u002Fpython\u002Ffastapi\u002Fsqlalchemy-orm","05.python\u002Ffastapi\u002F22.sqlalchemy-orm",{"title":2646,"path":2647,"stem":2648},"Alembic — міграції бази даних","\u002Fpython\u002Ffastapi\u002Falembic-migrations","05.python\u002Ffastapi\u002F23.alembic-migrations",{"title":2650,"path":2651,"stem":2652},"Repository Pattern та Clean Architecture у FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-repository-clean-arch","05.python\u002Ffastapi\u002F24.fastapi-repository-clean-arch",{"title":2654,"path":2655,"stem":2656},"Автентифікація та авторизація — JWT, OAuth2, RBAC","\u002Fpython\u002Ffastapi\u002Ffastapi-auth-security","05.python\u002Ffastapi\u002F25.fastapi-auth-security",{"title":2658,"path":2659,"stem":2660},"Тестування FastAPI — pytest, httpx, fixtures","\u002Fpython\u002Ffastapi\u002Ffastapi-testing","05.python\u002Ffastapi\u002F26.fastapi-testing",{"title":2662,"path":2663,"stem":2664},"Async на повну — Background Tasks, WebSockets, SSE та Celery","\u002Fpython\u002Ffastapi\u002Ffastapi-async-advanced","05.python\u002Ffastapi\u002F27.fastapi-async-advanced",{"title":2666,"path":2667,"stem":2668},"Deployment — Docker, CI\u002FCD, Monitoring","\u002Fpython\u002Ffastapi\u002Ffastapi-deployment","05.python\u002Ffastapi\u002F28.fastapi-deployment",{"title":2670,"path":2671,"stem":2672},"[object Object]","\u002Fpython\u002Foop-plan","05.python\u002Foop-plan",{"title":2674,"icon":2675,"path":2676,"stem":2677,"children":2678,"page":59},"Бази даних","i-lucide-database","\u002Fdatabases","06.databases",[2679,2709,2732,2769,2798,2816,2850,2862,2871],{"title":2680,"icon":2681,"path":2682,"stem":2683,"children":2684,"page":59},"Intro","i-lucide-play","\u002Fdatabases\u002Fintro","06.databases\u002F01.intro",[2685,2689,2693,2697,2701,2705],{"title":2686,"path":2687,"stem":2688},"Введення в теорію баз даних","\u002Fdatabases\u002Fintro\u002Fintroduction-to-databases","06.databases\u002F01.intro\u002F01.introduction-to-databases",{"title":2690,"path":2691,"stem":2692},"Реляційна модель даних","\u002Fdatabases\u002Fintro\u002Frelational-model-theory","06.databases\u002F01.intro\u002F02.relational-model-theory",{"title":2694,"path":2695,"stem":2696},"ER-моделювання","\u002Fdatabases\u002Fintro\u002Fer-modeling","06.databases\u002F01.intro\u002F03.er-modeling",{"title":2698,"path":2699,"stem":2700},"Логічне проектування БД","\u002Fdatabases\u002Fintro\u002Flogical-schema","06.databases\u002F01.intro\u002F04.logical-schema",{"title":2702,"path":2703,"stem":2704},"Класифікація таблиць","\u002Fdatabases\u002Fintro\u002Ftable-classification","06.databases\u002F01.intro\u002F05.table-classification",{"title":2706,"path":2707,"stem":2708},"PlantUML для баз даних","\u002Fdatabases\u002Fintro\u002Fplantuml-diagrams","06.databases\u002F01.intro\u002F06.plantuml-diagrams",{"title":2710,"icon":2675,"path":2711,"stem":2712,"children":2713,"page":59},"MS SQL Server Start","\u002Fdatabases\u002Fms-sql-server-start","06.databases\u002F02.ms-sql-server-start",[2714,2718,2724,2728],{"title":2715,"path":2716,"stem":2717},"Типи даних у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fdata-types","06.databases\u002F02.ms-sql-server-start\u002F01.data-types",{"title":2719,"path":2720,"stem":2721,"children":2722},"Індекси у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-indexes","06.databases\u002F02.ms-sql-server-start\u002F02.sql-indexes",[2723],{"title":2719,"path":2720,"stem":2721},{"title":2725,"path":2726,"stem":2727},"Системні бази даних MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsystem-databases","06.databases\u002F02.ms-sql-server-start\u002F03.system-databases",{"title":2729,"path":2730,"stem":2731},"Огляд мови SQL та запитів","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-queries-overview","06.databases\u002F02.ms-sql-server-start\u002F04.sql-queries-overview",{"title":2733,"icon":2675,"path":2734,"stem":2735,"children":2736,"page":59},"SQL","\u002Fdatabases\u002Fsql","06.databases\u002F03.sql",[2737,2741,2745,2749,2753,2757,2761,2765],{"title":2738,"path":2739,"stem":2740},"Налаштування демонстраційної бази даних","\u002Fdatabases\u002Fsql\u002Fsample-database-setup","06.databases\u002F03.sql\u002F00.sample-database-setup",{"title":2742,"path":2743,"stem":2744},"DDL - Створення таблиць (CREATE TABLE)","\u002Fdatabases\u002Fsql\u002Fddl-create-table","06.databases\u002F03.sql\u002F01.ddl-create-table",{"title":2746,"path":2747,"stem":2748},"DDL - Зміна та видалення таблиць (ALTER, DROP)","\u002Fdatabases\u002Fsql\u002Fddl-alter-drop-table","06.databases\u002F03.sql\u002F02.ddl-alter-drop-table",{"title":2750,"path":2751,"stem":2752},"SELECT запити - Основи","\u002Fdatabases\u002Fsql\u002Fselect-queries-fundamentals","06.databases\u002F03.sql\u002F03.select-queries-fundamentals",{"title":2754,"path":2755,"stem":2756},"SELECT запити - Розширені можливості","\u002Fdatabases\u002Fsql\u002Fselect-queries-advanced","06.databases\u002F03.sql\u002F04.select-queries-advanced",{"title":2758,"path":2759,"stem":2760},"INSERT запити - Додавання даних","\u002Fdatabases\u002Fsql\u002Finsert-queries","06.databases\u002F03.sql\u002F05.insert-queries",{"title":2762,"path":2763,"stem":2764},"UPDATE та DELETE запити","\u002Fdatabases\u002Fsql\u002Fupdate-delete-queries","06.databases\u002F03.sql\u002F06.update-delete-queries",{"title":2766,"path":2767,"stem":2768},"Транзакції в SQL","\u002Fdatabases\u002Fsql\u002Ftransactions","06.databases\u002F03.sql\u002F07.transactions",{"title":2770,"icon":2675,"path":2771,"stem":2772,"children":2773,"page":59},"Multi Table Databases","\u002Fdatabases\u002Fmulti-table-databases","06.databases\u002F04.multi-table-databases",[2774,2778,2782,2786,2790,2794],{"title":2775,"path":2776,"stem":2777},"Зв'язки та нормалізація БД","\u002Fdatabases\u002Fmulti-table-databases\u002Frelationships-and-normalization","06.databases\u002F04.multi-table-databases\u002F00.relationships-and-normalization",{"title":2779,"path":2780,"stem":2781},"INNER JOIN - З'єднання таблиць","\u002Fdatabases\u002Fmulti-table-databases\u002Finner-join","06.databases\u002F04.multi-table-databases\u002F01.inner-join",{"title":2783,"path":2784,"stem":2785},"OUTER JOINs - LEFT, RIGHT, FULL","\u002Fdatabases\u002Fmulti-table-databases\u002Fouter-joins","06.databases\u002F04.multi-table-databases\u002F02.outer-joins",{"title":2787,"path":2788,"stem":2789},"CROSS та SELF JOINs","\u002Fdatabases\u002Fmulti-table-databases\u002Fcross-self-joins","06.databases\u002F04.multi-table-databases\u002F03.cross-self-joins",{"title":2791,"path":2792,"stem":2793},"Підзапити (Subqueries)","\u002Fdatabases\u002Fmulti-table-databases\u002Fsubqueries","06.databases\u002F04.multi-table-databases\u002F04.subqueries",{"title":2795,"path":2796,"stem":2797},"Агрегації з JOIN","\u002Fdatabases\u002Fmulti-table-databases\u002Faggregations-with-joins","06.databases\u002F04.multi-table-databases\u002F05.aggregations-with-joins",{"title":2799,"icon":2800,"path":2801,"stem":2802,"children":2803,"page":59},"Aggregate Functions","i-lucide-calculator","\u002Fdatabases\u002Faggregate-functions","06.databases\u002F05.aggregate-functions",[2804,2808,2812],{"title":2805,"path":2806,"stem":2807},"Функції агрегування в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fintroduction-aggregate-functions","06.databases\u002F05.aggregate-functions\u002F01.introduction-aggregate-functions",{"title":2809,"path":2810,"stem":2811},"Групування даних в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fgrouping-data","06.databases\u002F05.aggregate-functions\u002F02.grouping-data",{"title":2813,"path":2814,"stem":2815},"Підзапити з агрегатними функціями","\u002Fdatabases\u002Faggregate-functions\u002Fsubqueries-aggregates","06.databases\u002F05.aggregate-functions\u002F03.subqueries-aggregates",{"title":2817,"icon":2818,"path":2819,"stem":2820,"children":2821,"page":59},"Тригери та зберігаємі процедури","i-lucide-database-zap","\u002Fdatabases\u002Ftriggers-stored-procedures","06.databases\u002F07.triggers-stored-procedures",[2822,2826,2830,2834,2838,2842,2846],{"title":2823,"path":2824,"stem":2825},"DML-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fdml-triggers","06.databases\u002F07.triggers-stored-procedures\u002F01.dml-triggers",{"title":2827,"path":2828,"stem":2829},"DDL-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fddl-triggers","06.databases\u002F07.triggers-stored-procedures\u002F02.ddl-triggers",{"title":2831,"path":2832,"stem":2833},"Transact-SQL розширення","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransact-sql-extensions","06.databases\u002F07.triggers-stored-procedures\u002F03.transact-sql-extensions",{"title":2835,"path":2836,"stem":2837},"Транзакції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransactions","06.databases\u002F07.triggers-stored-procedures\u002F04.transactions",{"title":2839,"path":2840,"stem":2841},"Зберігаємі процедури","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fstored-procedures","06.databases\u002F07.triggers-stored-procedures\u002F05.stored-procedures",{"title":2843,"path":2844,"stem":2845},"Користувацькі функції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fuser-defined-functions","06.databases\u002F07.triggers-stored-procedures\u002F06.user-defined-functions",{"title":2847,"path":2848,"stem":2849},"Безпека баз даних","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fsecurity","06.databases\u002F07.triggers-stored-procedures\u002F08.security",{"title":2847,"icon":793,"path":2851,"stem":2852,"children":2853,"page":59},"\u002Fdatabases\u002Fsecurity","06.databases\u002F08.security",[2854,2858],{"title":2855,"path":2856,"stem":2857},"Вступ до безпеки баз даних","\u002Fdatabases\u002Fsecurity\u002Fintroduction","06.databases\u002F08.security\u002F01.introduction",{"title":2859,"path":2860,"stem":2861},"Системні представлення та метадані","\u002Fdatabases\u002Fsecurity\u002Fsystem-views","06.databases\u002F08.security\u002F02.system-views",{"title":2863,"icon":2864,"path":2865,"stem":2866,"children":2867,"page":59},"Резервне копіювання та відновлення","i-lucide-database-backup","\u002Fdatabases\u002Fbackup-recovery","06.databases\u002F09.backup-recovery",[2868],{"title":2863,"path":2869,"stem":2870},"\u002Fdatabases\u002Fbackup-recovery\u002Fbackup-restore","06.databases\u002F09.backup-recovery\u002F01.backup-restore",{"title":2872,"icon":2873,"path":2874,"stem":2875,"children":2876,"page":59},"Повнотекстовий пошук","i-lucide-search","\u002Fdatabases\u002Ffull-text-search","06.databases\u002F10.full-text-search",[2877],{"title":2872,"path":2878,"stem":2879},"\u002Fdatabases\u002Ffull-text-search\u002Ffull-text-search","06.databases\u002F10.full-text-search\u002F01.full-text-search",{"title":2881,"icon":2882,"path":2883,"stem":2884,"children":2885,"page":59},"Tools","i-lucide-wrench","\u002Ftools","07.tools",[2886,2962],{"title":2887,"icon":2888,"path":2889,"stem":2890,"children":2891},"Docker","i-simple-icons-docker","\u002Ftools\u002Fdocker","07.tools\u002F01.docker\u002Findex",[2892,2894,2898,2902,2906,2910,2914,2918,2922,2926,2930,2934,2938,2942,2946,2950,2954,2958],{"title":2893,"path":2889,"stem":2890},"Docker: від нуля до production",{"title":2895,"path":2896,"stem":2897},"Контейнеризація — від проблеми до рішення","\u002Ftools\u002Fdocker\u002Fcontainerization-concept","07.tools\u002F01.docker\u002F01.containerization-concept",{"title":2899,"path":2900,"stem":2901},"Docker — що це і навіщо?","\u002Ftools\u002Fdocker\u002Fdocker-what-and-why","07.tools\u002F01.docker\u002F02.docker-what-and-why",{"title":2903,"path":2904,"stem":2905},"Архітектура Docker Engine","\u002Ftools\u002Fdocker\u002Fdocker-architecture","07.tools\u002F01.docker\u002F03.docker-architecture",{"title":2907,"path":2908,"stem":2909},"Встановлення Docker","\u002Ftools\u002Fdocker\u002Finstallation","07.tools\u002F01.docker\u002F04.installation",{"title":2911,"path":2912,"stem":2913},"Перший контейнер — docker run","\u002Ftools\u002Fdocker\u002Ffirst-container","07.tools\u002F01.docker\u002F05.first-container",{"title":2915,"path":2916,"stem":2917},"Життєвий цикл контейнера","\u002Ftools\u002Fdocker\u002Fcontainer-lifecycle","07.tools\u002F01.docker\u002F06.container-lifecycle",{"title":2919,"path":2920,"stem":2921},"Docker Images — фундаментальні концепції","\u002Ftools\u002Fdocker\u002Fdocker-images-fundamentals","07.tools\u002F01.docker\u002F07.docker-images-fundamentals",{"title":2923,"path":2924,"stem":2925},"Dockerfile — основи","\u002Ftools\u002Fdocker\u002Fdockerfile-basics","07.tools\u002F01.docker\u002F08.dockerfile-basics",{"title":2927,"path":2928,"stem":2929},"Dockerfile — просунуті техніки","\u002Ftools\u002Fdocker\u002Fdockerfile-advanced","07.tools\u002F01.docker\u002F09.dockerfile-advanced",{"title":2931,"path":2932,"stem":2933},"Build Context та кешування шарів","\u002Ftools\u002Fdocker\u002Fbuild-context-and-cache","07.tools\u002F01.docker\u002F10.build-context-and-cache",{"title":2935,"path":2936,"stem":2937},"Реєстри Docker-образів","\u002Ftools\u002Fdocker\u002Fimage-registries","07.tools\u002F01.docker\u002F11.image-registries",{"title":2939,"path":2940,"stem":2941},"Контейнеризація .NET додатків","\u002Ftools\u002Fdocker\u002Fdotnet-containerization","07.tools\u002F01.docker\u002F12.dotnet-containerization",{"title":2943,"path":2944,"stem":2945},"Томи та збереження даних","\u002Ftools\u002Fdocker\u002Fvolumes-and-data","07.tools\u002F01.docker\u002F13.volumes-and-data",{"title":2947,"path":2948,"stem":2949},"Основи мережі в Docker","\u002Ftools\u002Fdocker\u002Fnetworking-basics","07.tools\u002F01.docker\u002F14.networking-basics",{"title":2951,"path":2952,"stem":2953},"Змінні оточення та конфігурація","\u002Ftools\u002Fdocker\u002Fenvironment-and-configuration","07.tools\u002F01.docker\u002F15.environment-and-configuration",{"title":2955,"path":2956,"stem":2957},"Docker Compose — оркестрація контейнерів","\u002Ftools\u002Fdocker\u002Fdocker-compose-basics","07.tools\u002F01.docker\u002F16.docker-compose-basics",{"title":2959,"path":2960,"stem":2961},"Docker Compose — Multi-Service застосунки","\u002Ftools\u002Fdocker\u002Fcompose-multi-service","07.tools\u002F01.docker\u002F17.compose-multi-service",{"title":2963,"icon":2964,"path":2965,"stem":2966,"children":2967},"Kubernetes","simple-icons:kubernetes","\u002Ftools\u002Fkubernetes","07.tools\u002F02.kubernetes\u002Findex",[2968,2970,2974,2978,2982,2986,2990,2994,2998],{"title":2969,"path":2965,"stem":2966},"Kubernetes: від розробки до production",{"title":2971,"path":2972,"stem":2973},"Kubernetes — коли Docker Compose більше не вистачає","\u002Ftools\u002Fkubernetes\u002Fwhy-kubernetes","07.tools\u002F02.kubernetes\u002F01.why-kubernetes",{"title":2975,"path":2976,"stem":2977},"Архітектура Kubernetes — анатомія кластера","\u002Ftools\u002Fkubernetes\u002Fkubernetes-architecture","07.tools\u002F02.kubernetes\u002F02.kubernetes-architecture",{"title":2979,"path":2980,"stem":2981},"Локальне середовище — minikube, kind та k3s","\u002Ftools\u002Fkubernetes\u002Flocal-environment","07.tools\u002F02.kubernetes\u002F03.local-environment",{"title":2983,"path":2984,"stem":2985},"Pod — атомарна одиниця Kubernetes","\u002Ftools\u002Fkubernetes\u002Fpods-and-containers","07.tools\u002F02.kubernetes\u002F04.pods-and-containers",{"title":2987,"path":2988,"stem":2989},"Патерни використання Pod","\u002Ftools\u002Fkubernetes\u002Fpod-patterns","07.tools\u002F02.kubernetes\u002F05.pod-patterns",{"title":2991,"path":2992,"stem":2993},"Deployment — декларативне управління Pod","\u002Ftools\u002Fkubernetes\u002Fdeployment-basics","07.tools\u002F02.kubernetes\u002F06.deployment-basics",{"title":2995,"path":2996,"stem":2997},"Rolling Updates та управління життєвим циклом Deployment","\u002Ftools\u002Fkubernetes\u002Fdeployment-rolling-updates","07.tools\u002F02.kubernetes\u002F07.deployment-rolling-updates",{"title":2999,"path":3000,"stem":3001},"Service — мережева абстракція для Pod","\u002Ftools\u002Fkubernetes\u002Fservices-networking","07.tools\u002F02.kubernetes\u002F08.services-networking",{"title":3003,"icon":3004,"path":3005,"stem":3006,"children":3007,"page":59},"Software Engineering","i-lucide-code-2","\u002Fsoftware-engineering","09.software-engineering",[3008,3012,3016,3020,3024,3028,3032,3036,3040,3044,3048],{"title":3009,"path":3010,"stem":3011},"1. Аналіз предметної області. Експертні знання та складність","\u002Fsoftware-engineering\u002Fintro-subdomains","09.software-engineering\u002F01.intro-subdomains",{"title":3013,"path":3014,"stem":3015},"2. Обмежені контексти. Інтеграція обмежених контекстів","\u002Fsoftware-engineering\u002Fintegrating-limited-contexts","09.software-engineering\u002F02.integrating-limited-contexts",{"title":3017,"path":3018,"stem":3019},"3. Реалізація простої бізнес-логіки","\u002Fsoftware-engineering\u002Fsimple","09.software-engineering\u002F03.simple",{"title":3021,"path":3022,"stem":3023},"4. Опрацювання складної бізнес-логіки","\u002Fsoftware-engineering\u002Fcomplex-business-logic","09.software-engineering\u002F04.complex-business-logic",{"title":3025,"path":3026,"stem":3027},"5. Моделювання фактора часу. Подієво-орієнтована архітектура.","\u002Fsoftware-engineering\u002Fmodelling-the-time-factor","09.software-engineering\u002F05.modelling-the-time-factor",{"title":3029,"path":3030,"stem":3031},"6. Архітектурні патерни","\u002Fsoftware-engineering\u002Farchitectural-patterns","09.software-engineering\u002F06.architectural-patterns",{"title":3033,"path":3034,"stem":3035},"Паттерни взаємодії","\u002Fsoftware-engineering\u002Fpatterns-of-interaction","09.software-engineering\u002F07.patterns-of-interaction",{"title":3037,"path":3038,"stem":3039},"Евристика проєктування","\u002Fsoftware-engineering\u002Fdesign-heuristics","09.software-engineering\u002F08.design-heuristics",{"title":3041,"path":3042,"stem":3043},"Еволюція проєктних рішень","\u002Fsoftware-engineering\u002Fevolution-of-design-solutions","09.software-engineering\u002F09.evolution-of-design-solutions",{"title":3045,"path":3046,"stem":3047},"EventStorming","\u002Fsoftware-engineering\u002Feventstorming","09.software-engineering\u002F10.eventstorming",{"title":3049,"path":3050,"stem":3051},"DDD на практиці","\u002Fsoftware-engineering\u002Fddd-in-practice","09.software-engineering\u002F11.ddd-in-practice",{"title":3053,"icon":943,"path":3054,"stem":3055,"children":3056,"page":59},"DDD","\u002Fddd","10.ddd",[3057,3061,3065,3069,3073,3077,3081,3085,3089,3093,3097,3101,3105],{"title":3058,"path":3059,"stem":3060},"Аналіз предметної області","\u002Fddd\u002Fdomain-analysis","10.ddd\u002F01.domain-analysis",{"title":3062,"path":3063,"stem":3064},"Експертні знання про предметну область","\u002Fddd\u002Fdomain-expert-knowledge","10.ddd\u002F02.domain-expert-knowledge",{"title":3066,"path":3067,"stem":3068},"Як осмислити складність предметної області","\u002Fddd\u002Fmanaging-domain-complexity","10.ddd\u002F03.managing-domain-complexity",{"title":3070,"path":3071,"stem":3072},"Інтеграція обмежених контекстів","\u002Fddd\u002Fbounded-context-integration","10.ddd\u002F04.bounded-context-integration",{"title":3074,"path":3075,"stem":3076},"Реалізація простої бізнес-логіки","\u002Fddd\u002Fsimple-business-logic","10.ddd\u002F05.simple-business-logic",{"title":3078,"path":3079,"stem":3080},"Обробка складної бізнес-логіки","\u002Fddd\u002Fcomplex-business-logic","10.ddd\u002F06.complex-business-logic",{"title":3082,"path":3083,"stem":3084},"Моделювання фактора часу","\u002Fddd\u002Ftime-modeling","10.ddd\u002F07.time-modeling",{"title":3086,"path":3087,"stem":3088},"Глава 8. Архітектурні Патерни","\u002Fddd\u002Farchitectural-patterns","10.ddd\u002F08.architectural-patterns",{"title":3090,"path":3091,"stem":3092},"Глава 9. Патерни Взаємодії","\u002Fddd\u002Finteraction-patterns","10.ddd\u002F09.interaction-patterns",{"title":3094,"path":3095,"stem":3096},"Глава 10. Проектні Евристики","\u002Fddd\u002Fdesign-heuristics","10.ddd\u002F10.design-heuristics",{"title":3098,"path":3099,"stem":3100},"Глава 11. Еволюція Проектних Рішень","\u002Fddd\u002Fevolution-of-design-decisions","10.ddd\u002F11.evolution-of-design-decisions",{"title":3102,"path":3103,"stem":3104},"Глава 12. EventStorming","\u002Fddd\u002Fevent-storming","10.ddd\u002F12.event-storming",{"title":3106,"path":3107,"stem":3108},"Глава 13. DDD на Практиці","\u002Fddd\u002Fddd-in-practice","10.ddd\u002F13.ddd-in-practice",{"title":3110,"icon":3111,"path":3112,"stem":3113,"children":3114,"page":59},"Media Streaming","i-lucide-video","\u002Fmedia-streaming","11.media-streaming",[3115,3119,3123,3127,3131,3135,3139],{"title":3116,"path":3117,"stem":3118},"01. Магія Стрімінгу: Що відбувається, коли ви натискаєте \"Play\"","\u002Fmedia-streaming\u002Fintroduction","11.media-streaming\u002F01.introduction",{"title":3120,"path":3121,"stem":3122},"02. Анатомія Медіа: Кодеки, Контейнери та Стиснення","\u002Fmedia-streaming\u002Faudio-video-anatomy","11.media-streaming\u002F02.audio-video-anatomy",{"title":3124,"path":3125,"stem":3126},"03. The Gym: FFmpeg Deep Dive","\u002Fmedia-streaming\u002Fffmpeg-gym","11.media-streaming\u002F03.ffmpeg-gym",{"title":3128,"path":3129,"stem":3130},"04. HLS Protocol: HTTP Live Streaming у Деталях","\u002Fmedia-streaming\u002Fhls-protocol","11.media-streaming\u002F04.hls-protocol",{"title":3132,"path":3133,"stem":3134},"05. DASH Protocol: Відкритий Стандарт","\u002Fmedia-streaming\u002Fdash-protocol","11.media-streaming\u002F05.dash-protocol",{"title":3136,"path":3137,"stem":3138},"06. Масштабування: CDN та Adaptive Bitrate","\u002Fmedia-streaming\u002Fcdn-and-adaptive-bitrate","11.media-streaming\u002F06.cdn-and-adaptive-bitrate",{"title":3140,"path":3141,"stem":3142},"07. Війна із Затримкою (Latency)","\u002Fmedia-streaming\u002Frealtime-latency","11.media-streaming\u002F07.realtime-latency",{"title":3144,"icon":3145,"path":3146,"stem":3147,"children":3148,"page":59},"HTML & CSS","i-devicon-html5","\u002Fhtml-css","12.html-css",[3149,3153,3157,3161,3165,3169,3173,3177,3181,3185,3189,3193,3197,3201,3205,3209,3213,3217,3221,3225,3229,3233,3237,3241,3245,3249,3253,3257,3261,3265],{"title":3150,"path":3151,"stem":3152},"Вступ до HTML. Структура документа","\u002Fhtml-css\u002Fintro-html-structure","12.html-css\u002F01.intro-html-structure",{"title":3154,"path":3155,"stem":3156},"Форматування тексту в HTML","\u002Fhtml-css\u002Fhtml-text-formatting","12.html-css\u002F02.html-text-formatting",{"title":3158,"path":3159,"stem":3160},"Посилання та зображення в HTML","\u002Fhtml-css\u002Fhtml-links-images","12.html-css\u002F03.html-links-images",{"title":3162,"path":3163,"stem":3164},"Списки та таблиці в HTML","\u002Fhtml-css\u002Fhtml-lists-tables","12.html-css\u002F04.html-lists-tables",{"title":3166,"path":3167,"stem":3168},"Форми в HTML","\u002Fhtml-css\u002Fhtml-forms","12.html-css\u002F05.html-forms",{"title":3170,"path":3171,"stem":3172},"Семантичні елементи HTML5","\u002Fhtml-css\u002Fhtml-semantic-elements","12.html-css\u002F06.html-semantic-elements",{"title":3174,"path":3175,"stem":3176},"Мультимедіа та розширені елементи HTML","\u002Fhtml-css\u002Fhtml-multimedia-advanced","12.html-css\u002F07.html-multimedia-advanced",{"title":3178,"path":3179,"stem":3180},"Мікророзмітка та SEO в HTML","\u002Fhtml-css\u002Fhtml-microdata-seo","12.html-css\u002F08.html-microdata-seo",{"title":3182,"path":3183,"stem":3184},"Вступ до CSS. Селектори та специфічність","\u002Fhtml-css\u002Fcss-intro-selectors","12.html-css\u002F09.css-intro-selectors",{"title":3186,"path":3187,"stem":3188},"Блокова модель CSS. Відступи. Box Sizing","\u002Fhtml-css\u002Fcss-box-model","12.html-css\u002F10.css-box-model",{"title":3190,"path":3191,"stem":3192},"Розміри у CSS: повний довідник одиниць і ключових слів","\u002Fhtml-css\u002F10a.css-sizing","12.html-css\u002F10a.css-sizing",{"title":3194,"path":3195,"stem":3196},"Типографіка в CSS. Шрифти та текст","\u002Fhtml-css\u002Fcss-typography","12.html-css\u002F11.css-typography",{"title":3198,"path":3199,"stem":3200},"Кольори та фони в CSS","\u002Fhtml-css\u002Fcss-colors-backgrounds","12.html-css\u002F12.css-colors-backgrounds",{"title":3202,"path":3203,"stem":3204},"Тіні та фільтри в CSS","\u002Fhtml-css\u002F12b.css-shadows-filters","12.html-css\u002F12b.css-shadows-filters",{"title":3206,"path":3207,"stem":3208},"CSS Flexbox: Фундамент гнучких макетів","\u002Fhtml-css\u002Fcss-flexbox-fundamentals","12.html-css\u002F13.css-flexbox-fundamentals",{"title":3210,"path":3211,"stem":3212},"CSS Flexbox: Вирівнювання та Позиціонування","\u002Fhtml-css\u002Fcss-flexbox-alignment-sizing-and-patterns","12.html-css\u002F14.css-flexbox-alignment-sizing-and-patterns",{"title":3214,"path":3215,"stem":3216},"CSS Grid. Двовимірний макет. Частина 1","\u002Fhtml-css\u002Fcss-layout-grid","12.html-css\u002F15.css-layout-grid",{"title":3218,"path":3219,"stem":3220},"CSS Grid. Двовимірний макет. Частина 2","\u002Fhtml-css\u002Fcss-layout-grid-advanced","12.html-css\u002F16.css-layout-grid-advanced",{"title":3222,"path":3223,"stem":3224},"Позиціонування в CSS. Z-index. Stacking Context","\u002Fhtml-css\u002Fcss-positioning","12.html-css\u002F17.css-positioning",{"title":3226,"path":3227,"stem":3228},"CSS Анімації та Переходи","\u002Fhtml-css\u002Fcss-animations-transitions","12.html-css\u002F18.css-animations-transitions",{"title":3230,"path":3231,"stem":3232},"Адаптивний дизайн. Media Queries. Частина 1","\u002Fhtml-css\u002Fcss-responsive-media-queries","12.html-css\u002F19.css-responsive-media-queries",{"title":3234,"path":3235,"stem":3236},"Адаптивний дизайн. Частина 2: clamp(), Container Queries, @layer","\u002Fhtml-css\u002Fcss-responsive-advanced","12.html-css\u002F20.css-responsive-advanced",{"title":3238,"path":3239,"stem":3240},"CSS Custom Properties. Методології. Сучасний CSS","\u002Fhtml-css\u002Fcss-variables-methodologies","12.html-css\u002F21.css-variables-methodologies",{"title":3242,"path":3243,"stem":3244},"Сучасний CSS 2023–2025: Нові можливості","\u002Fhtml-css\u002Fcss-modern-features","12.html-css\u002F22.css-modern-features",{"title":3246,"path":3247,"stem":3248},"CSS Nesting, @layer, @scope та @property: нативний препроцесор","\u002Fhtml-css\u002F22a.css-nesting-modern-syntax","12.html-css\u002F22a.css-nesting-modern-syntax",{"title":3250,"path":3251,"stem":3252},"CSS для форм та інтерактивних станів","\u002Fhtml-css\u002Fcss-forms-interactive-states","12.html-css\u002F23.css-forms-interactive-states",{"title":3254,"path":3255,"stem":3256},"Доступність у CSS (CSS Accessibility)","\u002Fhtml-css\u002Fcss-accessibility","12.html-css\u002F24.css-accessibility",{"title":3258,"path":3259,"stem":3260},"CSS-функції та сучасні sizing primitives","\u002Fhtml-css\u002Fcss-functions-sizing","12.html-css\u002F25.css-functions-sizing",{"title":3262,"path":3263,"stem":3264},"Rendering Pipeline і CSS Performance","\u002Fhtml-css\u002Fcss-rendering-performance","12.html-css\u002F26.css-rendering-performance",{"title":3266,"path":3267,"stem":3268},"CSS Best Practices: типові ситуації та правильні рішення","\u002Fhtml-css\u002Fcss-best-practices","12.html-css\u002F27.css-best-practices",{"title":3270,"path":3271,"stem":3272,"children":3273,"page":59},"AWS","\u002Faws","13.aws",[3274,3278,3282,3286,3290,3294,3298,3302,3306,3310,3314,3318,3322,3326,3330,3334,3338,3342],{"title":3275,"path":3276,"stem":3277},"Реєстрація AWS акаунту та студентські програми","\u002Faws\u002Faccount-registration","13.aws\u002F00.account-registration",{"title":3279,"path":3280,"stem":3281},"Вступ до хмарних обчислень та AWS","\u002Faws\u002Fintroduction-to-cloud","13.aws\u002F01.introduction-to-cloud",{"title":3283,"path":3284,"stem":3285},"AWS IAM — Identity and Access Management","\u002Faws\u002Fiam","13.aws\u002F02.iam",{"title":3287,"path":3288,"stem":3289},"AWS IAM CLI — Довідник команд","\u002Faws\u002F02a.iam-doc","13.aws\u002F02a.iam-doc",{"title":3291,"path":3292,"stem":3293},"Docker та контейнеризація в AWS — ECR, ECS та Fargate","\u002Faws\u002Fdocker-ecs","13.aws\u002F03.docker-ecs",{"title":3295,"path":3296,"stem":3297},"AWS ECR \u002F ECS CLI — Довідник команд","\u002Faws\u002F03a.docker-ecs-doc","13.aws\u002F03a.docker-ecs-doc",{"title":3299,"path":3300,"stem":3301},"Amazon EC2 — Elastic Compute Cloud","\u002Faws\u002Fec2","13.aws\u002F04.ec2",{"title":3303,"path":3304,"stem":3305},"AWS EC2 CLI — Довідник команд","\u002Faws\u002F04a.ec2-doc","13.aws\u002F04a.ec2-doc",{"title":3307,"path":3308,"stem":3309},"Elastic Load Balancing та Auto Scaling","\u002Faws\u002Falb-asg","13.aws\u002F05.alb-asg",{"title":3311,"path":3312,"stem":3313},"Amazon S3 — Simple Storage Service","\u002Faws\u002Fs3","13.aws\u002F06.s3",{"title":3315,"path":3316,"stem":3317},"Amazon CloudFront — Content Delivery Network","\u002Faws\u002Fcloudfront","13.aws\u002F07.cloudfront",{"title":3319,"path":3320,"stem":3321},"Amazon RDS — Relational Database Service","\u002Faws\u002Frds","13.aws\u002F08.rds",{"title":3323,"path":3324,"stem":3325},"Amazon DynamoDB — NoSQL Database","\u002Faws\u002Fdynamodb","13.aws\u002F09.dynamodb",{"title":3327,"path":3328,"stem":3329},"AWS Lambda та Serverless Compute","\u002Faws\u002Flambda","13.aws\u002F10.lambda",{"title":3331,"path":3332,"stem":3333},"Amazon Bedrock - Foundation Models, RAG та Agents","\u002Faws\u002Fbedrock","13.aws\u002F22.bedrock",{"title":3335,"path":3336,"stem":3337},"Amazon Rekognition - Комп'ютерний зір","\u002Faws\u002Frekognition","13.aws\u002F23.rekognition",{"title":3339,"path":3340,"stem":3341},"Amazon Textract - Інтелектуальний аналіз документів","\u002Faws\u002Ftextract","13.aws\u002F24.textract",{"title":3343,"path":3344,"stem":3345},"Amazon Polly, Transcribe, Comprehend та Translate","\u002Faws\u002Faudio-nlp-services","13.aws\u002F25.audio-nlp-services",{"title":3347,"path":3348,"stem":3349,"children":3350,"page":59},"Ai Development","\u002Fai-development","14.ai-development",[3351],{"title":3352,"path":3353,"stem":3354,"children":3355,"page":59},"Foundations","\u002Fai-development\u002Ffoundations","14.ai-development\u002F00.foundations",[3356],{"title":3357,"path":3358,"stem":3359},"Модуль 0.1. Що таке Large Language Model (LLM)","\u002Fai-development\u002Ffoundations\u002Fwhat-is-llm","14.ai-development\u002F00.foundations\u002F01.what-is-llm",{"title":3361,"path":3362,"stem":3363,"children":3364,"page":59},"React Native","\u002Freact-native","15.react-native",[3365,3386],{"title":3366,"path":3367,"stem":3368,"children":3369,"page":59},"Version1","\u002Freact-native\u002Fversion1","15.react-native\u002Fversion1",[3370,3374,3378,3382],{"title":3371,"path":3372,"stem":3373},"Що таке React Native","\u002Freact-native\u002Fversion1\u002Fwhat-is-react-native","15.react-native\u002Fversion1\u002F01.what-is-react-native",{"title":3375,"path":3376,"stem":3377},"Як влаштований React Native «під капотом»","\u002Freact-native\u002Fversion1\u002Freact-native-architecture","15.react-native\u002Fversion1\u002F02.react-native-architecture",{"title":3379,"path":3380,"stem":3381},"Від React до React Native: ключові відмінності","\u002Freact-native\u002Fversion1\u002Freact-native-vs-react","15.react-native\u002Fversion1\u002F03.react-native-vs-react",{"title":3383,"path":3384,"stem":3385},"View та Text — фундаментальні будівельні блоки","\u002Freact-native\u002Fversion1\u002Fview-and-text","15.react-native\u002Fversion1\u002F04.view-and-text",{"title":3387,"path":3388,"stem":3389,"children":3390,"page":59},"Version2","\u002Freact-native\u002Fversion2","15.react-native\u002Fversion2",[3391,3395,3399,3403,3407,3411,3415,3419,3423,3427,3431,3435,3439,3443,3447,3451,3455,3459,3463,3467,3471,3475,3479,3483,3487,3491],{"title":3392,"path":3393,"stem":3394},"React Native — навіщо він потрібен","\u002Freact-native\u002Fversion2\u002Fwhy-react-native","15.react-native\u002Fversion2\u002F01.why-react-native",{"title":3396,"path":3397,"stem":3398},"Налаштування середовища розробки","\u002Freact-native\u002Fversion2\u002Fenvironment-setup","15.react-native\u002Fversion2\u002F02.environment-setup",{"title":3400,"path":3401,"stem":3402},"Expo і класичний React Native — два шляхи одного фреймворку","\u002Freact-native\u002Fversion2\u002Fexpo-vs-cli-landscape","15.react-native\u002Fversion2\u002F03.expo-vs-cli-landscape",{"title":3404,"path":3405,"stem":3406},"Середовище Expo — перший запуск","\u002Freact-native\u002Fversion2\u002Fexpo-setup-and-tooling","15.react-native\u002Fversion2\u002F04.expo-setup-and-tooling",{"title":3408,"path":3409,"stem":3410},"Структура проєкту та перші UI-примітиви","\u002Freact-native\u002Fversion2\u002Fproject-structure-and-conventions","15.react-native\u002Fversion2\u002F05.project-structure-and-conventions",{"title":3412,"path":3413,"stem":3414},"Базові компоненти React Native","\u002Freact-native\u002Fversion2\u002Fcore-components","15.react-native\u002Fversion2\u002F06.core-components",{"title":3416,"path":3417,"stem":3418},"Flexbox і layout у React Native","\u002Freact-native\u002Fversion2\u002Fflexbox-and-layout","15.react-native\u002Fversion2\u002F07.flexbox-and-layout",{"title":3420,"path":3421,"stem":3422},"StyleSheet і теми (light \u002F dark)","\u002Freact-native\u002Fversion2\u002Fstylesheet-and-theming","15.react-native\u002Fversion2\u002F08.stylesheet-and-theming",{"title":3424,"path":3425,"stem":3426},"Списки та віртуалізація","\u002Freact-native\u002Fversion2\u002Flists-and-virtualization","15.react-native\u002Fversion2\u002F09.lists-and-virtualization",{"title":3428,"path":3429,"stem":3430},"Форми, ввід і валідація","\u002Freact-native\u002Fversion2\u002Fforms-input-validation","15.react-native\u002Fversion2\u002F10.forms-input-validation",{"title":3432,"path":3433,"stem":3434},"Основи Expo Router","\u002Freact-native\u002Fversion2\u002Fexpo-router-basics","15.react-native\u002Fversion2\u002F11.expo-router-basics",{"title":3436,"path":3437,"stem":3438},"Вкладені навігатори та модалки","\u002Freact-native\u002Fversion2\u002Fnested-navigators-and-modals","15.react-native\u002Fversion2\u002F12.nested-navigators-and-modals",{"title":3440,"path":3441,"stem":3442},"Deep linking і параметри маршрутів","\u002Freact-native\u002Fversion2\u002Fdeep-linking-and-params","15.react-native\u002Fversion2\u002F13.deep-linking-and-params",{"title":3444,"path":3445,"stem":3446},"Робота з мережею та життєвий цикл застосунку","\u002Freact-native\u002Fversion2\u002Fnetworking-and-app-lifecycle","15.react-native\u002Fversion2\u002F14.networking-and-app-lifecycle",{"title":3448,"path":3449,"stem":3450},"Redux Toolkit на мобільних платформах","\u002Freact-native\u002Fversion2\u002Fredux-toolkit-on-mobile","15.react-native\u002Fversion2\u002F15.redux-toolkit-on-mobile",{"title":3452,"path":3453,"stem":3454},"RTK Query на мобільних платформах","\u002Freact-native\u002Fversion2\u002Frtk-query-mobile","15.react-native\u002Fversion2\u002F16.rtk-query-mobile",{"title":3456,"path":3457,"stem":3458},"Автентифікація та Безпечне Зберігання","\u002Freact-native\u002Fversion2\u002Fauth-secure-storage","15.react-native\u002Fversion2\u002F18.auth-secure-storage",{"title":3460,"path":3461,"stem":3462},"Локальне сховище — AsyncStorage, MMKV, SQLite","\u002Freact-native\u002Fversion2\u002Flocal-storage-mmkv-sqlite","15.react-native\u002Fversion2\u002F19.local-storage-mmkv-sqlite",{"title":3464,"path":3465,"stem":3466},"Офлайн-First і синхронізація","\u002Freact-native\u002Fversion2\u002Foffline-first-sync","15.react-native\u002Fversion2\u002F20.offline-first-sync",{"title":3468,"path":3469,"stem":3470},"Камера, медіа та файлова система","\u002Freact-native\u002Fversion2\u002Fcamera-media-filesystem","15.react-native\u002Fversion2\u002F21.camera-media-filesystem",{"title":3472,"path":3473,"stem":3474},"Карти та геолокація","\u002Freact-native\u002Fversion2\u002Fmaps-and-location","15.react-native\u002Fversion2\u002F22.maps-and-location",{"title":3476,"path":3477,"stem":3478},"Жести та дотики","\u002Freact-native\u002Fversion2\u002Fgestures-and-touch","15.react-native\u002Fversion2\u002F23.gestures-and-touch",{"title":3480,"path":3481,"stem":3482},"Анімації з Reanimated","\u002Freact-native\u002Fversion2\u002Freanimated-animations","15.react-native\u002Fversion2\u002F24.reanimated-animations",{"title":3484,"path":3485,"stem":3486},"Push і локальні сповіщення","\u002Freact-native\u002Fversion2\u002Fpush-and-local-notifications","15.react-native\u002Fversion2\u002F25.push-and-local-notifications",{"title":3488,"path":3489,"stem":3490},"Доступність та інтернаціоналізація","\u002Freact-native\u002Fversion2\u002Faccessibility-and-i18n","15.react-native\u002Fversion2\u002F26.accessibility-and-i18n",{"title":3492,"path":3493,"stem":3494},"EAS Build та профілі збірки","\u002Freact-native\u002Fversion2\u002Feas-build-and-profiles","15.react-native\u002Fversion2\u002F29.eas-build-and-profiles",{"title":3496,"path":3497,"stem":3498,"children":3499,"page":59},"Ai Python","\u002Fai-python","16.ai-python",[3500,3504,3508],{"title":3501,"path":3502,"stem":3503},"Вступ до штучного інтелекту та машинного навчання","\u002Fai-python\u002Fintro-to-ai","16.ai-python\u002F01.intro-to-ai",{"title":3505,"path":3506,"stem":3507},"Знайомство з Jupyter Notebook та JupyterLab","\u002Fai-python\u002Fjupyter-notebook","16.ai-python\u002F02.jupyter-notebook",{"title":3509,"path":3510,"stem":3511},"Робота з даними з використанням NumPy і pandas","\u002Fai-python\u002Fnumpy-pandas","16.ai-python\u002F03.numpy-pandas",{"title":3513,"icon":658,"path":3514,"stem":3515,"children":3516,"page":59},"Клієнт-серверна архітектура","\u002Fclient-server-architecture","17.client-server-architecture",[3517,3521],{"title":3518,"path":3519,"stem":3520},"Архітектура клієнт-серверних систем та основи Go","\u002Fclient-server-architecture\u002Fclient-server-architecture-and-go","17.client-server-architecture\u002F01.client-server-architecture-and-go",{"title":3522,"path":3523,"stem":3524},"Система типів та модель пам’яті мови Go","\u002Fclient-server-architecture\u002Ftype-system-and-memory-model","17.client-server-architecture\u002F02.type-system-and-memory-model",{"title":3526,"icon":1946,"path":3527,"stem":3528,"children":3529,"page":59},"Розробка WEB-застосувань","\u002Fweb-development","18.web-development",[3530,3575,3613,3642],{"title":3531,"icon":658,"path":3532,"stem":3533,"children":3534,"page":59},"Архітектура комп'ютерних мереж та мережеві протоколи","\u002Fweb-development\u002Fnetwork-architecture-and-protocols","18.web-development\u002F01.network-architecture-and-protocols",[3535,3539,3543,3547,3551,3555,3559,3563,3567,3571],{"title":3536,"path":3537,"stem":3538},"Еволюція веброзробки та модель клієнт-сервер","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fweb-evolution-client-server","18.web-development\u002F01.network-architecture-and-protocols\u002F01.web-evolution-client-server",{"title":3540,"path":3541,"stem":3542},"Еталонна модель OSI","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fosi-model","18.web-development\u002F01.network-architecture-and-protocols\u002F02.osi-model",{"title":3544,"path":3545,"stem":3546},"Стек протоколів TCP\u002FIP","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Ftcp-ip-stack","18.web-development\u002F01.network-architecture-and-protocols\u002F03.tcp-ip-stack",{"title":3548,"path":3549,"stem":3550},"IP-адресація, порти та сокети","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fip-addressing-ports-sockets","18.web-development\u002F01.network-architecture-and-protocols\u002F04.ip-addressing-ports-sockets",{"title":3552,"path":3553,"stem":3554},"Протоколи TCP та UDP","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Ftcp-udp-protocols","18.web-development\u002F01.network-architecture-and-protocols\u002F05.tcp-udp-protocols",{"title":3556,"path":3557,"stem":3558},"Система доменних імен DNS","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fdns-system","18.web-development\u002F01.network-architecture-and-protocols\u002F06.dns-system",{"title":3560,"path":3561,"stem":3562},"Протокол SMTP та поштові протоколи","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fsmtp-email-protocols","18.web-development\u002F01.network-architecture-and-protocols\u002F07.smtp-email-protocols",{"title":3564,"path":3565,"stem":3566},"Протокол WebSocket","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fwebsocket-protocol","18.web-development\u002F01.network-architecture-and-protocols\u002F08.websocket-protocol",{"title":3568,"path":3569,"stem":3570},"Протокол SSH","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fssh-protocol","18.web-development\u002F01.network-architecture-and-protocols\u002F09.ssh-protocol",{"title":3572,"path":3573,"stem":3574},"Огляд сучасних серверних технологій","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fmodern-backend-technologies","18.web-development\u002F01.network-architecture-and-protocols\u002F10.modern-backend-technologies",{"title":3576,"icon":3577,"path":3578,"stem":3579,"children":3580,"page":59},"Протокол HTTP та захищена передача даних HTTPS","i-lucide-lock","\u002Fweb-development\u002Fhttp-and-https","18.web-development\u002F02.http-and-https",[3581,3585,3589,3593,3597,3601,3605,3609],{"title":3582,"path":3583,"stem":3584},"Вступ до протоколу HTTP та еволюція веб-технологій","\u002Fweb-development\u002Fhttp-and-https\u002Fintroduction-and-evolution","18.web-development\u002F02.http-and-https\u002F01.introduction-and-evolution",{"title":3586,"path":3587,"stem":3588},"Анатомія HTTP-запиту","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-request-structure","18.web-development\u002F02.http-and-https\u002F02.http-request-structure",{"title":3590,"path":3591,"stem":3592},"Анатомія HTTP-відповіді","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-response-structure","18.web-development\u002F02.http-and-https\u002F03.http-response-structure",{"title":3594,"path":3595,"stem":3596},"Методи HTTP та їхня семантика","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-methods","18.web-development\u002F02.http-and-https\u002F04.http-methods",{"title":3598,"path":3599,"stem":3600},"Коди статусу HTTP та їхнє призначення","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-status-codes","18.web-development\u002F02.http-and-https\u002F05.http-status-codes",{"title":3602,"path":3603,"stem":3604},"HTTP-заголовки та їхнє призначення","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-headers","18.web-development\u002F02.http-and-https\u002F06.http-headers",{"title":3606,"path":3607,"stem":3608},"CORS та механізми безпеки HTTP","\u002Fweb-development\u002Fhttp-and-https\u002Fcors-and-security","18.web-development\u002F02.http-and-https\u002F07.cors-and-security",{"title":3610,"path":3611,"stem":3612},"HTTPS та криптографічні основи TLS","\u002Fweb-development\u002Fhttp-and-https\u002Fhttps-and-tls","18.web-development\u002F02.http-and-https\u002F08.https-and-tls",{"title":3614,"icon":2326,"path":3615,"stem":3616,"children":3617,"page":59},"Система типів мови TypeScript","\u002Fweb-development\u002Ftypescript-type-system","18.web-development\u002F03.typescript-type-system",[3618,3622,3626,3630,3634,3638],{"title":3619,"path":3620,"stem":3621},"Знайомство з TypeScript Compiler","\u002Fweb-development\u002Ftypescript-type-system\u002Fintroduction-compiler-config","18.web-development\u002F03.typescript-type-system\u002F01.introduction-compiler-config",{"title":3623,"path":3624,"stem":3625},"Примітивні типи даних: string, number, boolean","\u002Fweb-development\u002Ftypescript-type-system\u002Fprimitive-special-types","18.web-development\u002F03.typescript-type-system\u002F02.primitive-special-types",{"title":3627,"path":3628,"stem":3629},"Масиви, кортежі та об","\u002Fweb-development\u002Ftypescript-type-system\u002Farrays-tuples-objects","18.web-development\u002F03.typescript-type-system\u002F03.arrays-tuples-objects",{"title":3631,"path":3632,"stem":3633},"Union типи, Intersection типи та літеральні типи","\u002Fweb-development\u002Ftypescript-type-system\u002Funion-intersection-literals","18.web-development\u002F03.typescript-type-system\u002F04.union-intersection-literals",{"title":3635,"path":3636,"stem":3637},"Type Narrowing (звуження типів)","\u002Fweb-development\u002Ftypescript-type-system\u002Ftype-narrowing","18.web-development\u002F03.typescript-type-system\u002F05.type-narrowing",{"title":3639,"path":3640,"stem":3641},"Типізація функцій","\u002Fweb-development\u002Ftypescript-type-system\u002Ffunctions-typing","18.web-development\u002F03.typescript-type-system\u002F06.functions-typing",{"title":3643,"icon":2326,"path":3644,"stem":3645,"children":3646,"page":59},"Розширені засоби мови TypeScript","\u002Fweb-development\u002Ftypescript-advanced","18.web-development\u002F04.typescript-advanced",[3647,3651,3655,3659,3663,3667],{"title":3648,"path":3649,"stem":3650},"Interfaces та Classes","\u002Fweb-development\u002Ftypescript-advanced\u002Finterfaces-classes","18.web-development\u002F04.typescript-advanced\u002F01.interfaces-classes",{"title":3652,"path":3653,"stem":3654},"Основи Generic типів","\u002Fweb-development\u002Ftypescript-advanced\u002Fgenerics-fundamentals","18.web-development\u002F04.typescript-advanced\u002F02.generics-fundamentals",{"title":3656,"path":3657,"stem":3658},"Enums та Decorators","\u002Fweb-development\u002Ftypescript-advanced\u002Fenums-decorators","18.web-development\u002F04.typescript-advanced\u002F03.enums-decorators",{"title":3660,"path":3661,"stem":3662},"Utility Types","\u002Fweb-development\u002Ftypescript-advanced\u002Futility-types","18.web-development\u002F04.typescript-advanced\u002F04.utility-types",{"title":3664,"path":3665,"stem":3666},"Mapped та Conditional Types","\u002Fweb-development\u002Ftypescript-advanced\u002Fmapped-conditional-types","18.web-development\u002F04.typescript-advanced\u002F05.mapped-conditional-types",{"title":3668,"path":3669,"stem":3670},"Модулі та Strict Mode","\u002Fweb-development\u002Ftypescript-advanced\u002Fmodules-strict-mode","18.web-development\u002F04.typescript-advanced\u002F06.modules-strict-mode",{"title":3672,"path":3673,"stem":3674,"children":3675,"page":59},"Tailwind","\u002Ftailwind","21.tailwind",[3676,3680,3684,3688,3692,3696,3700,3704,3708,3712,3716,3720],{"title":3677,"path":3678,"stem":3679},"Що таке Tailwind CSS і навіщо він потрібен","\u002Ftailwind\u002Ftailwind-intro-philosophy","21.tailwind\u002F01.tailwind-intro-philosophy",{"title":3681,"path":3682,"stem":3683},"Встановлення та налаштування Tailwind CSS v4","\u002Ftailwind\u002Ftailwind-installation-setup","21.tailwind\u002F02.tailwind-installation-setup",{"title":3685,"path":3686,"stem":3687},"Utility-класи: основи та система Tailwind","\u002Ftailwind\u002Ftailwind-utility-classes-core","21.tailwind\u002F03.tailwind-utility-classes-core",{"title":3689,"path":3690,"stem":3691},"Layout: Flexbox та Grid через Tailwind","\u002Ftailwind\u002Ftailwind-flexbox-grid","21.tailwind\u002F04.tailwind-flexbox-grid",{"title":3693,"path":3694,"stem":3695},"Кастомізація теми через @theme у Tailwind v4","\u002Ftailwind\u002Ftailwind-theme-customization","21.tailwind\u002F05.tailwind-theme-customization",{"title":3697,"path":3698,"stem":3699},"Варіанти: hover, focus, responsive, dark mode та нові v4","\u002Ftailwind\u002Ftailwind-variants-states","21.tailwind\u002F06.tailwind-variants-states",{"title":3701,"path":3702,"stem":3703},"Типографіка та система кольорів у Tailwind v4","\u002Ftailwind\u002Ftailwind-typography-colors","21.tailwind\u002F07.tailwind-typography-colors",{"title":3705,"path":3706,"stem":3707},"Компоненти та повторюваність: @apply, @utility та патерни","\u002Ftailwind\u002Ftailwind-components-patterns","21.tailwind\u002F08.tailwind-components-patterns",{"title":3709,"path":3710,"stem":3711},"Темна тема та система дизайн-токенів у Tailwind v4","\u002Ftailwind\u002Ftailwind-dark-mode-theming","21.tailwind\u002F09.tailwind-dark-mode-theming",{"title":3713,"path":3714,"stem":3715},"Довільні значення та контейнерні запити у Tailwind v4","\u002Ftailwind\u002Ftailwind-arbitrary-container-queries","21.tailwind\u002F10.tailwind-arbitrary-container-queries",{"title":3717,"path":3718,"stem":3719},"Анімації, трансформації та 3D у Tailwind v4","\u002Ftailwind\u002Ftailwind-animations-transforms","21.tailwind\u002F11.tailwind-animations-transforms",{"title":3721,"path":3722,"stem":3723},"Tailwind CLI, PostCSS та інтеграція з фреймворками","\u002Ftailwind\u002Ftailwind-cli-tooling","21.tailwind\u002F12.tailwind-cli-tooling",{"title":3725,"path":3726,"stem":3727},"Тестування компонентів діаграм","\u002Ftest-components","98.test-components",{"id":3729,"title":3648,"body":3730,"description":19742,"extension":19743,"links":19744,"meta":19745,"navigation":4001,"path":3649,"seo":19746,"stem":3650,"__hash__":19747},"docs\u002F18.web-development\u002F04.typescript-advanced\u002F01.interfaces-classes.md",{"type":3731,"value":3732,"toc":19675},"minimark",[3733,3737,3837,3840,3845,3853,4114,4129,4144,4216,4218,4222,4236,4241,4247,4298,4305,4544,4550,4651,4655,4672,4844,4855,4859,4866,4932,4946,5143,5154,5249,5253,5260,5398,5401,5512,5514,5518,5528,5614,5622,5626,5631,5641,5795,5801,5880,5886,5891,5897,6009,6023,6033,6063,6068,6075,6173,6180,6195,6200,6211,6333,6339,6343,6434,6446,6455,6457,6461,6481,6485,6670,6692,6696,6703,6965,6979,6983,6994,7132,7135,7184,7224,7226,7230,7251,7255,7275,7278,7338,7367,7505,7509,7523,7727,7733,7764,7791,7800,7804,7810,7957,7981,7987,8048,8167,8174,8176,8180,8183,8187,8193,8426,8444,8545,8549,8564,8734,8740,8844,8848,8853,9173,9193,9213,9217,9230,9475,9489,9794,9841,9843,9847,9872,9876,9885,10025,10035,10039,10048,10385,10397,10568,10572,10581,10814,10824,10828,10837,11072,11077,11241,11342,11344,11348,11363,11367,11548,11564,11568,11583,11843,11849,11942,11960,11964,11973,12271,12296,12300,12310,12508,12515,12543,12545,12549,12563,12895,12906,12957,12961,12990,12999,13340,13632,13634,13638,13655,13659,13665,13811,13817,14233,14237,14251,14375,14381,14680,14684,14687,14791,14849,14851,14855,14868,14872,14882,15269,15277,15293,15297,15332,15478,15484,15486,15490,15504,15507,15665,15674,16415,16418,16454,16468,16470,16474,16495,16499,16692,16725,16728,16942,16958,17069,17073,17080,17305,17322,17331,17333,17337,17340,17344,17376,17380,18821,18825,18899,18909,18911,18915,18924,18955,18959,19026,19029,19102,19116,19118,19671],[3734,3735,3648],"h1",{"id":3736},"interfaces-та-classes",[3738,3739,3740,3787],"card-group",{},[3741,3742,3745],"card",{"icon":3743,"title":3744},"i-lucide-target","🎯 Мета розділу",[3746,3747,3748,3761,3764,3767,3770,3784],"ul",{},[3749,3750,3751,3752,3756,3757,3760],"li",{},"Зрозуміти фундаментальну відмінність між ",[3753,3754,3755],"code",{},"interface"," та ",[3753,3758,3759],{},"type"," у TypeScript та коли застосовувати кожен підхід.",[3749,3762,3763],{},"Опанувати систему класів JavaScript та їх типізацію через TypeScript.",[3749,3765,3766],{},"Навчитися проєктувати контракти поведінки через інтерфейси для досягнення слабкого зв'язування.",[3749,3768,3769],{},"Усвідомити прототипну природу класів JavaScript та механізм наслідування через ланцюг прототипів.",[3749,3771,3772,3773,3776,3777,3776,3780,3783],{},"Застосовувати принципи інкапсуляції через модифікатори доступу ",[3753,3774,3775],{},"public",", ",[3753,3778,3779],{},"private",[3753,3781,3782],{},"protected",".",[3749,3785,3786],{},"Розрізняти абстрактні класи та інтерфейси як інструменти моделювання архітектури.",[3741,3788,3791],{"icon":3789,"title":3790},"i-lucide-key","🔑 Ключові терміни",[3746,3792,3793,3800,3806,3812,3818,3831],{},[3749,3794,3795,3799],{},[3796,3797,3798],"strong",{},"Interface (Інтерфейс):"," контракт, що визначає структуру об'єкта або поведінку класу без реалізації.",[3749,3801,3802,3805],{},[3796,3803,3804],{},"Class (Клас):"," шаблон для створення об'єктів, що інкапсулює дані та методи.",[3749,3807,3808,3811],{},[3796,3809,3810],{},"Prototype (Прототип):"," об'єкт у JavaScript, від якого інші об'єкти наслідують властивості та методи.",[3749,3813,3814,3817],{},[3796,3815,3816],{},"Constructor (Конструктор):"," спеціальний метод класу, що викликається при створенні нового екземпляра.",[3749,3819,3820,3823,3824,3776,3826,3776,3828,3830],{},[3796,3821,3822],{},"Access Modifiers (Модифікатори доступу):"," ключові слова ",[3753,3825,3775],{},[3753,3827,3779],{},[3753,3829,3782],{},", що контролюють видимість членів класу.",[3749,3832,3833,3836],{},[3796,3834,3835],{},"Abstract Class (Абстрактний клас):"," клас, що не може бути інстанційованим напряму і призначений для успадкування.",[3838,3839],"hr",{},[3841,3842,3844],"h2",{"id":3843},"обмеження-inline-типів-та-необхідність-багаторазового-використання","Обмеження inline типів та необхідність багаторазового використання",[3846,3847,3848,3849,3852],"p",{},"У попередніх розділах ми активно користувалися ",[3796,3850,3851],{},"inline об'єктними типами"," для опису структури даних:",[3854,3855,3860],"pre",{"className":3856,"code":3857,"language":3858,"meta":3859,"style":3859},"language-typescript shiki shiki-themes light-plus dark-plus dark-plus","function createUser(data: { name: string; email: string; age: number }) {\n  return {\n    ...data,\n    id: Math.random().toString(36),\n    createdAt: new Date()\n  };\n}\n\nfunction validateUser(user: { name: string; email: string; age: number }): boolean {\n  return user.name.length > 0 && user.email.includes('@') && user.age >= 18;\n}\n","typescript","",[3753,3861,3862,3919,3929,3940,3969,3984,3990,3996,4003,4048,4109],{"__ignoreMap":3859},[3863,3864,3867,3871,3875,3879,3883,3886,3889,3892,3896,3899,3902,3904,3906,3908,3911,3913,3916],"span",{"class":3865,"line":3866},"line",1,[3863,3868,3870],{"class":3869},"su1O8","function",[3863,3872,3874],{"class":3873},"s8Opu"," createUser",[3863,3876,3878],{"class":3877},"sHH4Y","(",[3863,3880,3882],{"class":3881},"siwwj","data",[3863,3884,3885],{"class":3877},": { ",[3863,3887,3888],{"class":3881},"name",[3863,3890,3891],{"class":3877},": ",[3863,3893,3895],{"class":3894},"sN1BT","string",[3863,3897,3898],{"class":3877},"; ",[3863,3900,3901],{"class":3881},"email",[3863,3903,3891],{"class":3877},[3863,3905,3895],{"class":3894},[3863,3907,3898],{"class":3877},[3863,3909,3910],{"class":3881},"age",[3863,3912,3891],{"class":3877},[3863,3914,3915],{"class":3894},"number",[3863,3917,3918],{"class":3877}," }) {\n",[3863,3920,3922,3926],{"class":3865,"line":3921},2,[3863,3923,3925],{"class":3924},"s8xlr","  return",[3863,3927,3928],{"class":3877}," {\n",[3863,3930,3932,3935,3937],{"class":3865,"line":3931},3,[3863,3933,3934],{"class":3877},"    ...",[3863,3936,3882],{"class":3881},[3863,3938,3939],{"class":3877},",\n",[3863,3941,3943,3946,3949,3951,3954,3957,3960,3962,3966],{"class":3865,"line":3942},4,[3863,3944,3945],{"class":3881},"    id:",[3863,3947,3948],{"class":3881}," Math",[3863,3950,3783],{"class":3877},[3863,3952,3953],{"class":3873},"random",[3863,3955,3956],{"class":3877},"().",[3863,3958,3959],{"class":3873},"toString",[3863,3961,3878],{"class":3877},[3863,3963,3965],{"class":3964},"sJj4R","36",[3863,3967,3968],{"class":3877},"),\n",[3863,3970,3972,3975,3978,3981],{"class":3865,"line":3971},5,[3863,3973,3974],{"class":3881},"    createdAt:",[3863,3976,3977],{"class":3869}," new",[3863,3979,3980],{"class":3873}," Date",[3863,3982,3983],{"class":3877},"()\n",[3863,3985,3987],{"class":3865,"line":3986},6,[3863,3988,3989],{"class":3877},"  };\n",[3863,3991,3993],{"class":3865,"line":3992},7,[3863,3994,3995],{"class":3877},"}\n",[3863,3997,3999],{"class":3865,"line":3998},8,[3863,4000,4002],{"emptyLinePlaceholder":4001},true,"\n",[3863,4004,4006,4008,4011,4013,4016,4018,4020,4022,4024,4026,4028,4030,4032,4034,4036,4038,4040,4043,4046],{"class":3865,"line":4005},9,[3863,4007,3870],{"class":3869},[3863,4009,4010],{"class":3873}," validateUser",[3863,4012,3878],{"class":3877},[3863,4014,4015],{"class":3881},"user",[3863,4017,3885],{"class":3877},[3863,4019,3888],{"class":3881},[3863,4021,3891],{"class":3877},[3863,4023,3895],{"class":3894},[3863,4025,3898],{"class":3877},[3863,4027,3901],{"class":3881},[3863,4029,3891],{"class":3877},[3863,4031,3895],{"class":3894},[3863,4033,3898],{"class":3877},[3863,4035,3910],{"class":3881},[3863,4037,3891],{"class":3877},[3863,4039,3915],{"class":3894},[3863,4041,4042],{"class":3877}," }): ",[3863,4044,4045],{"class":3894},"boolean",[3863,4047,3928],{"class":3877},[3863,4049,4051,4053,4056,4058,4060,4062,4065,4068,4071,4074,4076,4078,4080,4082,4085,4087,4091,4094,4096,4098,4100,4103,4106],{"class":3865,"line":4050},10,[3863,4052,3925],{"class":3924},[3863,4054,4055],{"class":3881}," user",[3863,4057,3783],{"class":3877},[3863,4059,3888],{"class":3881},[3863,4061,3783],{"class":3877},[3863,4063,4064],{"class":3881},"length",[3863,4066,4067],{"class":3877}," > ",[3863,4069,4070],{"class":3964},"0",[3863,4072,4073],{"class":3877}," && ",[3863,4075,4015],{"class":3881},[3863,4077,3783],{"class":3877},[3863,4079,3901],{"class":3881},[3863,4081,3783],{"class":3877},[3863,4083,4084],{"class":3873},"includes",[3863,4086,3878],{"class":3877},[3863,4088,4090],{"class":4089},"sbdoH","'@'",[3863,4092,4093],{"class":3877},") && ",[3863,4095,4015],{"class":3881},[3863,4097,3783],{"class":3877},[3863,4099,3910],{"class":3881},[3863,4101,4102],{"class":3877}," >= ",[3863,4104,4105],{"class":3964},"18",[3863,4107,4108],{"class":3877},";\n",[3863,4110,4112],{"class":3865,"line":4111},11,[3863,4113,3995],{"class":3877},[3846,4115,4116,4117,4120,4121,4124,4125,4128],{},"Цей підхід працює, але призводить до ",[3796,4118,4119],{},"дублювання коду",": тип ",[3753,4122,4123],{},"{ name: string; email: string; age: number }"," повторюється двічі. Якщо структура користувача зміниться (наприклад, додамо поле ",[3753,4126,4127],{},"phone","), доведеться вносити зміни у кількох місцях, що підвищує ризик помилок та ускладнює підтримку коду.",[3846,4130,4131,4132,4135,4136,4139,4140,4143],{},"Для вирішення цієї проблеми у TypeScript існують два основні інструменти: ",[3796,4133,4134],{},"type aliases"," (псевдоніми типів, які ви вже знаєте з розділу про union та intersection типи) та ",[3796,4137,4138],{},"interfaces"," (інтерфейси). Обидва механізми дозволяють ",[3796,4141,4142],{},"винести опис типу у окреме іменоване оголошення"," та багаторазово використовувати його у сигнатурах функцій, змінних та класів.",[4145,4146,4147,4153,4213],"note",{},[3846,4148,4149,4150,4152],{},"Нагадаємо, що у розділі про union та intersection типи ми вже використовували ",[3753,4151,3759],{}," для створення псевдонімів:",[3854,4154,4156],{"className":3856,"code":4155,"language":3858,"meta":3859,"style":3859},"type StatusCode = 200 | 404 | 500;\ntype Point = { x: number; y: number };\n",[3753,4157,4158,4184],{"__ignoreMap":3859},[3863,4159,4160,4162,4165,4168,4171,4174,4177,4179,4182],{"class":3865,"line":3866},[3863,4161,3759],{"class":3869},[3863,4163,4164],{"class":3894}," StatusCode",[3863,4166,4167],{"class":3877}," = ",[3863,4169,4170],{"class":3964},"200",[3863,4172,4173],{"class":3877}," | ",[3863,4175,4176],{"class":3964},"404",[3863,4178,4173],{"class":3877},[3863,4180,4181],{"class":3964},"500",[3863,4183,4108],{"class":3877},[3863,4185,4186,4188,4191,4194,4197,4199,4201,4203,4206,4208,4210],{"class":3865,"line":3921},[3863,4187,3759],{"class":3869},[3863,4189,4190],{"class":3894}," Point",[3863,4192,4193],{"class":3877}," = { ",[3863,4195,4196],{"class":3881},"x",[3863,4198,3891],{"class":3877},[3863,4200,3915],{"class":3894},[3863,4202,3898],{"class":3877},[3863,4204,4205],{"class":3881},"y",[3863,4207,3891],{"class":3877},[3863,4209,3915],{"class":3894},[3863,4211,4212],{"class":3877}," };\n",[3846,4214,4215],{},"Інтерфейси доповнюють цей інструментарій, пропонуючи більш природний синтаксис для опису структур об'єктів та контрактів поведінки класів, а також унікальні можливості розширення та об'єднання оголошень.",[3838,4217],{},[3841,4219,4221],{"id":4220},"interface-контракт-структури-обєкта","Interface: контракт структури об'єкта",[3846,4223,4224,4227,4228,4231,4232,4235],{},[3796,4225,4226],{},"Інтерфейс"," (",[4229,4230,3755],"em",{},") у TypeScript — це спосіб формального визначення структури об'єкта: які властивості він повинен мати, які типи мають ці властивості, які методи він надає та які сигнатури мають ці методи. Інтерфейс діє як ",[3796,4233,4234],{},"контракт",": будь-який об'єкт або клас, що оголошує відповідність цьому інтерфейсу, зобов'язується надати всі описані властивості та методи з вказаними типами.",[4237,4238,4240],"h3",{"id":4239},"синтаксис-оголошення-інтерфейсу","Синтаксис оголошення інтерфейсу",[3846,4242,4243,4244,4246],{},"Інтерфейс оголошується через ключове слово ",[3753,4245,3755],{},", за яким слідує ім'я інтерфейсу (за конвенцією починається з великої літери) та тіло у фігурних дужках:",[3854,4248,4250],{"className":3856,"code":4249,"language":3858,"meta":3859,"style":3859},"interface User {\n  name: string;\n  email: string;\n  age: number;\n}\n",[3753,4251,4252,4261,4272,4283,4294],{"__ignoreMap":3859},[3863,4253,4254,4256,4259],{"class":3865,"line":3866},[3863,4255,3755],{"class":3869},[3863,4257,4258],{"class":3894}," User",[3863,4260,3928],{"class":3877},[3863,4262,4263,4266,4268,4270],{"class":3865,"line":3921},[3863,4264,4265],{"class":3881},"  name",[3863,4267,3891],{"class":3877},[3863,4269,3895],{"class":3894},[3863,4271,4108],{"class":3877},[3863,4273,4274,4277,4279,4281],{"class":3865,"line":3931},[3863,4275,4276],{"class":3881},"  email",[3863,4278,3891],{"class":3877},[3863,4280,3895],{"class":3894},[3863,4282,4108],{"class":3877},[3863,4284,4285,4288,4290,4292],{"class":3865,"line":3942},[3863,4286,4287],{"class":3881},"  age",[3863,4289,3891],{"class":3877},[3863,4291,3915],{"class":3894},[3863,4293,4108],{"class":3877},[3863,4295,4296],{"class":3865,"line":3971},[3863,4297,3995],{"class":3877},[3846,4299,4300,4301,4304],{},"Тепер ми можемо використовувати ",[3753,4302,4303],{},"User"," як тип у будь-якому місці програми:",[3854,4306,4308],{"className":3856,"code":4307,"language":3858,"meta":3859,"style":3859},"function createUser(data: User): User & { id: string; createdAt: Date } {\n  return {\n    ...data,\n    id: Math.random().toString(36),\n    createdAt: new Date()\n  };\n}\n\nfunction validateUser(user: User): boolean {\n  return user.name.length > 0 && user.email.includes('@') && user.age >= 18;\n}\n\nconst newUser = createUser({ \n  name: 'Олена Шевченко', \n  email: 'olena@example.com', \n  age: 22 \n});\n",[3753,4309,4310,4352,4358,4366,4386,4396,4400,4404,4408,4428,4476,4480,4485,4503,4515,4526,4538],{"__ignoreMap":3859},[3863,4311,4312,4314,4316,4318,4320,4322,4324,4327,4329,4332,4335,4337,4339,4341,4344,4346,4349],{"class":3865,"line":3866},[3863,4313,3870],{"class":3869},[3863,4315,3874],{"class":3873},[3863,4317,3878],{"class":3877},[3863,4319,3882],{"class":3881},[3863,4321,3891],{"class":3877},[3863,4323,4303],{"class":3894},[3863,4325,4326],{"class":3877},"): ",[3863,4328,4303],{"class":3894},[3863,4330,4331],{"class":3877}," & { ",[3863,4333,4334],{"class":3881},"id",[3863,4336,3891],{"class":3877},[3863,4338,3895],{"class":3894},[3863,4340,3898],{"class":3877},[3863,4342,4343],{"class":3881},"createdAt",[3863,4345,3891],{"class":3877},[3863,4347,4348],{"class":3894},"Date",[3863,4350,4351],{"class":3877}," } {\n",[3863,4353,4354,4356],{"class":3865,"line":3921},[3863,4355,3925],{"class":3924},[3863,4357,3928],{"class":3877},[3863,4359,4360,4362,4364],{"class":3865,"line":3931},[3863,4361,3934],{"class":3877},[3863,4363,3882],{"class":3881},[3863,4365,3939],{"class":3877},[3863,4367,4368,4370,4372,4374,4376,4378,4380,4382,4384],{"class":3865,"line":3942},[3863,4369,3945],{"class":3881},[3863,4371,3948],{"class":3881},[3863,4373,3783],{"class":3877},[3863,4375,3953],{"class":3873},[3863,4377,3956],{"class":3877},[3863,4379,3959],{"class":3873},[3863,4381,3878],{"class":3877},[3863,4383,3965],{"class":3964},[3863,4385,3968],{"class":3877},[3863,4387,4388,4390,4392,4394],{"class":3865,"line":3971},[3863,4389,3974],{"class":3881},[3863,4391,3977],{"class":3869},[3863,4393,3980],{"class":3873},[3863,4395,3983],{"class":3877},[3863,4397,4398],{"class":3865,"line":3986},[3863,4399,3989],{"class":3877},[3863,4401,4402],{"class":3865,"line":3992},[3863,4403,3995],{"class":3877},[3863,4405,4406],{"class":3865,"line":3998},[3863,4407,4002],{"emptyLinePlaceholder":4001},[3863,4409,4410,4412,4414,4416,4418,4420,4422,4424,4426],{"class":3865,"line":4005},[3863,4411,3870],{"class":3869},[3863,4413,4010],{"class":3873},[3863,4415,3878],{"class":3877},[3863,4417,4015],{"class":3881},[3863,4419,3891],{"class":3877},[3863,4421,4303],{"class":3894},[3863,4423,4326],{"class":3877},[3863,4425,4045],{"class":3894},[3863,4427,3928],{"class":3877},[3863,4429,4430,4432,4434,4436,4438,4440,4442,4444,4446,4448,4450,4452,4454,4456,4458,4460,4462,4464,4466,4468,4470,4472,4474],{"class":3865,"line":4050},[3863,4431,3925],{"class":3924},[3863,4433,4055],{"class":3881},[3863,4435,3783],{"class":3877},[3863,4437,3888],{"class":3881},[3863,4439,3783],{"class":3877},[3863,4441,4064],{"class":3881},[3863,4443,4067],{"class":3877},[3863,4445,4070],{"class":3964},[3863,4447,4073],{"class":3877},[3863,4449,4015],{"class":3881},[3863,4451,3783],{"class":3877},[3863,4453,3901],{"class":3881},[3863,4455,3783],{"class":3877},[3863,4457,4084],{"class":3873},[3863,4459,3878],{"class":3877},[3863,4461,4090],{"class":4089},[3863,4463,4093],{"class":3877},[3863,4465,4015],{"class":3881},[3863,4467,3783],{"class":3877},[3863,4469,3910],{"class":3881},[3863,4471,4102],{"class":3877},[3863,4473,4105],{"class":3964},[3863,4475,4108],{"class":3877},[3863,4477,4478],{"class":3865,"line":4111},[3863,4479,3995],{"class":3877},[3863,4481,4483],{"class":3865,"line":4482},12,[3863,4484,4002],{"emptyLinePlaceholder":4001},[3863,4486,4488,4491,4495,4497,4500],{"class":3865,"line":4487},13,[3863,4489,4490],{"class":3869},"const",[3863,4492,4494],{"class":4493},"s-QsJ"," newUser",[3863,4496,4167],{"class":3877},[3863,4498,4499],{"class":3873},"createUser",[3863,4501,4502],{"class":3877},"({ \n",[3863,4504,4506,4509,4512],{"class":3865,"line":4505},14,[3863,4507,4508],{"class":3881},"  name:",[3863,4510,4511],{"class":4089}," 'Олена Шевченко'",[3863,4513,4514],{"class":3877},", \n",[3863,4516,4518,4521,4524],{"class":3865,"line":4517},15,[3863,4519,4520],{"class":3881},"  email:",[3863,4522,4523],{"class":4089}," 'olena@example.com'",[3863,4525,4514],{"class":3877},[3863,4527,4529,4532,4535],{"class":3865,"line":4528},16,[3863,4530,4531],{"class":3881},"  age:",[3863,4533,4534],{"class":3964}," 22",[3863,4536,4537],{"class":3877}," \n",[3863,4539,4541],{"class":3865,"line":4540},17,[3863,4542,4543],{"class":3877},"});\n",[3846,4545,4546,4547,4549],{},"Компілятор TypeScript перевіряє, що об'єкт, переданий як ",[3753,4548,4303],{},", містить усі обов'язкові поля з правильними типами. Якщо передати неповний об'єкт або об'єкт з полями неправильних типів, отримаємо помилку компіляції:",[3854,4551,4553],{"className":3856,"code":4552,"language":3858,"meta":3859,"style":3859},"\u002F\u002F ❌ Error: Property 'age' is missing in type\nconst invalidUser: User = { \n  name: 'Іван', \n  email: 'ivan@example.com' \n};\n\n\u002F\u002F ❌ Error: Type 'string' is not assignable to type 'number'\nconst anotherInvalidUser: User = { \n  name: 'Марія', \n  email: 'maria@example.com', \n  age: 'twenty' \n};\n",[3753,4554,4555,4561,4575,4584,4593,4598,4602,4607,4620,4629,4638,4647],{"__ignoreMap":3859},[3863,4556,4557],{"class":3865,"line":3866},[3863,4558,4560],{"class":4559},"spJ8K","\u002F\u002F ❌ Error: Property 'age' is missing in type\n",[3863,4562,4563,4565,4568,4570,4572],{"class":3865,"line":3921},[3863,4564,4490],{"class":3869},[3863,4566,4567],{"class":4493}," invalidUser",[3863,4569,3891],{"class":3877},[3863,4571,4303],{"class":3894},[3863,4573,4574],{"class":3877}," = { \n",[3863,4576,4577,4579,4582],{"class":3865,"line":3931},[3863,4578,4508],{"class":3881},[3863,4580,4581],{"class":4089}," 'Іван'",[3863,4583,4514],{"class":3877},[3863,4585,4586,4588,4591],{"class":3865,"line":3942},[3863,4587,4520],{"class":3881},[3863,4589,4590],{"class":4089}," 'ivan@example.com'",[3863,4592,4537],{"class":3877},[3863,4594,4595],{"class":3865,"line":3971},[3863,4596,4597],{"class":3877},"};\n",[3863,4599,4600],{"class":3865,"line":3986},[3863,4601,4002],{"emptyLinePlaceholder":4001},[3863,4603,4604],{"class":3865,"line":3992},[3863,4605,4606],{"class":4559},"\u002F\u002F ❌ Error: Type 'string' is not assignable to type 'number'\n",[3863,4608,4609,4611,4614,4616,4618],{"class":3865,"line":3998},[3863,4610,4490],{"class":3869},[3863,4612,4613],{"class":4493}," anotherInvalidUser",[3863,4615,3891],{"class":3877},[3863,4617,4303],{"class":3894},[3863,4619,4574],{"class":3877},[3863,4621,4622,4624,4627],{"class":3865,"line":4005},[3863,4623,4508],{"class":3881},[3863,4625,4626],{"class":4089}," 'Марія'",[3863,4628,4514],{"class":3877},[3863,4630,4631,4633,4636],{"class":3865,"line":4050},[3863,4632,4520],{"class":3881},[3863,4634,4635],{"class":4089}," 'maria@example.com'",[3863,4637,4514],{"class":3877},[3863,4639,4640,4642,4645],{"class":3865,"line":4111},[3863,4641,4531],{"class":3881},[3863,4643,4644],{"class":4089}," 'twenty'",[3863,4646,4537],{"class":3877},[3863,4648,4649],{"class":3865,"line":4482},[3863,4650,4597],{"class":3877},[4237,4652,4654],{"id":4653},"опціональні-властивості-та-readonly-модифікатор","Опціональні властивості та readonly модифікатор",[3846,4656,4657,4658,4661,4662,3756,4665,4661,4668,4671],{},"Як і у inline типах, інтерфейси підтримують ",[3796,4659,4660],{},"опціональні властивості"," через ",[3753,4663,4664],{},"?",[3796,4666,4667],{},"незмінні властивості",[3753,4669,4670],{},"readonly",":",[3854,4673,4675],{"className":3856,"code":4674,"language":3858,"meta":3859,"style":3859},"interface Product {\n  readonly id: string;        \u002F\u002F неможливо змінити після створення\n  name: string;\n  price: number;\n  description?: string;       \u002F\u002F опціональне поле\n  category?: string;\n}\n\nconst laptop: Product = {\n  id: 'prod-001',\n  name: 'MacBook Pro',\n  price: 2500\n  \u002F\u002F description та category відсутні — це допустимо\n};\n\nlaptop.price = 2400;          \u002F\u002F ✅ OK: price не readonly\n\u002F\u002F laptop.id = 'prod-002';    \u002F\u002F ❌ Error: Cannot assign to 'id' because it is a read-only property\n",[3753,4676,4677,4686,4704,4714,4725,4741,4752,4756,4760,4775,4785,4794,4802,4807,4811,4815,4836],{"__ignoreMap":3859},[3863,4678,4679,4681,4684],{"class":3865,"line":3866},[3863,4680,3755],{"class":3869},[3863,4682,4683],{"class":3894}," Product",[3863,4685,3928],{"class":3877},[3863,4687,4688,4691,4694,4696,4698,4701],{"class":3865,"line":3921},[3863,4689,4690],{"class":3869},"  readonly",[3863,4692,4693],{"class":3881}," id",[3863,4695,3891],{"class":3877},[3863,4697,3895],{"class":3894},[3863,4699,4700],{"class":3877},";        ",[3863,4702,4703],{"class":4559},"\u002F\u002F неможливо змінити після створення\n",[3863,4705,4706,4708,4710,4712],{"class":3865,"line":3931},[3863,4707,4265],{"class":3881},[3863,4709,3891],{"class":3877},[3863,4711,3895],{"class":3894},[3863,4713,4108],{"class":3877},[3863,4715,4716,4719,4721,4723],{"class":3865,"line":3942},[3863,4717,4718],{"class":3881},"  price",[3863,4720,3891],{"class":3877},[3863,4722,3915],{"class":3894},[3863,4724,4108],{"class":3877},[3863,4726,4727,4730,4733,4735,4738],{"class":3865,"line":3971},[3863,4728,4729],{"class":3881},"  description",[3863,4731,4732],{"class":3877},"?: ",[3863,4734,3895],{"class":3894},[3863,4736,4737],{"class":3877},";       ",[3863,4739,4740],{"class":4559},"\u002F\u002F опціональне поле\n",[3863,4742,4743,4746,4748,4750],{"class":3865,"line":3986},[3863,4744,4745],{"class":3881},"  category",[3863,4747,4732],{"class":3877},[3863,4749,3895],{"class":3894},[3863,4751,4108],{"class":3877},[3863,4753,4754],{"class":3865,"line":3992},[3863,4755,3995],{"class":3877},[3863,4757,4758],{"class":3865,"line":3998},[3863,4759,4002],{"emptyLinePlaceholder":4001},[3863,4761,4762,4764,4767,4769,4772],{"class":3865,"line":4005},[3863,4763,4490],{"class":3869},[3863,4765,4766],{"class":4493}," laptop",[3863,4768,3891],{"class":3877},[3863,4770,4771],{"class":3894},"Product",[3863,4773,4774],{"class":3877}," = {\n",[3863,4776,4777,4780,4783],{"class":3865,"line":4050},[3863,4778,4779],{"class":3881},"  id:",[3863,4781,4782],{"class":4089}," 'prod-001'",[3863,4784,3939],{"class":3877},[3863,4786,4787,4789,4792],{"class":3865,"line":4111},[3863,4788,4508],{"class":3881},[3863,4790,4791],{"class":4089}," 'MacBook Pro'",[3863,4793,3939],{"class":3877},[3863,4795,4796,4799],{"class":3865,"line":4482},[3863,4797,4798],{"class":3881},"  price:",[3863,4800,4801],{"class":3964}," 2500\n",[3863,4803,4804],{"class":3865,"line":4487},[3863,4805,4806],{"class":4559},"  \u002F\u002F description та category відсутні — це допустимо\n",[3863,4808,4809],{"class":3865,"line":4505},[3863,4810,4597],{"class":3877},[3863,4812,4813],{"class":3865,"line":4517},[3863,4814,4002],{"emptyLinePlaceholder":4001},[3863,4816,4817,4820,4822,4825,4827,4830,4833],{"class":3865,"line":4528},[3863,4818,4819],{"class":3881},"laptop",[3863,4821,3783],{"class":3877},[3863,4823,4824],{"class":3881},"price",[3863,4826,4167],{"class":3877},[3863,4828,4829],{"class":3964},"2400",[3863,4831,4832],{"class":3877},";          ",[3863,4834,4835],{"class":4559},"\u002F\u002F ✅ OK: price не readonly\n",[3863,4837,4838,4841],{"class":3865,"line":4540},[3863,4839,4840],{"class":4559},"\u002F\u002F laptop.id = 'prod-002';",[3863,4842,4843],{"class":4559},"    \u002F\u002F ❌ Error: Cannot assign to 'id' because it is a read-only property\n",[4845,4846,4847,4848,4850,4851,4854],"tip",{},"Використовуйте ",[3753,4849,4670],{}," для властивостей, що представляють ",[3796,4852,4853],{},"ідентифікатори, мітки часу створення або інші незмінні метадані",". Це запобігає випадковій зміні критичних даних у коді та робить інтенції явними: \"це поле встановлюється один раз і більше не змінюється\".",[4237,4856,4858],{"id":4857},"методи-в-інтерфейсах","Методи в інтерфейсах",[3846,4860,4861,4862,4865],{},"Інтерфейси можуть описувати не лише дані, але й ",[3796,4863,4864],{},"поведінку"," — методи, що об'єкт повинен реалізувати. Сигнатура методу визначає ім'я, параметри та тип повернення, але не містить реалізації (це лише контракт):",[3854,4867,4869],{"className":3856,"code":4868,"language":3858,"meta":3859,"style":3859},"interface Logger {\n  log(message: string): void;\n  error(message: string, code?: number): void;\n}\n",[3753,4870,4871,4880,4901,4928],{"__ignoreMap":3859},[3863,4872,4873,4875,4878],{"class":3865,"line":3866},[3863,4874,3755],{"class":3869},[3863,4876,4877],{"class":3894}," Logger",[3863,4879,3928],{"class":3877},[3863,4881,4882,4885,4887,4890,4892,4894,4896,4899],{"class":3865,"line":3921},[3863,4883,4884],{"class":3873},"  log",[3863,4886,3878],{"class":3877},[3863,4888,4889],{"class":3881},"message",[3863,4891,3891],{"class":3877},[3863,4893,3895],{"class":3894},[3863,4895,4326],{"class":3877},[3863,4897,4898],{"class":3894},"void",[3863,4900,4108],{"class":3877},[3863,4902,4903,4906,4908,4910,4912,4914,4916,4918,4920,4922,4924,4926],{"class":3865,"line":3931},[3863,4904,4905],{"class":3873},"  error",[3863,4907,3878],{"class":3877},[3863,4909,4889],{"class":3881},[3863,4911,3891],{"class":3877},[3863,4913,3895],{"class":3894},[3863,4915,3776],{"class":3877},[3863,4917,3753],{"class":3881},[3863,4919,4732],{"class":3877},[3863,4921,3915],{"class":3894},[3863,4923,4326],{"class":3877},[3863,4925,4898],{"class":3894},[3863,4927,4108],{"class":3877},[3863,4929,4930],{"class":3865,"line":3942},[3863,4931,3995],{"class":3877},[3846,4933,4934,4935,4938,4939,3756,4942,4945],{},"Об'єкт, що відповідає інтерфейсу ",[3753,4936,4937],{},"Logger",", зобов'язаний надати методи ",[3753,4940,4941],{},"log",[3753,4943,4944],{},"error"," з вказаними сигнатурами:",[3854,4947,4949],{"className":3856,"code":4948,"language":3858,"meta":3859,"style":3859},"const consoleLogger: Logger = {\n  log(message: string): void {\n    console.log(`[LOG] ${message}`);\n  },\n  error(message: string, code?: number): void {\n    console.error(`[ERROR] ${message}`, code !== undefined ? `Code: ${code}` : '');\n  }\n};\n\nconsoleLogger.log('Сервер запущено на порту 3000');\nconsoleLogger.error('Не вдалося підключитися до бази даних', 1001);\n",[3753,4950,4951,4964,4982,5010,5015,5041,5094,5099,5103,5107,5123],{"__ignoreMap":3859},[3863,4952,4953,4955,4958,4960,4962],{"class":3865,"line":3866},[3863,4954,4490],{"class":3869},[3863,4956,4957],{"class":4493}," consoleLogger",[3863,4959,3891],{"class":3877},[3863,4961,4937],{"class":3894},[3863,4963,4774],{"class":3877},[3863,4965,4966,4968,4970,4972,4974,4976,4978,4980],{"class":3865,"line":3921},[3863,4967,4884],{"class":3873},[3863,4969,3878],{"class":3877},[3863,4971,4889],{"class":3881},[3863,4973,3891],{"class":3877},[3863,4975,3895],{"class":3894},[3863,4977,4326],{"class":3877},[3863,4979,4898],{"class":3894},[3863,4981,3928],{"class":3877},[3863,4983,4984,4987,4989,4991,4993,4996,4999,5001,5004,5007],{"class":3865,"line":3931},[3863,4985,4986],{"class":3881},"    console",[3863,4988,3783],{"class":3877},[3863,4990,4941],{"class":3873},[3863,4992,3878],{"class":3877},[3863,4994,4995],{"class":4089},"`[LOG] ",[3863,4997,4998],{"class":3869},"${",[3863,5000,4889],{"class":3881},[3863,5002,5003],{"class":3869},"}",[3863,5005,5006],{"class":4089},"`",[3863,5008,5009],{"class":3877},");\n",[3863,5011,5012],{"class":3865,"line":3942},[3863,5013,5014],{"class":3877},"  },\n",[3863,5016,5017,5019,5021,5023,5025,5027,5029,5031,5033,5035,5037,5039],{"class":3865,"line":3971},[3863,5018,4905],{"class":3873},[3863,5020,3878],{"class":3877},[3863,5022,4889],{"class":3881},[3863,5024,3891],{"class":3877},[3863,5026,3895],{"class":3894},[3863,5028,3776],{"class":3877},[3863,5030,3753],{"class":3881},[3863,5032,4732],{"class":3877},[3863,5034,3915],{"class":3894},[3863,5036,4326],{"class":3877},[3863,5038,4898],{"class":3894},[3863,5040,3928],{"class":3877},[3863,5042,5043,5045,5047,5049,5051,5054,5056,5058,5060,5062,5064,5066,5069,5072,5075,5078,5080,5082,5084,5086,5089,5092],{"class":3865,"line":3986},[3863,5044,4986],{"class":3881},[3863,5046,3783],{"class":3877},[3863,5048,4944],{"class":3873},[3863,5050,3878],{"class":3877},[3863,5052,5053],{"class":4089},"`[ERROR] ",[3863,5055,4998],{"class":3869},[3863,5057,4889],{"class":3881},[3863,5059,5003],{"class":3869},[3863,5061,5006],{"class":4089},[3863,5063,3776],{"class":3877},[3863,5065,3753],{"class":3881},[3863,5067,5068],{"class":3877}," !== ",[3863,5070,5071],{"class":3869},"undefined",[3863,5073,5074],{"class":3877}," ? ",[3863,5076,5077],{"class":4089},"`Code: ",[3863,5079,4998],{"class":3869},[3863,5081,3753],{"class":3881},[3863,5083,5003],{"class":3869},[3863,5085,5006],{"class":4089},[3863,5087,5088],{"class":3877}," : ",[3863,5090,5091],{"class":4089},"''",[3863,5093,5009],{"class":3877},[3863,5095,5096],{"class":3865,"line":3992},[3863,5097,5098],{"class":3877},"  }\n",[3863,5100,5101],{"class":3865,"line":3998},[3863,5102,4597],{"class":3877},[3863,5104,5105],{"class":3865,"line":4005},[3863,5106,4002],{"emptyLinePlaceholder":4001},[3863,5108,5109,5112,5114,5116,5118,5121],{"class":3865,"line":4050},[3863,5110,5111],{"class":3881},"consoleLogger",[3863,5113,3783],{"class":3877},[3863,5115,4941],{"class":3873},[3863,5117,3878],{"class":3877},[3863,5119,5120],{"class":4089},"'Сервер запущено на порту 3000'",[3863,5122,5009],{"class":3877},[3863,5124,5125,5127,5129,5131,5133,5136,5138,5141],{"class":3865,"line":4111},[3863,5126,5111],{"class":3881},[3863,5128,3783],{"class":3877},[3863,5130,4944],{"class":3873},[3863,5132,3878],{"class":3877},[3863,5134,5135],{"class":4089},"'Не вдалося підключитися до бази даних'",[3863,5137,3776],{"class":3877},[3863,5139,5140],{"class":3964},"1001",[3863,5142,5009],{"class":3877},[3846,5144,5145,5146,5149,5150,5153],{},"Важливо розуміти, що інтерфейс описує ",[3796,5147,5148],{},"лише сигнатуру"," методу, але не його ",[3796,5151,5152],{},"реалізацію",". Реалізація надається об'єктом або класом, що впроваджує цей інтерфейс.",[4145,5155,5156,5172,5236],{},[3846,5157,5158,5161,5162,5165,5166,5168,5169,5171],{},[3796,5159,5160],{},"Чому це корисно?"," Уявімо, що система логування використовується у багатьох модулях застосунку. Замість прив'язування коду до конкретної реалізації (",[3753,5163,5164],{},"console.log","), ми оголошуємо інтерфейс ",[3753,5167,4937],{}," та пишемо функції, що приймають ",[3753,5170,4937],{}," як залежність:",[3854,5173,5175],{"className":3856,"code":5174,"language":3858,"meta":3859,"style":3859},"function processRequest(logger: Logger) {\n  logger.log('Обробка запиту розпочата');\n  \u002F\u002F ... бізнес-логіка\n  logger.log('Обробка запиту завершена');\n}\n",[3753,5176,5177,5196,5212,5217,5232],{"__ignoreMap":3859},[3863,5178,5179,5181,5184,5186,5189,5191,5193],{"class":3865,"line":3866},[3863,5180,3870],{"class":3869},[3863,5182,5183],{"class":3873}," processRequest",[3863,5185,3878],{"class":3877},[3863,5187,5188],{"class":3881},"logger",[3863,5190,3891],{"class":3877},[3863,5192,4937],{"class":3894},[3863,5194,5195],{"class":3877},") {\n",[3863,5197,5198,5201,5203,5205,5207,5210],{"class":3865,"line":3921},[3863,5199,5200],{"class":3881},"  logger",[3863,5202,3783],{"class":3877},[3863,5204,4941],{"class":3873},[3863,5206,3878],{"class":3877},[3863,5208,5209],{"class":4089},"'Обробка запиту розпочата'",[3863,5211,5009],{"class":3877},[3863,5213,5214],{"class":3865,"line":3931},[3863,5215,5216],{"class":4559},"  \u002F\u002F ... бізнес-логіка\n",[3863,5218,5219,5221,5223,5225,5227,5230],{"class":3865,"line":3942},[3863,5220,5200],{"class":3881},[3863,5222,3783],{"class":3877},[3863,5224,4941],{"class":3873},[3863,5226,3878],{"class":3877},[3863,5228,5229],{"class":4089},"'Обробка запиту завершена'",[3863,5231,5009],{"class":3877},[3863,5233,5234],{"class":3865,"line":3971},[3863,5235,3995],{"class":3877},[3846,5237,5238,5239,5241,5242,5244,5245,5248],{},"Тепер ми можемо передати будь-яку реалізацію ",[3753,5240,4937],{},": консольний логер, логер у файл, логер у віддалений сервіс моніторингу — головне, щоб об'єкт задовольняв контракт ",[3753,5243,4937],{},". Це дозволяє легко підміняти реалізацію без зміни коду, що використовує логер, — принцип ",[3796,5246,5247],{},"dependency inversion"," із SOLID.",[4237,5250,5252],{"id":5251},"index-signatures-в-інтерфейсах","Index signatures в інтерфейсах",[3846,5254,5255,5256,5259],{},"Інтерфейси, як і inline об'єктні типи, підтримують ",[3796,5257,5258],{},"index signatures"," для опису об'єктів з динамічною кількістю властивостей:",[3854,5261,5263],{"className":3856,"code":5262,"language":3858,"meta":3859,"style":3859},"interface Dictionary {\n  [key: string]: string;\n}\n\nconst translations: Dictionary = {\n  hello: 'привіт',\n  goodbye: 'до побачення',\n  thanks: 'дякую'\n};\n\nconsole.log(translations['hello']);  \u002F\u002F \"привіт\"\ntranslations['welcome'] = 'ласкаво просимо';  \u002F\u002F ✅ OK\n",[3753,5264,5265,5274,5293,5297,5301,5315,5325,5335,5343,5347,5351,5377],{"__ignoreMap":3859},[3863,5266,5267,5269,5272],{"class":3865,"line":3866},[3863,5268,3755],{"class":3869},[3863,5270,5271],{"class":3894}," Dictionary",[3863,5273,3928],{"class":3877},[3863,5275,5276,5279,5282,5284,5286,5289,5291],{"class":3865,"line":3921},[3863,5277,5278],{"class":3877},"  [",[3863,5280,5281],{"class":3881},"key",[3863,5283,3891],{"class":3877},[3863,5285,3895],{"class":3894},[3863,5287,5288],{"class":3877},"]: ",[3863,5290,3895],{"class":3894},[3863,5292,4108],{"class":3877},[3863,5294,5295],{"class":3865,"line":3931},[3863,5296,3995],{"class":3877},[3863,5298,5299],{"class":3865,"line":3942},[3863,5300,4002],{"emptyLinePlaceholder":4001},[3863,5302,5303,5305,5308,5310,5313],{"class":3865,"line":3971},[3863,5304,4490],{"class":3869},[3863,5306,5307],{"class":4493}," translations",[3863,5309,3891],{"class":3877},[3863,5311,5312],{"class":3894},"Dictionary",[3863,5314,4774],{"class":3877},[3863,5316,5317,5320,5323],{"class":3865,"line":3986},[3863,5318,5319],{"class":3881},"  hello:",[3863,5321,5322],{"class":4089}," 'привіт'",[3863,5324,3939],{"class":3877},[3863,5326,5327,5330,5333],{"class":3865,"line":3992},[3863,5328,5329],{"class":3881},"  goodbye:",[3863,5331,5332],{"class":4089}," 'до побачення'",[3863,5334,3939],{"class":3877},[3863,5336,5337,5340],{"class":3865,"line":3998},[3863,5338,5339],{"class":3881},"  thanks:",[3863,5341,5342],{"class":4089}," 'дякую'\n",[3863,5344,5345],{"class":3865,"line":4005},[3863,5346,4597],{"class":3877},[3863,5348,5349],{"class":3865,"line":4050},[3863,5350,4002],{"emptyLinePlaceholder":4001},[3863,5352,5353,5356,5358,5360,5362,5365,5368,5371,5374],{"class":3865,"line":4111},[3863,5354,5355],{"class":3881},"console",[3863,5357,3783],{"class":3877},[3863,5359,4941],{"class":3873},[3863,5361,3878],{"class":3877},[3863,5363,5364],{"class":3881},"translations",[3863,5366,5367],{"class":3877},"[",[3863,5369,5370],{"class":4089},"'hello'",[3863,5372,5373],{"class":3877},"]);  ",[3863,5375,5376],{"class":4559},"\u002F\u002F \"привіт\"\n",[3863,5378,5379,5381,5383,5386,5389,5392,5395],{"class":3865,"line":4482},[3863,5380,5364],{"class":3881},[3863,5382,5367],{"class":3877},[3863,5384,5385],{"class":4089},"'welcome'",[3863,5387,5388],{"class":3877},"] = ",[3863,5390,5391],{"class":4089},"'ласкаво просимо'",[3863,5393,5394],{"class":3877},";  ",[3863,5396,5397],{"class":4559},"\u002F\u002F ✅ OK\n",[3846,5399,5400],{},"Можна комбінувати index signature з фіксованими властивостями, але типи фіксованих властивостей мають бути сумісними з типом index signature:",[3854,5402,5404],{"className":3856,"code":5403,"language":3858,"meta":3859,"style":3859},"interface Config {\n  readonly version: string;  \u002F\u002F ✅ OK: string сумісний з string\n  [key: string]: string | number;\n}\n\nconst appConfig: Config = {\n  version: '1.0.0',\n  port: 3000,               \u002F\u002F ✅ OK: number сумісний з string | number\n  host: 'localhost'         \u002F\u002F ✅ OK: string сумісний з string | number\n};\n",[3753,5405,5406,5415,5431,5451,5455,5459,5473,5483,5497,5508],{"__ignoreMap":3859},[3863,5407,5408,5410,5413],{"class":3865,"line":3866},[3863,5409,3755],{"class":3869},[3863,5411,5412],{"class":3894}," Config",[3863,5414,3928],{"class":3877},[3863,5416,5417,5419,5422,5424,5426,5428],{"class":3865,"line":3921},[3863,5418,4690],{"class":3869},[3863,5420,5421],{"class":3881}," version",[3863,5423,3891],{"class":3877},[3863,5425,3895],{"class":3894},[3863,5427,5394],{"class":3877},[3863,5429,5430],{"class":4559},"\u002F\u002F ✅ OK: string сумісний з string\n",[3863,5432,5433,5435,5437,5439,5441,5443,5445,5447,5449],{"class":3865,"line":3931},[3863,5434,5278],{"class":3877},[3863,5436,5281],{"class":3881},[3863,5438,3891],{"class":3877},[3863,5440,3895],{"class":3894},[3863,5442,5288],{"class":3877},[3863,5444,3895],{"class":3894},[3863,5446,4173],{"class":3877},[3863,5448,3915],{"class":3894},[3863,5450,4108],{"class":3877},[3863,5452,5453],{"class":3865,"line":3942},[3863,5454,3995],{"class":3877},[3863,5456,5457],{"class":3865,"line":3971},[3863,5458,4002],{"emptyLinePlaceholder":4001},[3863,5460,5461,5463,5466,5468,5471],{"class":3865,"line":3986},[3863,5462,4490],{"class":3869},[3863,5464,5465],{"class":4493}," appConfig",[3863,5467,3891],{"class":3877},[3863,5469,5470],{"class":3894},"Config",[3863,5472,4774],{"class":3877},[3863,5474,5475,5478,5481],{"class":3865,"line":3992},[3863,5476,5477],{"class":3881},"  version:",[3863,5479,5480],{"class":4089}," '1.0.0'",[3863,5482,3939],{"class":3877},[3863,5484,5485,5488,5491,5494],{"class":3865,"line":3998},[3863,5486,5487],{"class":3881},"  port:",[3863,5489,5490],{"class":3964}," 3000",[3863,5492,5493],{"class":3877},",               ",[3863,5495,5496],{"class":4559},"\u002F\u002F ✅ OK: number сумісний з string | number\n",[3863,5498,5499,5502,5505],{"class":3865,"line":4005},[3863,5500,5501],{"class":3881},"  host:",[3863,5503,5504],{"class":4089}," 'localhost'",[3863,5506,5507],{"class":4559},"         \u002F\u002F ✅ OK: string сумісний з string | number\n",[3863,5509,5510],{"class":3865,"line":4050},[3863,5511,4597],{"class":3877},[3838,5513],{},[3841,5515,5517],{"id":5516},"interface-vs-type-семантичні-відмінності-та-практичні-рекомендації","Interface vs Type: семантичні відмінності та практичні рекомендації",[3846,5519,5520,5521,5523,5524,5527],{},"Ви вже знайомі з ",[3753,5522,3759],{}," псевдонімами з попередніх розділів. Інтерфейси та псевдоніми типів у багатьох випадках ",[3796,5525,5526],{},"взаємозамінні",", особливо для опису структур об'єктів:",[3854,5529,5531],{"className":3856,"code":5530,"language":3858,"meta":3859,"style":3859},"\u002F\u002F Через interface\ninterface Point {\n  x: number;\n  y: number;\n}\n\n\u002F\u002F Через type alias\ntype PointType = {\n  x: number;\n  y: number;\n};\n",[3753,5532,5533,5538,5546,5557,5568,5572,5576,5581,5590,5600,5610],{"__ignoreMap":3859},[3863,5534,5535],{"class":3865,"line":3866},[3863,5536,5537],{"class":4559},"\u002F\u002F Через interface\n",[3863,5539,5540,5542,5544],{"class":3865,"line":3921},[3863,5541,3755],{"class":3869},[3863,5543,4190],{"class":3894},[3863,5545,3928],{"class":3877},[3863,5547,5548,5551,5553,5555],{"class":3865,"line":3931},[3863,5549,5550],{"class":3881},"  x",[3863,5552,3891],{"class":3877},[3863,5554,3915],{"class":3894},[3863,5556,4108],{"class":3877},[3863,5558,5559,5562,5564,5566],{"class":3865,"line":3942},[3863,5560,5561],{"class":3881},"  y",[3863,5563,3891],{"class":3877},[3863,5565,3915],{"class":3894},[3863,5567,4108],{"class":3877},[3863,5569,5570],{"class":3865,"line":3971},[3863,5571,3995],{"class":3877},[3863,5573,5574],{"class":3865,"line":3986},[3863,5575,4002],{"emptyLinePlaceholder":4001},[3863,5577,5578],{"class":3865,"line":3992},[3863,5579,5580],{"class":4559},"\u002F\u002F Через type alias\n",[3863,5582,5583,5585,5588],{"class":3865,"line":3998},[3863,5584,3759],{"class":3869},[3863,5586,5587],{"class":3894}," PointType",[3863,5589,4774],{"class":3877},[3863,5591,5592,5594,5596,5598],{"class":3865,"line":4005},[3863,5593,5550],{"class":3881},[3863,5595,3891],{"class":3877},[3863,5597,3915],{"class":3894},[3863,5599,4108],{"class":3877},[3863,5601,5602,5604,5606,5608],{"class":3865,"line":4050},[3863,5603,5561],{"class":3881},[3863,5605,3891],{"class":3877},[3863,5607,3915],{"class":3894},[3863,5609,4108],{"class":3877},[3863,5611,5612],{"class":3865,"line":4111},[3863,5613,4597],{"class":3877},[3846,5615,5616,5617,3756,5619,5621],{},"Обидва підходи створюють тип для об'єкта з полями ",[3753,5618,4196],{},[3753,5620,4205],{},". Проте між ними існують важливі відмінності, що впливають на вибір інструменту.",[4237,5623,5625],{"id":5624},"ключові-відмінності","Ключові відмінності",[3846,5627,5628],{},[3796,5629,5630],{},"1. Розширення (Extending)",[3846,5632,5633,5634,5637,5638,4671],{},"Інтерфейси підтримують ",[3796,5635,5636],{},"наслідування"," через ключове слово ",[3753,5639,5640],{},"extends",[3854,5642,5644],{"className":3856,"code":5643,"language":3858,"meta":3859,"style":3859},"interface Animal {\n  name: string;\n  age: number;\n}\n\ninterface Dog extends Animal {\n  breed: string;\n  bark(): void;\n}\n\nconst myDog: Dog = {\n  name: 'Рекс',\n  age: 3,\n  breed: 'Німецька вівчарка',\n  bark() { console.log('Гав!'); }\n};\n",[3753,5645,5646,5655,5665,5675,5679,5683,5697,5708,5720,5724,5728,5742,5751,5760,5770,5791],{"__ignoreMap":3859},[3863,5647,5648,5650,5653],{"class":3865,"line":3866},[3863,5649,3755],{"class":3869},[3863,5651,5652],{"class":3894}," Animal",[3863,5654,3928],{"class":3877},[3863,5656,5657,5659,5661,5663],{"class":3865,"line":3921},[3863,5658,4265],{"class":3881},[3863,5660,3891],{"class":3877},[3863,5662,3895],{"class":3894},[3863,5664,4108],{"class":3877},[3863,5666,5667,5669,5671,5673],{"class":3865,"line":3931},[3863,5668,4287],{"class":3881},[3863,5670,3891],{"class":3877},[3863,5672,3915],{"class":3894},[3863,5674,4108],{"class":3877},[3863,5676,5677],{"class":3865,"line":3942},[3863,5678,3995],{"class":3877},[3863,5680,5681],{"class":3865,"line":3971},[3863,5682,4002],{"emptyLinePlaceholder":4001},[3863,5684,5685,5687,5690,5693,5695],{"class":3865,"line":3986},[3863,5686,3755],{"class":3869},[3863,5688,5689],{"class":3894}," Dog",[3863,5691,5692],{"class":3869}," extends",[3863,5694,5652],{"class":3894},[3863,5696,3928],{"class":3877},[3863,5698,5699,5702,5704,5706],{"class":3865,"line":3992},[3863,5700,5701],{"class":3881},"  breed",[3863,5703,3891],{"class":3877},[3863,5705,3895],{"class":3894},[3863,5707,4108],{"class":3877},[3863,5709,5710,5713,5716,5718],{"class":3865,"line":3998},[3863,5711,5712],{"class":3873},"  bark",[3863,5714,5715],{"class":3877},"(): ",[3863,5717,4898],{"class":3894},[3863,5719,4108],{"class":3877},[3863,5721,5722],{"class":3865,"line":4005},[3863,5723,3995],{"class":3877},[3863,5725,5726],{"class":3865,"line":4050},[3863,5727,4002],{"emptyLinePlaceholder":4001},[3863,5729,5730,5732,5735,5737,5740],{"class":3865,"line":4111},[3863,5731,4490],{"class":3869},[3863,5733,5734],{"class":4493}," myDog",[3863,5736,3891],{"class":3877},[3863,5738,5739],{"class":3894},"Dog",[3863,5741,4774],{"class":3877},[3863,5743,5744,5746,5749],{"class":3865,"line":4482},[3863,5745,4508],{"class":3881},[3863,5747,5748],{"class":4089}," 'Рекс'",[3863,5750,3939],{"class":3877},[3863,5752,5753,5755,5758],{"class":3865,"line":4487},[3863,5754,4531],{"class":3881},[3863,5756,5757],{"class":3964}," 3",[3863,5759,3939],{"class":3877},[3863,5761,5762,5765,5768],{"class":3865,"line":4505},[3863,5763,5764],{"class":3881},"  breed:",[3863,5766,5767],{"class":4089}," 'Німецька вівчарка'",[3863,5769,3939],{"class":3877},[3863,5771,5772,5774,5777,5779,5781,5783,5785,5788],{"class":3865,"line":4517},[3863,5773,5712],{"class":3873},[3863,5775,5776],{"class":3877},"() { ",[3863,5778,5355],{"class":3881},[3863,5780,3783],{"class":3877},[3863,5782,4941],{"class":3873},[3863,5784,3878],{"class":3877},[3863,5786,5787],{"class":4089},"'Гав!'",[3863,5789,5790],{"class":3877},"); }\n",[3863,5792,5793],{"class":3865,"line":4528},[3863,5794,4597],{"class":3877},[3846,5796,5797,5798,4671],{},"Type aliases можуть досягти аналогічного ефекту через ",[3796,5799,5800],{},"intersection types",[3854,5802,5804],{"className":3856,"code":5803,"language":3858,"meta":3859,"style":3859},"type Animal = {\n  name: string;\n  age: number;\n};\n\ntype Dog = Animal & {\n  breed: string;\n  bark(): void;\n};\n",[3753,5805,5806,5814,5824,5834,5838,5842,5856,5866,5876],{"__ignoreMap":3859},[3863,5807,5808,5810,5812],{"class":3865,"line":3866},[3863,5809,3759],{"class":3869},[3863,5811,5652],{"class":3894},[3863,5813,4774],{"class":3877},[3863,5815,5816,5818,5820,5822],{"class":3865,"line":3921},[3863,5817,4265],{"class":3881},[3863,5819,3891],{"class":3877},[3863,5821,3895],{"class":3894},[3863,5823,4108],{"class":3877},[3863,5825,5826,5828,5830,5832],{"class":3865,"line":3931},[3863,5827,4287],{"class":3881},[3863,5829,3891],{"class":3877},[3863,5831,3915],{"class":3894},[3863,5833,4108],{"class":3877},[3863,5835,5836],{"class":3865,"line":3942},[3863,5837,4597],{"class":3877},[3863,5839,5840],{"class":3865,"line":3971},[3863,5841,4002],{"emptyLinePlaceholder":4001},[3863,5843,5844,5846,5848,5850,5853],{"class":3865,"line":3986},[3863,5845,3759],{"class":3869},[3863,5847,5689],{"class":3894},[3863,5849,4167],{"class":3877},[3863,5851,5852],{"class":3894},"Animal",[3863,5854,5855],{"class":3877}," & {\n",[3863,5857,5858,5860,5862,5864],{"class":3865,"line":3992},[3863,5859,5701],{"class":3881},[3863,5861,3891],{"class":3877},[3863,5863,3895],{"class":3894},[3863,5865,4108],{"class":3877},[3863,5867,5868,5870,5872,5874],{"class":3865,"line":3998},[3863,5869,5712],{"class":3873},[3863,5871,5715],{"class":3877},[3863,5873,4898],{"class":3894},[3863,5875,4108],{"class":3877},[3863,5877,5878],{"class":3865,"line":4005},[3863,5879,4597],{"class":3877},[3846,5881,5882,5883,5885],{},"Результат ідентичний, але ",[3753,5884,5640],{}," у інтерфейсах семантично виразніший: \"Dog розширює Animal\" читається природніше, ніж \"Dog є перетином Animal та додаткових полів\".",[3846,5887,5888],{},[3796,5889,5890],{},"2. Declaration Merging (Об'єднання оголошень)",[3846,5892,5633,5893,5896],{},[3796,5894,5895],{},"declaration merging",": якщо в одному scope оголошено кілька інтерфейсів з однаковим іменем, TypeScript автоматично об'єднає їх в один:",[3854,5898,5900],{"className":3856,"code":5899,"language":3858,"meta":3859,"style":3859},"interface Window {\n  title: string;\n}\n\ninterface Window {\n  close(): void;\n}\n\n\u002F\u002F TypeScript об'єднує обидва оголошення\nconst myWindow: Window = {\n  title: 'Головне вікно',\n  close() { console.log('Закриття вікна'); }\n};\n",[3753,5901,5902,5911,5922,5926,5930,5938,5949,5953,5957,5962,5976,5986,6005],{"__ignoreMap":3859},[3863,5903,5904,5906,5909],{"class":3865,"line":3866},[3863,5905,3755],{"class":3869},[3863,5907,5908],{"class":3894}," Window",[3863,5910,3928],{"class":3877},[3863,5912,5913,5916,5918,5920],{"class":3865,"line":3921},[3863,5914,5915],{"class":3881},"  title",[3863,5917,3891],{"class":3877},[3863,5919,3895],{"class":3894},[3863,5921,4108],{"class":3877},[3863,5923,5924],{"class":3865,"line":3931},[3863,5925,3995],{"class":3877},[3863,5927,5928],{"class":3865,"line":3942},[3863,5929,4002],{"emptyLinePlaceholder":4001},[3863,5931,5932,5934,5936],{"class":3865,"line":3971},[3863,5933,3755],{"class":3869},[3863,5935,5908],{"class":3894},[3863,5937,3928],{"class":3877},[3863,5939,5940,5943,5945,5947],{"class":3865,"line":3986},[3863,5941,5942],{"class":3873},"  close",[3863,5944,5715],{"class":3877},[3863,5946,4898],{"class":3894},[3863,5948,4108],{"class":3877},[3863,5950,5951],{"class":3865,"line":3992},[3863,5952,3995],{"class":3877},[3863,5954,5955],{"class":3865,"line":3998},[3863,5956,4002],{"emptyLinePlaceholder":4001},[3863,5958,5959],{"class":3865,"line":4005},[3863,5960,5961],{"class":4559},"\u002F\u002F TypeScript об'єднує обидва оголошення\n",[3863,5963,5964,5966,5969,5971,5974],{"class":3865,"line":4050},[3863,5965,4490],{"class":3869},[3863,5967,5968],{"class":4493}," myWindow",[3863,5970,3891],{"class":3877},[3863,5972,5973],{"class":3894},"Window",[3863,5975,4774],{"class":3877},[3863,5977,5978,5981,5984],{"class":3865,"line":4111},[3863,5979,5980],{"class":3881},"  title:",[3863,5982,5983],{"class":4089}," 'Головне вікно'",[3863,5985,3939],{"class":3877},[3863,5987,5988,5990,5992,5994,5996,5998,6000,6003],{"class":3865,"line":4482},[3863,5989,5942],{"class":3873},[3863,5991,5776],{"class":3877},[3863,5993,5355],{"class":3881},[3863,5995,3783],{"class":3877},[3863,5997,4941],{"class":3873},[3863,5999,3878],{"class":3877},[3863,6001,6002],{"class":4089},"'Закриття вікна'",[3863,6004,5790],{"class":3877},[3863,6006,6007],{"class":3865,"line":4487},[3863,6008,4597],{"class":3877},[3846,6010,6011,6012,6015,6016,6018,6019,6022],{},"Цей механізм широко використовується для ",[3796,6013,6014],{},"розширення глобальних типів"," (наприклад, додавання власних властивостей до ",[3753,6017,5973],{}," або ",[3753,6020,6021],{},"Array"," у браузерному середовищі).",[3846,6024,6025,6026,6029,6030,6032],{},"Type aliases ",[3796,6027,6028],{},"не підтримують declaration merging"," — спроба оголосити два ",[3753,6031,3759],{}," з однаковим іменем призведе до помилки:",[3854,6034,6036],{"className":3856,"code":6035,"language":3858,"meta":3859,"style":3859},"type Config = { port: number };\n\u002F\u002F type Config = { host: string }; \u002F\u002F ❌ Error: Duplicate identifier 'Config'\n",[3753,6037,6038,6055],{"__ignoreMap":3859},[3863,6039,6040,6042,6044,6046,6049,6051,6053],{"class":3865,"line":3866},[3863,6041,3759],{"class":3869},[3863,6043,5412],{"class":3894},[3863,6045,4193],{"class":3877},[3863,6047,6048],{"class":3881},"port",[3863,6050,3891],{"class":3877},[3863,6052,3915],{"class":3894},[3863,6054,4212],{"class":3877},[3863,6056,6057,6060],{"class":3865,"line":3921},[3863,6058,6059],{"class":4559},"\u002F\u002F type Config = { host: string };",[3863,6061,6062],{"class":4559}," \u002F\u002F ❌ Error: Duplicate identifier 'Config'\n",[3846,6064,6065],{},[3796,6066,6067],{},"3. Що можна описати",[3846,6069,6070,6071,6074],{},"Type aliases більш ",[3796,6072,6073],{},"універсальні",": вони можуть описувати не лише об'єкти, але й union types, intersection types, примітивні типи, кортежі, функціональні типи:",[3854,6076,6078],{"className":3856,"code":6077,"language":3858,"meta":3859,"style":3859},"type ID = string | number;                    \u002F\u002F union\ntype Point = [number, number];                 \u002F\u002F tuple\ntype Callback = (data: string) => void;        \u002F\u002F function\ntype StringOrNumber = string | number;         \u002F\u002F union примітивів\n",[3753,6079,6080,6101,6122,6152],{"__ignoreMap":3859},[3863,6081,6082,6084,6087,6089,6091,6093,6095,6098],{"class":3865,"line":3866},[3863,6083,3759],{"class":3869},[3863,6085,6086],{"class":3894}," ID",[3863,6088,4167],{"class":3877},[3863,6090,3895],{"class":3894},[3863,6092,4173],{"class":3877},[3863,6094,3915],{"class":3894},[3863,6096,6097],{"class":3877},";                    ",[3863,6099,6100],{"class":4559},"\u002F\u002F union\n",[3863,6102,6103,6105,6107,6110,6112,6114,6116,6119],{"class":3865,"line":3921},[3863,6104,3759],{"class":3869},[3863,6106,4190],{"class":3894},[3863,6108,6109],{"class":3877}," = [",[3863,6111,3915],{"class":3894},[3863,6113,3776],{"class":3877},[3863,6115,3915],{"class":3894},[3863,6117,6118],{"class":3877},"];                 ",[3863,6120,6121],{"class":4559},"\u002F\u002F tuple\n",[3863,6123,6124,6126,6129,6132,6134,6136,6138,6141,6144,6147,6149],{"class":3865,"line":3931},[3863,6125,3759],{"class":3869},[3863,6127,6128],{"class":3894}," Callback",[3863,6130,6131],{"class":3877}," = (",[3863,6133,3882],{"class":3881},[3863,6135,3891],{"class":3877},[3863,6137,3895],{"class":3894},[3863,6139,6140],{"class":3877},") ",[3863,6142,6143],{"class":3869},"=>",[3863,6145,6146],{"class":3894}," void",[3863,6148,4700],{"class":3877},[3863,6150,6151],{"class":4559},"\u002F\u002F function\n",[3863,6153,6154,6156,6159,6161,6163,6165,6167,6170],{"class":3865,"line":3942},[3863,6155,3759],{"class":3869},[3863,6157,6158],{"class":3894}," StringOrNumber",[3863,6160,4167],{"class":3877},[3863,6162,3895],{"class":3894},[3863,6164,4173],{"class":3877},[3863,6166,3915],{"class":3894},[3863,6168,6169],{"class":3877},";         ",[3863,6171,6172],{"class":4559},"\u002F\u002F union примітивів\n",[3846,6174,6175,6176,6179],{},"Інтерфейси ",[3796,6177,6178],{},"призначені для об'єктів та класів",". Вони не можуть описувати union types або примітиви:",[3854,6181,6183],{"className":3856,"code":6182,"language":3858,"meta":3859,"style":3859},"\u002F\u002F ❌ Error: An interface can only extend an object type\n\u002F\u002F interface ID extends string | number {}\n",[3753,6184,6185,6190],{"__ignoreMap":3859},[3863,6186,6187],{"class":3865,"line":3866},[3863,6188,6189],{"class":4559},"\u002F\u002F ❌ Error: An interface can only extend an object type\n",[3863,6191,6192],{"class":3865,"line":3921},[3863,6193,6194],{"class":4559},"\u002F\u002F interface ID extends string | number {}\n",[3846,6196,6197],{},[3796,6198,6199],{},"4. Повідомлення про помилки",[3846,6201,6202,6203,6206,6207,6210],{},"Компілятор TypeScript у повідомленнях про помилки часто ",[3796,6204,6205],{},"показує інтерфейси за іменем",", тоді як type aliases можуть бути ",[3796,6208,6209],{},"розгорнуті"," до своєї структури. Це робить помилки з інтерфейсами зрозумілішими:",[3854,6212,6214],{"className":3856,"code":6213,"language":3858,"meta":3859,"style":3859},"interface User {\n  name: string;\n  email: string;\n}\n\nfunction greet(user: User) {\n  console.log(`Привіт, ${user.name}`);\n}\n\n\u002F\u002F ❌ Error: Argument of type '{ name: string; }' is not assignable to parameter of type 'User'.\n\u002F\u002F           Property 'email' is missing in type '{ name: string; }' but required in type 'User'.\ngreet({ name: 'Олександр' });\n",[3753,6215,6216,6224,6234,6244,6248,6252,6269,6298,6302,6306,6311,6316],{"__ignoreMap":3859},[3863,6217,6218,6220,6222],{"class":3865,"line":3866},[3863,6219,3755],{"class":3869},[3863,6221,4258],{"class":3894},[3863,6223,3928],{"class":3877},[3863,6225,6226,6228,6230,6232],{"class":3865,"line":3921},[3863,6227,4265],{"class":3881},[3863,6229,3891],{"class":3877},[3863,6231,3895],{"class":3894},[3863,6233,4108],{"class":3877},[3863,6235,6236,6238,6240,6242],{"class":3865,"line":3931},[3863,6237,4276],{"class":3881},[3863,6239,3891],{"class":3877},[3863,6241,3895],{"class":3894},[3863,6243,4108],{"class":3877},[3863,6245,6246],{"class":3865,"line":3942},[3863,6247,3995],{"class":3877},[3863,6249,6250],{"class":3865,"line":3971},[3863,6251,4002],{"emptyLinePlaceholder":4001},[3863,6253,6254,6256,6259,6261,6263,6265,6267],{"class":3865,"line":3986},[3863,6255,3870],{"class":3869},[3863,6257,6258],{"class":3873}," greet",[3863,6260,3878],{"class":3877},[3863,6262,4015],{"class":3881},[3863,6264,3891],{"class":3877},[3863,6266,4303],{"class":3894},[3863,6268,5195],{"class":3877},[3863,6270,6271,6274,6276,6278,6280,6283,6285,6287,6290,6292,6294,6296],{"class":3865,"line":3992},[3863,6272,6273],{"class":3881},"  console",[3863,6275,3783],{"class":3877},[3863,6277,4941],{"class":3873},[3863,6279,3878],{"class":3877},[3863,6281,6282],{"class":4089},"`Привіт, ",[3863,6284,4998],{"class":3869},[3863,6286,4015],{"class":3881},[3863,6288,3783],{"class":6289},"sD7JJ",[3863,6291,3888],{"class":3881},[3863,6293,5003],{"class":3869},[3863,6295,5006],{"class":4089},[3863,6297,5009],{"class":3877},[3863,6299,6300],{"class":3865,"line":3998},[3863,6301,3995],{"class":3877},[3863,6303,6304],{"class":3865,"line":4005},[3863,6305,4002],{"emptyLinePlaceholder":4001},[3863,6307,6308],{"class":3865,"line":4050},[3863,6309,6310],{"class":4559},"\u002F\u002F ❌ Error: Argument of type '{ name: string; }' is not assignable to parameter of type 'User'.\n",[3863,6312,6313],{"class":3865,"line":4111},[3863,6314,6315],{"class":4559},"\u002F\u002F           Property 'email' is missing in type '{ name: string; }' but required in type 'User'.\n",[3863,6317,6318,6321,6324,6327,6330],{"class":3865,"line":4482},[3863,6319,6320],{"class":3873},"greet",[3863,6322,6323],{"class":3877},"({ ",[3863,6325,6326],{"class":3881},"name:",[3863,6328,6329],{"class":4089}," 'Олександр'",[3863,6331,6332],{"class":3877}," });\n",[3846,6334,6335,6336,6338],{},"Помилка чітко вказує на інтерфейс ",[3753,6337,4303],{}," та відсутнє поле. З type alias повідомлення може бути більш громіздким, особливо для складних типів.",[4237,6340,6342],{"id":6341},"практичні-рекомендації","Практичні рекомендації",[4845,6344,6345,6352,6393,6399],{},[3846,6346,6347],{},[3796,6348,6349,6350,4671],{},"Коли використовувати ",[3753,6351,3755],{},[3746,6353,6354,6364,6373,6380],{},[3749,6355,6356,6357,3756,6360,6363],{},"Для опису ",[3796,6358,6359],{},"структур об'єктів",[3796,6361,6362],{},"контрактів поведінки"," (особливо коли об'єкт або клас реалізовуватиме інтерфейс).",[3749,6365,6366,6367,4661,6370,6372],{},"Коли потрібна можливість ",[3796,6368,6369],{},"розширення",[3753,6371,5640],{}," (наслідування інтерфейсів).",[3749,6374,6375,6376,6379],{},"Коли пишете ",[3796,6377,6378],{},"публічну бібліотеку"," і хочете дозволити користувачам розширювати ваші типи через declaration merging.",[3749,6381,6382,6383,3756,6386,4227,6389,6392],{},"Для ",[3796,6384,6385],{},"доменних моделей",[3796,6387,6388],{},"DTO",[4229,6390,6391],{},"Data Transfer Objects","), що представляють сутності предметної області.",[3846,6394,6395],{},[3796,6396,6349,6397,4671],{},[3753,6398,3759],{},[3746,6400,6401,6412,6421,6428],{},[3749,6402,6382,6403,3756,6406,6408,6409,3783],{},[3796,6404,6405],{},"union types",[3796,6407,5800],{}," складних комбінацій: ",[3753,6410,6411],{},"type Status = 'idle' | 'loading' | 'success' | 'error'",[3749,6413,6382,6414,6417,6418,3783],{},[3796,6415,6416],{},"примітивних псевдонімів",", кортежів, функціональних типів: ",[3753,6419,6420],{},"type ID = string; type Point = [number, number]",[3749,6422,6423,6424,6427],{},"Коли потрібна більша ",[3796,6425,6426],{},"гнучкість"," у композиції типів (mapped types, conditional types — вивчатимуться у наступних розділах).",[3749,6429,6382,6430,6433],{},[3796,6431,6432],{},"внутрішніх допоміжних типів"," у модулі, що не призначені для розширення ззовні.",[3846,6435,6436,6437,3756,6439,6441,6442,6445],{},"У багатьох ситуаціях вибір між ",[3753,6438,3755],{},[3753,6440,3759],{}," є питанням стилю та командних домовленостей. Головне — ",[3796,6443,6444],{},"бути послідовним"," у межах проєкту.",[6447,6448,6449,6450,3756,6452,6454],"warning",{},"Уникайте змішування ",[3753,6451,3755],{},[3753,6453,3759],{}," для опису однієї сутності без причини. Якщо ви почали описувати доменну модель через інтерфейси, продовжуйте у тому ж ключі для узгодженості коду.",[3838,6456],{},[3841,6458,6460],{"id":6459},"наслідування-інтерфейсів-через-extends","Наслідування інтерфейсів через extends",[3846,6462,5633,6463,4227,6465,6468,6469,6472,6473,6476,6477,6480],{},[3796,6464,5636],{},[4229,6466,6467],{},"inheritance","), що дозволяє створювати ",[3796,6470,6471],{},"ієрархії типів"," та повторно використовувати спільні частини структур. Інтерфейс-нащадок (",[4229,6474,6475],{},"derived interface",") успадковує всі властивості та методи батьківського інтерфейсу (",[4229,6478,6479],{},"base interface",") та може додавати власні.",[4237,6482,6484],{"id":6483},"одиночне-наслідування","Одиночне наслідування",[3854,6486,6488],{"className":3856,"code":6487,"language":3858,"meta":3859,"style":3859},"interface Person {\n  firstName: string;\n  lastName: string;\n  age: number;\n}\n\ninterface Employee extends Person {\n  employeeId: string;\n  position: string;\n  salary: number;\n}\n\nconst employee: Employee = {\n  firstName: 'Олександр',\n  lastName: 'Коваленко',\n  age: 28,\n  employeeId: 'EMP-12345',\n  position: 'Backend Developer',\n  salary: 50000\n};\n",[3753,6489,6490,6499,6510,6521,6531,6535,6539,6552,6563,6574,6585,6589,6593,6607,6616,6626,6635,6645,6656,6665],{"__ignoreMap":3859},[3863,6491,6492,6494,6497],{"class":3865,"line":3866},[3863,6493,3755],{"class":3869},[3863,6495,6496],{"class":3894}," Person",[3863,6498,3928],{"class":3877},[3863,6500,6501,6504,6506,6508],{"class":3865,"line":3921},[3863,6502,6503],{"class":3881},"  firstName",[3863,6505,3891],{"class":3877},[3863,6507,3895],{"class":3894},[3863,6509,4108],{"class":3877},[3863,6511,6512,6515,6517,6519],{"class":3865,"line":3931},[3863,6513,6514],{"class":3881},"  lastName",[3863,6516,3891],{"class":3877},[3863,6518,3895],{"class":3894},[3863,6520,4108],{"class":3877},[3863,6522,6523,6525,6527,6529],{"class":3865,"line":3942},[3863,6524,4287],{"class":3881},[3863,6526,3891],{"class":3877},[3863,6528,3915],{"class":3894},[3863,6530,4108],{"class":3877},[3863,6532,6533],{"class":3865,"line":3971},[3863,6534,3995],{"class":3877},[3863,6536,6537],{"class":3865,"line":3986},[3863,6538,4002],{"emptyLinePlaceholder":4001},[3863,6540,6541,6543,6546,6548,6550],{"class":3865,"line":3992},[3863,6542,3755],{"class":3869},[3863,6544,6545],{"class":3894}," Employee",[3863,6547,5692],{"class":3869},[3863,6549,6496],{"class":3894},[3863,6551,3928],{"class":3877},[3863,6553,6554,6557,6559,6561],{"class":3865,"line":3998},[3863,6555,6556],{"class":3881},"  employeeId",[3863,6558,3891],{"class":3877},[3863,6560,3895],{"class":3894},[3863,6562,4108],{"class":3877},[3863,6564,6565,6568,6570,6572],{"class":3865,"line":4005},[3863,6566,6567],{"class":3881},"  position",[3863,6569,3891],{"class":3877},[3863,6571,3895],{"class":3894},[3863,6573,4108],{"class":3877},[3863,6575,6576,6579,6581,6583],{"class":3865,"line":4050},[3863,6577,6578],{"class":3881},"  salary",[3863,6580,3891],{"class":3877},[3863,6582,3915],{"class":3894},[3863,6584,4108],{"class":3877},[3863,6586,6587],{"class":3865,"line":4111},[3863,6588,3995],{"class":3877},[3863,6590,6591],{"class":3865,"line":4482},[3863,6592,4002],{"emptyLinePlaceholder":4001},[3863,6594,6595,6597,6600,6602,6605],{"class":3865,"line":4487},[3863,6596,4490],{"class":3869},[3863,6598,6599],{"class":4493}," employee",[3863,6601,3891],{"class":3877},[3863,6603,6604],{"class":3894},"Employee",[3863,6606,4774],{"class":3877},[3863,6608,6609,6612,6614],{"class":3865,"line":4505},[3863,6610,6611],{"class":3881},"  firstName:",[3863,6613,6329],{"class":4089},[3863,6615,3939],{"class":3877},[3863,6617,6618,6621,6624],{"class":3865,"line":4517},[3863,6619,6620],{"class":3881},"  lastName:",[3863,6622,6623],{"class":4089}," 'Коваленко'",[3863,6625,3939],{"class":3877},[3863,6627,6628,6630,6633],{"class":3865,"line":4528},[3863,6629,4531],{"class":3881},[3863,6631,6632],{"class":3964}," 28",[3863,6634,3939],{"class":3877},[3863,6636,6637,6640,6643],{"class":3865,"line":4540},[3863,6638,6639],{"class":3881},"  employeeId:",[3863,6641,6642],{"class":4089}," 'EMP-12345'",[3863,6644,3939],{"class":3877},[3863,6646,6648,6651,6654],{"class":3865,"line":6647},18,[3863,6649,6650],{"class":3881},"  position:",[3863,6652,6653],{"class":4089}," 'Backend Developer'",[3863,6655,3939],{"class":3877},[3863,6657,6659,6662],{"class":3865,"line":6658},19,[3863,6660,6661],{"class":3881},"  salary:",[3863,6663,6664],{"class":3964}," 50000\n",[3863,6666,6668],{"class":3865,"line":6667},20,[3863,6669,4597],{"class":3877},[3846,6671,6672,6673,6675,6676,3776,6679,3776,6682,6684,6685,6688,6689,6691],{},"Інтерфейс ",[3753,6674,6604],{}," автоматично включає поля ",[3753,6677,6678],{},"firstName",[3753,6680,6681],{},"lastName",[3753,6683,3910],{}," з ",[3753,6686,6687],{},"Person"," та додає три власні поля. Об'єкт типу ",[3753,6690,6604],{}," має задовольняти обидва контракти.",[4237,6693,6695],{"id":6694},"множинне-наслідування","Множинне наслідування",[3846,6697,6698,6699,6702],{},"На відміну від класів у багатьох мовах (де множинне наслідування заборонене або обмежене), інтерфейси TypeScript можуть ",[3796,6700,6701],{},"успадковувати від кількох батьківських інтерфейсів"," одночасно:",[3854,6704,6706],{"className":3856,"code":6705,"language":3858,"meta":3859,"style":3859},"interface Loggable {\n  log(message: string): void;\n}\n\ninterface Serializable {\n  toJSON(): string;\n}\n\ninterface Entity extends Loggable, Serializable {\n  id: string;\n  createdAt: Date;\n}\n\nconst userEntity: Entity = {\n  id: 'user-001',\n  createdAt: new Date(),\n  log(message: string) {\n    console.log(`[Entity ${this.id}] ${message}`);\n  },\n  toJSON() {\n    return JSON.stringify({ id: this.id, createdAt: this.createdAt });\n  }\n};\n",[3753,6707,6708,6717,6735,6739,6743,6752,6763,6767,6771,6789,6800,6811,6815,6819,6833,6842,6854,6868,6905,6909,6916,6955,6960],{"__ignoreMap":3859},[3863,6709,6710,6712,6715],{"class":3865,"line":3866},[3863,6711,3755],{"class":3869},[3863,6713,6714],{"class":3894}," Loggable",[3863,6716,3928],{"class":3877},[3863,6718,6719,6721,6723,6725,6727,6729,6731,6733],{"class":3865,"line":3921},[3863,6720,4884],{"class":3873},[3863,6722,3878],{"class":3877},[3863,6724,4889],{"class":3881},[3863,6726,3891],{"class":3877},[3863,6728,3895],{"class":3894},[3863,6730,4326],{"class":3877},[3863,6732,4898],{"class":3894},[3863,6734,4108],{"class":3877},[3863,6736,6737],{"class":3865,"line":3931},[3863,6738,3995],{"class":3877},[3863,6740,6741],{"class":3865,"line":3942},[3863,6742,4002],{"emptyLinePlaceholder":4001},[3863,6744,6745,6747,6750],{"class":3865,"line":3971},[3863,6746,3755],{"class":3869},[3863,6748,6749],{"class":3894}," Serializable",[3863,6751,3928],{"class":3877},[3863,6753,6754,6757,6759,6761],{"class":3865,"line":3986},[3863,6755,6756],{"class":3873},"  toJSON",[3863,6758,5715],{"class":3877},[3863,6760,3895],{"class":3894},[3863,6762,4108],{"class":3877},[3863,6764,6765],{"class":3865,"line":3992},[3863,6766,3995],{"class":3877},[3863,6768,6769],{"class":3865,"line":3998},[3863,6770,4002],{"emptyLinePlaceholder":4001},[3863,6772,6773,6775,6778,6780,6782,6784,6787],{"class":3865,"line":4005},[3863,6774,3755],{"class":3869},[3863,6776,6777],{"class":3894}," Entity",[3863,6779,5692],{"class":3869},[3863,6781,6714],{"class":3894},[3863,6783,3776],{"class":3877},[3863,6785,6786],{"class":3894},"Serializable",[3863,6788,3928],{"class":3877},[3863,6790,6791,6794,6796,6798],{"class":3865,"line":4050},[3863,6792,6793],{"class":3881},"  id",[3863,6795,3891],{"class":3877},[3863,6797,3895],{"class":3894},[3863,6799,4108],{"class":3877},[3863,6801,6802,6805,6807,6809],{"class":3865,"line":4111},[3863,6803,6804],{"class":3881},"  createdAt",[3863,6806,3891],{"class":3877},[3863,6808,4348],{"class":3894},[3863,6810,4108],{"class":3877},[3863,6812,6813],{"class":3865,"line":4482},[3863,6814,3995],{"class":3877},[3863,6816,6817],{"class":3865,"line":4487},[3863,6818,4002],{"emptyLinePlaceholder":4001},[3863,6820,6821,6823,6826,6828,6831],{"class":3865,"line":4505},[3863,6822,4490],{"class":3869},[3863,6824,6825],{"class":4493}," userEntity",[3863,6827,3891],{"class":3877},[3863,6829,6830],{"class":3894},"Entity",[3863,6832,4774],{"class":3877},[3863,6834,6835,6837,6840],{"class":3865,"line":4517},[3863,6836,4779],{"class":3881},[3863,6838,6839],{"class":4089}," 'user-001'",[3863,6841,3939],{"class":3877},[3863,6843,6844,6847,6849,6851],{"class":3865,"line":4528},[3863,6845,6846],{"class":3881},"  createdAt:",[3863,6848,3977],{"class":3869},[3863,6850,3980],{"class":3873},[3863,6852,6853],{"class":3877},"(),\n",[3863,6855,6856,6858,6860,6862,6864,6866],{"class":3865,"line":4540},[3863,6857,4884],{"class":3873},[3863,6859,3878],{"class":3877},[3863,6861,4889],{"class":3881},[3863,6863,3891],{"class":3877},[3863,6865,3895],{"class":3894},[3863,6867,5195],{"class":3877},[3863,6869,6870,6872,6874,6876,6878,6881,6883,6886,6888,6890,6892,6895,6897,6899,6901,6903],{"class":3865,"line":6647},[3863,6871,4986],{"class":3881},[3863,6873,3783],{"class":3877},[3863,6875,4941],{"class":3873},[3863,6877,3878],{"class":3877},[3863,6879,6880],{"class":4089},"`[Entity ",[3863,6882,4998],{"class":3869},[3863,6884,6885],{"class":3869},"this",[3863,6887,3783],{"class":6289},[3863,6889,4334],{"class":3881},[3863,6891,5003],{"class":3869},[3863,6893,6894],{"class":4089},"] ",[3863,6896,4998],{"class":3869},[3863,6898,4889],{"class":3881},[3863,6900,5003],{"class":3869},[3863,6902,5006],{"class":4089},[3863,6904,5009],{"class":3877},[3863,6906,6907],{"class":3865,"line":6658},[3863,6908,5014],{"class":3877},[3863,6910,6911,6913],{"class":3865,"line":6667},[3863,6912,6756],{"class":3873},[3863,6914,6915],{"class":3877},"() {\n",[3863,6917,6919,6922,6925,6927,6930,6932,6935,6938,6940,6942,6944,6947,6949,6951,6953],{"class":3865,"line":6918},21,[3863,6920,6921],{"class":3924},"    return",[3863,6923,6924],{"class":4493}," JSON",[3863,6926,3783],{"class":3877},[3863,6928,6929],{"class":3873},"stringify",[3863,6931,6323],{"class":3877},[3863,6933,6934],{"class":3881},"id:",[3863,6936,6937],{"class":3869}," this",[3863,6939,3783],{"class":3877},[3863,6941,4334],{"class":3881},[3863,6943,3776],{"class":3877},[3863,6945,6946],{"class":3881},"createdAt:",[3863,6948,6937],{"class":3869},[3863,6950,3783],{"class":3877},[3863,6952,4343],{"class":3881},[3863,6954,6332],{"class":3877},[3863,6956,6958],{"class":3865,"line":6957},22,[3863,6959,5098],{"class":3877},[3863,6961,6963],{"class":3865,"line":6962},23,[3863,6964,4597],{"class":3877},[3846,6966,6672,6967,6969,6970,3756,6973,6975,6976,6978],{},[3753,6968,6830],{}," успадковує методи з ",[3753,6971,6972],{},"Loggable",[3753,6974,6786],{},", а також додає власні поля. Об'єкт, що реалізує ",[3753,6977,6830],{},", зобов'язаний надати всі чотири елементи.",[4237,6980,6982],{"id":6981},"перевизначення-властивостей-при-наслідуванні","Перевизначення властивостей при наслідуванні",[3846,6984,6985,6986,6989,6990,6993],{},"Інтерфейс-нащадок може ",[3796,6987,6988],{},"звузити тип"," батьківської властивості (зробити його більш специфічним), але не може ",[3796,6991,6992],{},"розширити"," (зробити менш специфічним):",[3854,6995,6997],{"className":3856,"code":6996,"language":3858,"meta":3859,"style":3859},"interface Animal {\n  name: string;\n  age: number | null;  \u002F\u002F може бути null (вік невідомий)\n}\n\ninterface Dog extends Animal {\n  age: number;         \u002F\u002F ✅ OK: звуження типу (прибираємо null)\n  breed: string;\n}\n\nconst dog: Dog = {\n  name: 'Бобік',\n  age: 5,              \u002F\u002F тепер age обов'язково число, не може бути null\n  breed: 'Лабрадор'\n};\n",[3753,6998,6999,7007,7017,7035,7039,7043,7055,7068,7078,7082,7086,7099,7108,7121,7128],{"__ignoreMap":3859},[3863,7000,7001,7003,7005],{"class":3865,"line":3866},[3863,7002,3755],{"class":3869},[3863,7004,5652],{"class":3894},[3863,7006,3928],{"class":3877},[3863,7008,7009,7011,7013,7015],{"class":3865,"line":3921},[3863,7010,4265],{"class":3881},[3863,7012,3891],{"class":3877},[3863,7014,3895],{"class":3894},[3863,7016,4108],{"class":3877},[3863,7018,7019,7021,7023,7025,7027,7030,7032],{"class":3865,"line":3931},[3863,7020,4287],{"class":3881},[3863,7022,3891],{"class":3877},[3863,7024,3915],{"class":3894},[3863,7026,4173],{"class":3877},[3863,7028,7029],{"class":3894},"null",[3863,7031,5394],{"class":3877},[3863,7033,7034],{"class":4559},"\u002F\u002F може бути null (вік невідомий)\n",[3863,7036,7037],{"class":3865,"line":3942},[3863,7038,3995],{"class":3877},[3863,7040,7041],{"class":3865,"line":3971},[3863,7042,4002],{"emptyLinePlaceholder":4001},[3863,7044,7045,7047,7049,7051,7053],{"class":3865,"line":3986},[3863,7046,3755],{"class":3869},[3863,7048,5689],{"class":3894},[3863,7050,5692],{"class":3869},[3863,7052,5652],{"class":3894},[3863,7054,3928],{"class":3877},[3863,7056,7057,7059,7061,7063,7065],{"class":3865,"line":3992},[3863,7058,4287],{"class":3881},[3863,7060,3891],{"class":3877},[3863,7062,3915],{"class":3894},[3863,7064,6169],{"class":3877},[3863,7066,7067],{"class":4559},"\u002F\u002F ✅ OK: звуження типу (прибираємо null)\n",[3863,7069,7070,7072,7074,7076],{"class":3865,"line":3998},[3863,7071,5701],{"class":3881},[3863,7073,3891],{"class":3877},[3863,7075,3895],{"class":3894},[3863,7077,4108],{"class":3877},[3863,7079,7080],{"class":3865,"line":4005},[3863,7081,3995],{"class":3877},[3863,7083,7084],{"class":3865,"line":4050},[3863,7085,4002],{"emptyLinePlaceholder":4001},[3863,7087,7088,7090,7093,7095,7097],{"class":3865,"line":4111},[3863,7089,4490],{"class":3869},[3863,7091,7092],{"class":4493}," dog",[3863,7094,3891],{"class":3877},[3863,7096,5739],{"class":3894},[3863,7098,4774],{"class":3877},[3863,7100,7101,7103,7106],{"class":3865,"line":4482},[3863,7102,4508],{"class":3881},[3863,7104,7105],{"class":4089}," 'Бобік'",[3863,7107,3939],{"class":3877},[3863,7109,7110,7112,7115,7118],{"class":3865,"line":4487},[3863,7111,4531],{"class":3881},[3863,7113,7114],{"class":3964}," 5",[3863,7116,7117],{"class":3877},",              ",[3863,7119,7120],{"class":4559},"\u002F\u002F тепер age обов'язково число, не може бути null\n",[3863,7122,7123,7125],{"class":3865,"line":4505},[3863,7124,5764],{"class":3881},[3863,7126,7127],{"class":4089}," 'Лабрадор'\n",[3863,7129,7130],{"class":3865,"line":4517},[3863,7131,4597],{"class":3877},[3846,7133,7134],{},"Спроба розширити тип призведе до помилки:",[3854,7136,7138],{"className":3856,"code":7137,"language":3858,"meta":3859,"style":3859},"interface Cat extends Animal {\n  \u002F\u002F ❌ Error: Interface 'Cat' incorrectly extends interface 'Animal'.\n  \u002F\u002F           Types of property 'name' are incompatible.\n  name: string | number;  \u002F\u002F спроба розширити тип з string до string | number\n}\n",[3753,7139,7140,7153,7158,7163,7180],{"__ignoreMap":3859},[3863,7141,7142,7144,7147,7149,7151],{"class":3865,"line":3866},[3863,7143,3755],{"class":3869},[3863,7145,7146],{"class":3894}," Cat",[3863,7148,5692],{"class":3869},[3863,7150,5652],{"class":3894},[3863,7152,3928],{"class":3877},[3863,7154,7155],{"class":3865,"line":3921},[3863,7156,7157],{"class":4559},"  \u002F\u002F ❌ Error: Interface 'Cat' incorrectly extends interface 'Animal'.\n",[3863,7159,7160],{"class":3865,"line":3931},[3863,7161,7162],{"class":4559},"  \u002F\u002F           Types of property 'name' are incompatible.\n",[3863,7164,7165,7167,7169,7171,7173,7175,7177],{"class":3865,"line":3942},[3863,7166,4265],{"class":3881},[3863,7168,3891],{"class":3877},[3863,7170,3895],{"class":3894},[3863,7172,4173],{"class":3877},[3863,7174,3915],{"class":3894},[3863,7176,5394],{"class":3877},[3863,7178,7179],{"class":4559},"\u002F\u002F спроба розширити тип з string до string | number\n",[3863,7181,7182],{"class":3865,"line":3971},[3863,7183,3995],{"class":3877},[4145,7185,7186,7189,7190,7193,7194,7197,7198,7201,7202,7204,7205,7207,7208,7210,7211,7213,7214,7216,7217,4227,7220,7223],{},[3796,7187,7188],{},"Чому заборонено розширення типу?"," Якби ",[3753,7191,7192],{},"Cat.name"," міг бути ",[3753,7195,7196],{},"string | number",", то об'єкт типу ",[3753,7199,7200],{},"Cat"," не міг би бути безпечно використаний там, де очікується ",[3753,7203,5852],{}," (адже код, що працює з ",[3753,7206,5852],{},", очікує ",[3753,7209,3888],{}," типу ",[3753,7212,3895],{},", а отримав би можливість ",[3753,7215,3915],{},"). Це порушило б ",[3796,7218,7219],{},"принцип підстановки Лісков",[4229,7221,7222],{},"Liskov Substitution Principle","), один з фундаментальних принципів об'єктно-орієнтованого програмування.",[3838,7225],{},[3841,7227,7229],{"id":7228},"класи-у-javascript-прототипна-природа-та-синтаксичний-цукор","Класи у JavaScript: прототипна природа та синтаксичний цукор",[3846,7231,7232,7233,7236,7237,4227,7240,7243,7244,4227,7247,7250],{},"Перш ніж занурюватися у типізацію класів через TypeScript, критично важливо зрозуміти, ",[3796,7234,7235],{},"як насправді працюють класи у JavaScript",". На відміну від класичних об'єктно-орієнтованих мов (Java, C#, C++), де класи є фундаментальною частиною мови, у JavaScript класи — це ",[3796,7238,7239],{},"синтаксичний цукор",[4229,7241,7242],{},"syntactic sugar",") поверх ",[3796,7245,7246],{},"прототипної моделі наслідування",[4229,7248,7249],{},"prototypal inheritance","), що існувала у мові з самого початку.",[4237,7252,7254],{"id":7253},"прототипи-основа-обєктів-javascript","Прототипи: основа об'єктів JavaScript",[3846,7256,7257,7258,4227,7261,7264,7265,4227,7268,7271,7272,3783],{},"У JavaScript кожен об'єкт має внутрішнє посилання на інший об'єкт, що називається його ",[3796,7259,7260],{},"прототипом",[4229,7262,7263],{},"prototype","). Коли ви намагаєтеся звернутися до властивості об'єкта, і ця властивість не знайдена безпосередньо у самому об'єкті, JavaScript автоматично шукає цю властивість у прототипі об'єкта, потім у прототипі прототипа, і так далі, формуючи ",[3796,7266,7267],{},"ланцюг прототипів",[4229,7269,7270],{},"prototype chain","). Цей процес називається ",[3796,7273,7274],{},"прототипним lookup",[3846,7276,7277],{},"Розглянемо найпростіший приклад створення об'єкта через літерал:",[3854,7279,7283],{"className":7280,"code":7281,"language":7282,"meta":3859,"style":3859},"language-javascript shiki shiki-themes light-plus dark-plus dark-plus","const user = {\n  name: 'Марія',\n  age: 25\n};\n\nconsole.log(user.toString());  \u002F\u002F \"[object Object]\"\n","javascript",[3753,7284,7285,7293,7301,7308,7312,7316],{"__ignoreMap":3859},[3863,7286,7287,7289,7291],{"class":3865,"line":3866},[3863,7288,4490],{"class":3869},[3863,7290,4055],{"class":4493},[3863,7292,4774],{"class":3877},[3863,7294,7295,7297,7299],{"class":3865,"line":3921},[3863,7296,4508],{"class":3881},[3863,7298,4626],{"class":4089},[3863,7300,3939],{"class":3877},[3863,7302,7303,7305],{"class":3865,"line":3931},[3863,7304,4531],{"class":3881},[3863,7306,7307],{"class":3964}," 25\n",[3863,7309,7310],{"class":3865,"line":3942},[3863,7311,4597],{"class":3877},[3863,7313,7314],{"class":3865,"line":3971},[3863,7315,4002],{"emptyLinePlaceholder":4001},[3863,7317,7318,7320,7322,7324,7326,7328,7330,7332,7335],{"class":3865,"line":3986},[3863,7319,5355],{"class":3881},[3863,7321,3783],{"class":3877},[3863,7323,4941],{"class":3873},[3863,7325,3878],{"class":3877},[3863,7327,4015],{"class":3881},[3863,7329,3783],{"class":3877},[3863,7331,3959],{"class":3873},[3863,7333,7334],{"class":3877},"());  ",[3863,7336,7337],{"class":4559},"\u002F\u002F \"[object Object]\"\n",[3846,7339,7340,7341,7343,7344,7346,7347,7350,7351,7353,7354,7356,7357,7360,7361,7363,7364,7366],{},"Об'єкт ",[3753,7342,4015],{}," не має власного методу ",[3753,7345,3959],{},", але виклик ",[3753,7348,7349],{},"user.toString()"," не призводить до помилки. Як це працює? JavaScript шукає ",[3753,7352,3959],{}," у прототипі ",[3753,7355,4015],{},", яким є ",[3753,7358,7359],{},"Object.prototype"," — базовий прототип для всіх об'єктів у мові. ",[3753,7362,7359],{}," містить метод ",[3753,7365,3959],{},", тому виклик успішний.",[7368,7369,7371],"plant-uml",{"alt":7370},"Ланцюг прототипів JavaScript",[3854,7372,7376],{"className":7373,"code":7374,"language":7375,"meta":3859,"style":3859},"language-plantuml shiki shiki-themes light-plus dark-plus dark-plus","@startuml\nskinparam style plain\nskinparam backgroundColor #FFFFFF\n\nobject \"user\" as user #DBEAFE {\n  name = \"Марія\"\n  age = 25\n  [[Prototype]] = Object.prototype\n}\n\nobject \"Object.prototype\" as ObjProto #DCFCE7 {\n  toString: function\n  valueOf: function\n  hasOwnProperty: function\n  [[Prototype]] = null\n}\n\nuser -down-> ObjProto : [[Prototype]]\n\nnote right of user\n  Коли викликається user.toString(),\n  JavaScript не знаходить toString\n  у самому user, тому йде по ланцюгу\n  прототипів до Object.prototype\nend note\n@enduml\n","plantuml",[3753,7377,7378,7383,7388,7393,7397,7402,7407,7412,7417,7421,7425,7430,7435,7440,7445,7450,7454,7458,7463,7467,7472,7477,7482,7487,7493,7499],{"__ignoreMap":3859},[3863,7379,7380],{"class":3865,"line":3866},[3863,7381,7382],{},"@startuml\n",[3863,7384,7385],{"class":3865,"line":3921},[3863,7386,7387],{},"skinparam style plain\n",[3863,7389,7390],{"class":3865,"line":3931},[3863,7391,7392],{},"skinparam backgroundColor #FFFFFF\n",[3863,7394,7395],{"class":3865,"line":3942},[3863,7396,4002],{"emptyLinePlaceholder":4001},[3863,7398,7399],{"class":3865,"line":3971},[3863,7400,7401],{},"object \"user\" as user #DBEAFE {\n",[3863,7403,7404],{"class":3865,"line":3986},[3863,7405,7406],{},"  name = \"Марія\"\n",[3863,7408,7409],{"class":3865,"line":3992},[3863,7410,7411],{},"  age = 25\n",[3863,7413,7414],{"class":3865,"line":3998},[3863,7415,7416],{},"  [[Prototype]] = Object.prototype\n",[3863,7418,7419],{"class":3865,"line":4005},[3863,7420,3995],{},[3863,7422,7423],{"class":3865,"line":4050},[3863,7424,4002],{"emptyLinePlaceholder":4001},[3863,7426,7427],{"class":3865,"line":4111},[3863,7428,7429],{},"object \"Object.prototype\" as ObjProto #DCFCE7 {\n",[3863,7431,7432],{"class":3865,"line":4482},[3863,7433,7434],{},"  toString: function\n",[3863,7436,7437],{"class":3865,"line":4487},[3863,7438,7439],{},"  valueOf: function\n",[3863,7441,7442],{"class":3865,"line":4505},[3863,7443,7444],{},"  hasOwnProperty: function\n",[3863,7446,7447],{"class":3865,"line":4517},[3863,7448,7449],{},"  [[Prototype]] = null\n",[3863,7451,7452],{"class":3865,"line":4528},[3863,7453,3995],{},[3863,7455,7456],{"class":3865,"line":4540},[3863,7457,4002],{"emptyLinePlaceholder":4001},[3863,7459,7460],{"class":3865,"line":6647},[3863,7461,7462],{},"user -down-> ObjProto : [[Prototype]]\n",[3863,7464,7465],{"class":3865,"line":6658},[3863,7466,4002],{"emptyLinePlaceholder":4001},[3863,7468,7469],{"class":3865,"line":6667},[3863,7470,7471],{},"note right of user\n",[3863,7473,7474],{"class":3865,"line":6918},[3863,7475,7476],{},"  Коли викликається user.toString(),\n",[3863,7478,7479],{"class":3865,"line":6957},[3863,7480,7481],{},"  JavaScript не знаходить toString\n",[3863,7483,7484],{"class":3865,"line":6962},[3863,7485,7486],{},"  у самому user, тому йде по ланцюгу\n",[3863,7488,7490],{"class":3865,"line":7489},24,[3863,7491,7492],{},"  прототипів до Object.prototype\n",[3863,7494,7496],{"class":3865,"line":7495},25,[3863,7497,7498],{},"end note\n",[3863,7500,7502],{"class":3865,"line":7501},26,[3863,7503,7504],{},"@enduml\n",[4237,7506,7508],{"id":7507},"функції-конструктори-прообраз-класів","Функції-конструктори: прообраз класів",[3846,7510,7511,7512,7515,7516,4227,7519,7522],{},"До появи синтаксису ",[3753,7513,7514],{},"class"," у ES2015 розробники JavaScript використовували ",[3796,7517,7518],{},"функції-конструктори",[4229,7520,7521],{},"constructor functions",") для створення об'єктів з спільним прототипом:",[3854,7524,7526],{"className":7280,"code":7525,"language":7282,"meta":3859,"style":3859},"function User(name, age) {\n  this.name = name;\n  this.age = age;\n}\n\nUser.prototype.greet = function() {\n  return `Привіт, мене звати ${this.name}`;\n};\n\nconst user1 = new User('Олександр', 30);\nconst user2 = new User('Олена', 28);\n\nconsole.log(user1.greet());  \u002F\u002F \"Привіт, мене звати Олександр\"\nconsole.log(user2.greet());  \u002F\u002F \"Привіт, мене звати Олена\"\n",[3753,7527,7528,7544,7559,7573,7577,7581,7599,7620,7624,7628,7654,7679,7683,7705],{"__ignoreMap":3859},[3863,7529,7530,7532,7534,7536,7538,7540,7542],{"class":3865,"line":3866},[3863,7531,3870],{"class":3869},[3863,7533,4258],{"class":3873},[3863,7535,3878],{"class":3877},[3863,7537,3888],{"class":3881},[3863,7539,3776],{"class":3877},[3863,7541,3910],{"class":3881},[3863,7543,5195],{"class":3877},[3863,7545,7546,7549,7551,7553,7555,7557],{"class":3865,"line":3921},[3863,7547,7548],{"class":3869},"  this",[3863,7550,3783],{"class":3877},[3863,7552,3888],{"class":3881},[3863,7554,4167],{"class":3877},[3863,7556,3888],{"class":3881},[3863,7558,4108],{"class":3877},[3863,7560,7561,7563,7565,7567,7569,7571],{"class":3865,"line":3931},[3863,7562,7548],{"class":3869},[3863,7564,3783],{"class":3877},[3863,7566,3910],{"class":3881},[3863,7568,4167],{"class":3877},[3863,7570,3910],{"class":3881},[3863,7572,4108],{"class":3877},[3863,7574,7575],{"class":3865,"line":3942},[3863,7576,3995],{"class":3877},[3863,7578,7579],{"class":3865,"line":3971},[3863,7580,4002],{"emptyLinePlaceholder":4001},[3863,7582,7583,7585,7587,7589,7591,7593,7595,7597],{"class":3865,"line":3986},[3863,7584,4303],{"class":3894},[3863,7586,3783],{"class":3877},[3863,7588,7263],{"class":3881},[3863,7590,3783],{"class":3877},[3863,7592,6320],{"class":3873},[3863,7594,4167],{"class":3877},[3863,7596,3870],{"class":3869},[3863,7598,6915],{"class":3877},[3863,7600,7601,7603,7606,7608,7610,7612,7614,7616,7618],{"class":3865,"line":3992},[3863,7602,3925],{"class":3924},[3863,7604,7605],{"class":4089}," `Привіт, мене звати ",[3863,7607,4998],{"class":3869},[3863,7609,6885],{"class":3869},[3863,7611,3783],{"class":6289},[3863,7613,3888],{"class":3881},[3863,7615,5003],{"class":3869},[3863,7617,5006],{"class":4089},[3863,7619,4108],{"class":3877},[3863,7621,7622],{"class":3865,"line":3998},[3863,7623,4597],{"class":3877},[3863,7625,7626],{"class":3865,"line":4005},[3863,7627,4002],{"emptyLinePlaceholder":4001},[3863,7629,7630,7632,7635,7637,7640,7642,7644,7647,7649,7652],{"class":3865,"line":4050},[3863,7631,4490],{"class":3869},[3863,7633,7634],{"class":4493}," user1",[3863,7636,4167],{"class":3877},[3863,7638,7639],{"class":3869},"new",[3863,7641,4258],{"class":3873},[3863,7643,3878],{"class":3877},[3863,7645,7646],{"class":4089},"'Олександр'",[3863,7648,3776],{"class":3877},[3863,7650,7651],{"class":3964},"30",[3863,7653,5009],{"class":3877},[3863,7655,7656,7658,7661,7663,7665,7667,7669,7672,7674,7677],{"class":3865,"line":4111},[3863,7657,4490],{"class":3869},[3863,7659,7660],{"class":4493}," user2",[3863,7662,4167],{"class":3877},[3863,7664,7639],{"class":3869},[3863,7666,4258],{"class":3873},[3863,7668,3878],{"class":3877},[3863,7670,7671],{"class":4089},"'Олена'",[3863,7673,3776],{"class":3877},[3863,7675,7676],{"class":3964},"28",[3863,7678,5009],{"class":3877},[3863,7680,7681],{"class":3865,"line":4482},[3863,7682,4002],{"emptyLinePlaceholder":4001},[3863,7684,7685,7687,7689,7691,7693,7696,7698,7700,7702],{"class":3865,"line":4487},[3863,7686,5355],{"class":3881},[3863,7688,3783],{"class":3877},[3863,7690,4941],{"class":3873},[3863,7692,3878],{"class":3877},[3863,7694,7695],{"class":3881},"user1",[3863,7697,3783],{"class":3877},[3863,7699,6320],{"class":3873},[3863,7701,7334],{"class":3877},[3863,7703,7704],{"class":4559},"\u002F\u002F \"Привіт, мене звати Олександр\"\n",[3863,7706,7707,7709,7711,7713,7715,7718,7720,7722,7724],{"class":3865,"line":4505},[3863,7708,5355],{"class":3881},[3863,7710,3783],{"class":3877},[3863,7712,4941],{"class":3873},[3863,7714,3878],{"class":3877},[3863,7716,7717],{"class":3881},"user2",[3863,7719,3783],{"class":3877},[3863,7721,6320],{"class":3873},[3863,7723,7334],{"class":3877},[3863,7725,7726],{"class":4559},"\u002F\u002F \"Привіт, мене звати Олена\"\n",[3846,7728,7729,7730,4671],{},"Що відбувається при виклику ",[3753,7731,7732],{},"new User('Олександр', 30)",[7734,7735,7736,7742,7748,7761],"ol",{},[3749,7737,7738,7739,3783],{},"Створюється новий порожній об'єкт ",[3753,7740,7741],{},"{}",[3749,7743,7744,7745,3783],{},"Встановлюється прототип цього об'єкта: ",[3753,7746,7747],{},"{}.__proto__ = User.prototype",[3749,7749,7750,7751,7753,7754,7756,7757,3756,7759,3783],{},"Функція ",[3753,7752,4303],{}," викликається з ",[3753,7755,6885],{},", прив'язаним до нового об'єкта, і встановлює властивості ",[3753,7758,3888],{},[3753,7760,3910],{},[3749,7762,7763],{},"Повертається новостворений об'єкт (якщо конструктор не повертає інший об'єкт явно).",[3846,7765,7766,7767,3756,7769,7771,7772,3756,7774,7776,7777,7780,7781,7783,7784,7787,7788,7790],{},"Обидва екземпляри ",[3753,7768,7695],{},[3753,7770,7717],{}," мають власні властивості ",[3753,7773,3888],{},[3753,7775,3910],{},", але ",[3796,7778,7779],{},"спільний метод"," ",[3753,7782,6320],{},", що знаходиться у ",[3753,7785,7786],{},"User.prototype",". Це економить пам'ять: замість створення нової копії функції ",[3753,7789,6320],{}," для кожного користувача, усі екземпляри спільно використовують одну функцію з прототипа.",[4145,7792,7793,7796,7797,7799],{},[3796,7794,7795],{},"Чому це важливо для розуміння класів TypeScript?"," Тому що під капотом синтаксис ",[3753,7798,7514],{}," компілюється саме у функцію-конструктор з прототипами. TypeScript не змінює поведінку JavaScript — він лише додає типізацію поверх існуючої прототипної моделі.",[4237,7801,7803],{"id":7802},"синтаксис-class-у-es2015-та-компіляція-typescript","Синтаксис class у ES2015 та компіляція TypeScript",[3846,7805,7806,7807,7809],{},"У ES2015 (ES6) до JavaScript додали синтаксис ",[3753,7808,7514],{},", що робить код більш читабельним та схожим на інші ОО-мови:",[3854,7811,7813],{"className":7280,"code":7812,"language":7282,"meta":3859,"style":3859},"class User {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n\n  greet() {\n    return `Привіт, мене звати ${this.name}`;\n  }\n}\n\nconst user = new User('Ігор', 32);\nconsole.log(user.greet());\n",[3753,7814,7815,7823,7838,7853,7867,7871,7875,7882,7902,7906,7910,7914,7938],{"__ignoreMap":3859},[3863,7816,7817,7819,7821],{"class":3865,"line":3866},[3863,7818,7514],{"class":3869},[3863,7820,4258],{"class":3894},[3863,7822,3928],{"class":3877},[3863,7824,7825,7828,7830,7832,7834,7836],{"class":3865,"line":3921},[3863,7826,7827],{"class":3869},"  constructor",[3863,7829,3878],{"class":3877},[3863,7831,3888],{"class":3881},[3863,7833,3776],{"class":3877},[3863,7835,3910],{"class":3881},[3863,7837,5195],{"class":3877},[3863,7839,7840,7843,7845,7847,7849,7851],{"class":3865,"line":3931},[3863,7841,7842],{"class":3869},"    this",[3863,7844,3783],{"class":3877},[3863,7846,3888],{"class":3881},[3863,7848,4167],{"class":3877},[3863,7850,3888],{"class":3881},[3863,7852,4108],{"class":3877},[3863,7854,7855,7857,7859,7861,7863,7865],{"class":3865,"line":3942},[3863,7856,7842],{"class":3869},[3863,7858,3783],{"class":3877},[3863,7860,3910],{"class":3881},[3863,7862,4167],{"class":3877},[3863,7864,3910],{"class":3881},[3863,7866,4108],{"class":3877},[3863,7868,7869],{"class":3865,"line":3971},[3863,7870,5098],{"class":3877},[3863,7872,7873],{"class":3865,"line":3986},[3863,7874,4002],{"emptyLinePlaceholder":4001},[3863,7876,7877,7880],{"class":3865,"line":3992},[3863,7878,7879],{"class":3873},"  greet",[3863,7881,6915],{"class":3877},[3863,7883,7884,7886,7888,7890,7892,7894,7896,7898,7900],{"class":3865,"line":3998},[3863,7885,6921],{"class":3924},[3863,7887,7605],{"class":4089},[3863,7889,4998],{"class":3869},[3863,7891,6885],{"class":3869},[3863,7893,3783],{"class":6289},[3863,7895,3888],{"class":3881},[3863,7897,5003],{"class":3869},[3863,7899,5006],{"class":4089},[3863,7901,4108],{"class":3877},[3863,7903,7904],{"class":3865,"line":4005},[3863,7905,5098],{"class":3877},[3863,7907,7908],{"class":3865,"line":4050},[3863,7909,3995],{"class":3877},[3863,7911,7912],{"class":3865,"line":4111},[3863,7913,4002],{"emptyLinePlaceholder":4001},[3863,7915,7916,7918,7920,7922,7924,7926,7928,7931,7933,7936],{"class":3865,"line":4482},[3863,7917,4490],{"class":3869},[3863,7919,4055],{"class":4493},[3863,7921,4167],{"class":3877},[3863,7923,7639],{"class":3869},[3863,7925,4258],{"class":3873},[3863,7927,3878],{"class":3877},[3863,7929,7930],{"class":4089},"'Ігор'",[3863,7932,3776],{"class":3877},[3863,7934,7935],{"class":3964},"32",[3863,7937,5009],{"class":3877},[3863,7939,7940,7942,7944,7946,7948,7950,7952,7954],{"class":3865,"line":4487},[3863,7941,5355],{"class":3881},[3863,7943,3783],{"class":3877},[3863,7945,4941],{"class":3873},[3863,7947,3878],{"class":3877},[3863,7949,4015],{"class":3881},[3863,7951,3783],{"class":3877},[3863,7953,6320],{"class":3873},[3863,7955,7956],{"class":3877},"());\n",[3846,7958,7959,7960,7963,7964,7966,7967,7969,7970,7973,7974,7976,7977,7980],{},"Цей код ",[3796,7961,7962],{},"функціонально ідентичний"," попередньому прикладу з функцією-конструктором: метод ",[3753,7965,6320],{}," додається до ",[3753,7968,7786],{},", а ",[3753,7971,7972],{},"constructor"," — це та сама функція-конструктор. Синтаксис ",[3753,7975,7514],{}," — це лише ",[3796,7978,7979],{},"більш зручна обгортка"," над прототипами, але прототипна модель залишається незмінною.",[3846,7982,7983,7984,7986],{},"Коли TypeScript компілює клас з таргетом ES5 (який не підтримує ",[3753,7985,7514],{},"), він генерує функцію-конструктор:",[3854,7988,7990],{"className":3856,"code":7989,"language":3858,"meta":3859,"style":3859},"\u002F\u002F TypeScript код\nclass Counter {\n  count = 0;\n\n  increment() {\n    this.count++;\n  }\n}\n",[3753,7991,7992,7997,8006,8017,8021,8028,8040,8044],{"__ignoreMap":3859},[3863,7993,7994],{"class":3865,"line":3866},[3863,7995,7996],{"class":4559},"\u002F\u002F TypeScript код\n",[3863,7998,7999,8001,8004],{"class":3865,"line":3921},[3863,8000,7514],{"class":3869},[3863,8002,8003],{"class":3894}," Counter",[3863,8005,3928],{"class":3877},[3863,8007,8008,8011,8013,8015],{"class":3865,"line":3931},[3863,8009,8010],{"class":3881},"  count",[3863,8012,4167],{"class":3877},[3863,8014,4070],{"class":3964},[3863,8016,4108],{"class":3877},[3863,8018,8019],{"class":3865,"line":3942},[3863,8020,4002],{"emptyLinePlaceholder":4001},[3863,8022,8023,8026],{"class":3865,"line":3971},[3863,8024,8025],{"class":3873},"  increment",[3863,8027,6915],{"class":3877},[3863,8029,8030,8032,8034,8037],{"class":3865,"line":3986},[3863,8031,7842],{"class":3869},[3863,8033,3783],{"class":3877},[3863,8035,8036],{"class":3881},"count",[3863,8038,8039],{"class":3877},"++;\n",[3863,8041,8042],{"class":3865,"line":3992},[3863,8043,5098],{"class":3877},[3863,8045,8046],{"class":3865,"line":3998},[3863,8047,3995],{"class":3877},[3854,8049,8051],{"className":7280,"code":8050,"language":7282,"meta":3859,"style":3859},"\u002F\u002F Компіляція у ES5\n\"use strict\";\nvar Counter = \u002F** @class *\u002F (function () {\n    function Counter() {\n        this.count = 0;\n    }\n    Counter.prototype.increment = function () {\n        this.count++;\n    };\n    return Counter;\n}());\n",[3753,8052,8053,8058,8065,8090,8099,8114,8119,8139,8149,8154,8162],{"__ignoreMap":3859},[3863,8054,8055],{"class":3865,"line":3866},[3863,8056,8057],{"class":4559},"\u002F\u002F Компіляція у ES5\n",[3863,8059,8060,8063],{"class":3865,"line":3921},[3863,8061,8062],{"class":4089},"\"use strict\"",[3863,8064,4108],{"class":3877},[3863,8066,8067,8070,8072,8074,8077,8080,8083,8085,8087],{"class":3865,"line":3931},[3863,8068,8069],{"class":3869},"var",[3863,8071,8003],{"class":3881},[3863,8073,4167],{"class":3877},[3863,8075,8076],{"class":4559},"\u002F** ",[3863,8078,8079],{"class":3869},"@class",[3863,8081,8082],{"class":4559}," *\u002F",[3863,8084,4227],{"class":3877},[3863,8086,3870],{"class":3869},[3863,8088,8089],{"class":3877}," () {\n",[3863,8091,8092,8095,8097],{"class":3865,"line":3942},[3863,8093,8094],{"class":3869},"    function",[3863,8096,8003],{"class":3873},[3863,8098,6915],{"class":3877},[3863,8100,8101,8104,8106,8108,8110,8112],{"class":3865,"line":3971},[3863,8102,8103],{"class":3869},"        this",[3863,8105,3783],{"class":3877},[3863,8107,8036],{"class":3881},[3863,8109,4167],{"class":3877},[3863,8111,4070],{"class":3964},[3863,8113,4108],{"class":3877},[3863,8115,8116],{"class":3865,"line":3986},[3863,8117,8118],{"class":3877},"    }\n",[3863,8120,8121,8124,8126,8128,8130,8133,8135,8137],{"class":3865,"line":3992},[3863,8122,8123],{"class":3894},"    Counter",[3863,8125,3783],{"class":3877},[3863,8127,7263],{"class":3881},[3863,8129,3783],{"class":3877},[3863,8131,8132],{"class":3873},"increment",[3863,8134,4167],{"class":3877},[3863,8136,3870],{"class":3869},[3863,8138,8089],{"class":3877},[3863,8140,8141,8143,8145,8147],{"class":3865,"line":3998},[3863,8142,8103],{"class":3869},[3863,8144,3783],{"class":3877},[3863,8146,8036],{"class":3881},[3863,8148,8039],{"class":3877},[3863,8150,8151],{"class":3865,"line":4005},[3863,8152,8153],{"class":3877},"    };\n",[3863,8155,8156,8158,8160],{"class":3865,"line":4050},[3863,8157,6921],{"class":3924},[3863,8159,8003],{"class":3881},[3863,8161,4108],{"class":3877},[3863,8163,8164],{"class":3865,"line":4111},[3863,8165,8166],{"class":3877},"}());\n",[3846,8168,8169,8170,8173],{},"Розуміння цього перетворення допомагає усвідомити, що ",[3796,8171,8172],{},"класи TypeScript — це насамперед JavaScript-класи"," з додатковою типізацією часу компіляції.",[3838,8175],{},[3841,8177,8179],{"id":8178},"базовий-синтаксис-класів-у-typescript","Базовий синтаксис класів у TypeScript",[3846,8181,8182],{},"Тепер, коли ми розуміємо прототипну основу, розглянемо, як TypeScript типізує та розширює функціональність класів.",[4237,8184,8186],{"id":8185},"оголошення-класу-та-конструктор","Оголошення класу та конструктор",[3846,8188,8189,8190,8192],{},"Клас оголошується через ключове слово ",[3753,8191,7514],{},", за яким слідує ім'я класу та тіло класу у фігурних дужках:",[3854,8194,8196],{"className":3856,"code":8195,"language":3858,"meta":3859,"style":3859},"class User {\n  name: string;\n  email: string;\n  age: number;\n\n  constructor(name: string, email: string, age: number) {\n    this.name = name;\n    this.email = email;\n    this.age = age;\n  }\n\n  greet(): string {\n    return `Привіт, мене звати ${this.name}, мені ${this.age} років`;\n  }\n}\n\nconst user = new User('Анна', 'anna@example.com', 27);\nconsole.log(user.greet());  \u002F\u002F \"Привіт, мене звати Анна, мені 27 років\"\n",[3753,8197,8198,8206,8216,8226,8236,8240,8270,8284,8298,8312,8316,8320,8330,8364,8368,8372,8376,8405],{"__ignoreMap":3859},[3863,8199,8200,8202,8204],{"class":3865,"line":3866},[3863,8201,7514],{"class":3869},[3863,8203,4258],{"class":3894},[3863,8205,3928],{"class":3877},[3863,8207,8208,8210,8212,8214],{"class":3865,"line":3921},[3863,8209,4265],{"class":3881},[3863,8211,3891],{"class":3877},[3863,8213,3895],{"class":3894},[3863,8215,4108],{"class":3877},[3863,8217,8218,8220,8222,8224],{"class":3865,"line":3931},[3863,8219,4276],{"class":3881},[3863,8221,3891],{"class":3877},[3863,8223,3895],{"class":3894},[3863,8225,4108],{"class":3877},[3863,8227,8228,8230,8232,8234],{"class":3865,"line":3942},[3863,8229,4287],{"class":3881},[3863,8231,3891],{"class":3877},[3863,8233,3915],{"class":3894},[3863,8235,4108],{"class":3877},[3863,8237,8238],{"class":3865,"line":3971},[3863,8239,4002],{"emptyLinePlaceholder":4001},[3863,8241,8242,8244,8246,8248,8250,8252,8254,8256,8258,8260,8262,8264,8266,8268],{"class":3865,"line":3986},[3863,8243,7827],{"class":3869},[3863,8245,3878],{"class":3877},[3863,8247,3888],{"class":3881},[3863,8249,3891],{"class":3877},[3863,8251,3895],{"class":3894},[3863,8253,3776],{"class":3877},[3863,8255,3901],{"class":3881},[3863,8257,3891],{"class":3877},[3863,8259,3895],{"class":3894},[3863,8261,3776],{"class":3877},[3863,8263,3910],{"class":3881},[3863,8265,3891],{"class":3877},[3863,8267,3915],{"class":3894},[3863,8269,5195],{"class":3877},[3863,8271,8272,8274,8276,8278,8280,8282],{"class":3865,"line":3992},[3863,8273,7842],{"class":3869},[3863,8275,3783],{"class":3877},[3863,8277,3888],{"class":3881},[3863,8279,4167],{"class":3877},[3863,8281,3888],{"class":3881},[3863,8283,4108],{"class":3877},[3863,8285,8286,8288,8290,8292,8294,8296],{"class":3865,"line":3998},[3863,8287,7842],{"class":3869},[3863,8289,3783],{"class":3877},[3863,8291,3901],{"class":3881},[3863,8293,4167],{"class":3877},[3863,8295,3901],{"class":3881},[3863,8297,4108],{"class":3877},[3863,8299,8300,8302,8304,8306,8308,8310],{"class":3865,"line":4005},[3863,8301,7842],{"class":3869},[3863,8303,3783],{"class":3877},[3863,8305,3910],{"class":3881},[3863,8307,4167],{"class":3877},[3863,8309,3910],{"class":3881},[3863,8311,4108],{"class":3877},[3863,8313,8314],{"class":3865,"line":4050},[3863,8315,5098],{"class":3877},[3863,8317,8318],{"class":3865,"line":4111},[3863,8319,4002],{"emptyLinePlaceholder":4001},[3863,8321,8322,8324,8326,8328],{"class":3865,"line":4482},[3863,8323,7879],{"class":3873},[3863,8325,5715],{"class":3877},[3863,8327,3895],{"class":3894},[3863,8329,3928],{"class":3877},[3863,8331,8332,8334,8336,8338,8340,8342,8344,8346,8349,8351,8353,8355,8357,8359,8362],{"class":3865,"line":4487},[3863,8333,6921],{"class":3924},[3863,8335,7605],{"class":4089},[3863,8337,4998],{"class":3869},[3863,8339,6885],{"class":3869},[3863,8341,3783],{"class":6289},[3863,8343,3888],{"class":3881},[3863,8345,5003],{"class":3869},[3863,8347,8348],{"class":4089},", мені ",[3863,8350,4998],{"class":3869},[3863,8352,6885],{"class":3869},[3863,8354,3783],{"class":6289},[3863,8356,3910],{"class":3881},[3863,8358,5003],{"class":3869},[3863,8360,8361],{"class":4089}," років`",[3863,8363,4108],{"class":3877},[3863,8365,8366],{"class":3865,"line":4505},[3863,8367,5098],{"class":3877},[3863,8369,8370],{"class":3865,"line":4517},[3863,8371,3995],{"class":3877},[3863,8373,8374],{"class":3865,"line":4528},[3863,8375,4002],{"emptyLinePlaceholder":4001},[3863,8377,8378,8380,8382,8384,8386,8388,8390,8393,8395,8398,8400,8403],{"class":3865,"line":4540},[3863,8379,4490],{"class":3869},[3863,8381,4055],{"class":4493},[3863,8383,4167],{"class":3877},[3863,8385,7639],{"class":3869},[3863,8387,4258],{"class":3873},[3863,8389,3878],{"class":3877},[3863,8391,8392],{"class":4089},"'Анна'",[3863,8394,3776],{"class":3877},[3863,8396,8397],{"class":4089},"'anna@example.com'",[3863,8399,3776],{"class":3877},[3863,8401,8402],{"class":3964},"27",[3863,8404,5009],{"class":3877},[3863,8406,8407,8409,8411,8413,8415,8417,8419,8421,8423],{"class":3865,"line":6647},[3863,8408,5355],{"class":3881},[3863,8410,3783],{"class":3877},[3863,8412,4941],{"class":3873},[3863,8414,3878],{"class":3877},[3863,8416,4015],{"class":3881},[3863,8418,3783],{"class":3877},[3863,8420,6320],{"class":3873},[3863,8422,7334],{"class":3877},[3863,8424,8425],{"class":4559},"\u002F\u002F \"Привіт, мене звати Анна, мені 27 років\"\n",[3846,8427,8428,4227,8431,8433,8434,8436,8437,3776,8439,3776,8441,8443],{},[3796,8429,8430],{},"Конструктор",[4229,8432,7972],{},") — це спеціальний метод, що викликається автоматично при створенні екземпляра класу через ",[3753,8435,7639],{},". Він ініціалізує властивості екземпляра. У TypeScript поля класу (",[3753,8438,3888],{},[3753,8440,3901],{},[3753,8442,3910],{},") оголошуються у тілі класу з вказівкою типу, а потім ініціалізуються у конструкторі.",[6447,8445,8446,8449,8531],{},[3846,8447,8448],{},"Якщо поле оголошено у класі, але не ініціалізовано у конструкторі і не має значення за замовчуванням, TypeScript у strict mode видасть помилку:",[3854,8450,8452],{"className":3856,"code":8451,"language":3858,"meta":3859,"style":3859},"class Product {\n  name: string;      \u002F\u002F ❌ Error: Property 'name' has no initializer\n  price: number;\n\n  constructor(price: number) {\n    this.price = price;\n    \u002F\u002F name не ініціалізовано\n  }\n}\n",[3753,8453,8454,8462,8476,8486,8490,8504,8518,8523,8527],{"__ignoreMap":3859},[3863,8455,8456,8458,8460],{"class":3865,"line":3866},[3863,8457,7514],{"class":3869},[3863,8459,4683],{"class":3894},[3863,8461,3928],{"class":3877},[3863,8463,8464,8466,8468,8470,8473],{"class":3865,"line":3921},[3863,8465,4265],{"class":3881},[3863,8467,3891],{"class":3877},[3863,8469,3895],{"class":3894},[3863,8471,8472],{"class":3877},";      ",[3863,8474,8475],{"class":4559},"\u002F\u002F ❌ Error: Property 'name' has no initializer\n",[3863,8477,8478,8480,8482,8484],{"class":3865,"line":3931},[3863,8479,4718],{"class":3881},[3863,8481,3891],{"class":3877},[3863,8483,3915],{"class":3894},[3863,8485,4108],{"class":3877},[3863,8487,8488],{"class":3865,"line":3942},[3863,8489,4002],{"emptyLinePlaceholder":4001},[3863,8491,8492,8494,8496,8498,8500,8502],{"class":3865,"line":3971},[3863,8493,7827],{"class":3869},[3863,8495,3878],{"class":3877},[3863,8497,4824],{"class":3881},[3863,8499,3891],{"class":3877},[3863,8501,3915],{"class":3894},[3863,8503,5195],{"class":3877},[3863,8505,8506,8508,8510,8512,8514,8516],{"class":3865,"line":3986},[3863,8507,7842],{"class":3869},[3863,8509,3783],{"class":3877},[3863,8511,4824],{"class":3881},[3863,8513,4167],{"class":3877},[3863,8515,4824],{"class":3881},[3863,8517,4108],{"class":3877},[3863,8519,8520],{"class":3865,"line":3992},[3863,8521,8522],{"class":4559},"    \u002F\u002F name не ініціалізовано\n",[3863,8524,8525],{"class":3865,"line":3998},[3863,8526,5098],{"class":3877},[3863,8528,8529],{"class":3865,"line":4005},[3863,8530,3995],{"class":3877},[3846,8532,8533,8534,8537,8538,4227,8541,8544],{},"Щоб уникнути помилки, ініціалізуйте поле або позначте його як опціональне (",[3753,8535,8536],{},"name?: string",") або використайте ",[3796,8539,8540],{},"definite assignment assertion",[3753,8542,8543],{},"name!: string","), якщо впевнені, що ініціалізація відбудеться іншим способом.",[4237,8546,8548],{"id":8547},"скорочений-синтаксис-конструктора-parameter-properties","Скорочений синтаксис конструктора (Parameter Properties)",[3846,8550,8551,8552,8555,8556,3776,8558,3776,8560,6018,8562,4671],{},"TypeScript пропонує ",[3796,8553,8554],{},"скорочений синтаксис"," для автоматичного оголошення та ініціалізації полів класу безпосередньо у параметрах конструктора через модифікатори доступу ",[3753,8557,3775],{},[3753,8559,3779],{},[3753,8561,3782],{},[3753,8563,4670],{},[3854,8565,8567],{"className":3856,"code":8566,"language":3858,"meta":3859,"style":3859},"class User {\n  constructor(\n    public name: string,\n    public email: string,\n    public age: number\n  ) {\n    \u002F\u002F Поля name, email, age автоматично оголошені та ініціалізовані\n  }\n\n  greet(): string {\n    return `Привіт, мене звати ${this.name}`;\n  }\n}\n\nconst user = new User('Максим', 'max@example.com', 24);\nconsole.log(user.name);  \u002F\u002F \"Максим\"\n",[3753,8568,8569,8577,8584,8598,8611,8623,8628,8633,8637,8641,8651,8671,8675,8679,8683,8712],{"__ignoreMap":3859},[3863,8570,8571,8573,8575],{"class":3865,"line":3866},[3863,8572,7514],{"class":3869},[3863,8574,4258],{"class":3894},[3863,8576,3928],{"class":3877},[3863,8578,8579,8581],{"class":3865,"line":3921},[3863,8580,7827],{"class":3869},[3863,8582,8583],{"class":3877},"(\n",[3863,8585,8586,8589,8592,8594,8596],{"class":3865,"line":3931},[3863,8587,8588],{"class":3869},"    public",[3863,8590,8591],{"class":3881}," name",[3863,8593,3891],{"class":3877},[3863,8595,3895],{"class":3894},[3863,8597,3939],{"class":3877},[3863,8599,8600,8602,8605,8607,8609],{"class":3865,"line":3942},[3863,8601,8588],{"class":3869},[3863,8603,8604],{"class":3881}," email",[3863,8606,3891],{"class":3877},[3863,8608,3895],{"class":3894},[3863,8610,3939],{"class":3877},[3863,8612,8613,8615,8618,8620],{"class":3865,"line":3971},[3863,8614,8588],{"class":3869},[3863,8616,8617],{"class":3881}," age",[3863,8619,3891],{"class":3877},[3863,8621,8622],{"class":3894},"number\n",[3863,8624,8625],{"class":3865,"line":3986},[3863,8626,8627],{"class":3877},"  ) {\n",[3863,8629,8630],{"class":3865,"line":3992},[3863,8631,8632],{"class":4559},"    \u002F\u002F Поля name, email, age автоматично оголошені та ініціалізовані\n",[3863,8634,8635],{"class":3865,"line":3998},[3863,8636,5098],{"class":3877},[3863,8638,8639],{"class":3865,"line":4005},[3863,8640,4002],{"emptyLinePlaceholder":4001},[3863,8642,8643,8645,8647,8649],{"class":3865,"line":4050},[3863,8644,7879],{"class":3873},[3863,8646,5715],{"class":3877},[3863,8648,3895],{"class":3894},[3863,8650,3928],{"class":3877},[3863,8652,8653,8655,8657,8659,8661,8663,8665,8667,8669],{"class":3865,"line":4111},[3863,8654,6921],{"class":3924},[3863,8656,7605],{"class":4089},[3863,8658,4998],{"class":3869},[3863,8660,6885],{"class":3869},[3863,8662,3783],{"class":6289},[3863,8664,3888],{"class":3881},[3863,8666,5003],{"class":3869},[3863,8668,5006],{"class":4089},[3863,8670,4108],{"class":3877},[3863,8672,8673],{"class":3865,"line":4482},[3863,8674,5098],{"class":3877},[3863,8676,8677],{"class":3865,"line":4487},[3863,8678,3995],{"class":3877},[3863,8680,8681],{"class":3865,"line":4505},[3863,8682,4002],{"emptyLinePlaceholder":4001},[3863,8684,8685,8687,8689,8691,8693,8695,8697,8700,8702,8705,8707,8710],{"class":3865,"line":4517},[3863,8686,4490],{"class":3869},[3863,8688,4055],{"class":4493},[3863,8690,4167],{"class":3877},[3863,8692,7639],{"class":3869},[3863,8694,4258],{"class":3873},[3863,8696,3878],{"class":3877},[3863,8698,8699],{"class":4089},"'Максим'",[3863,8701,3776],{"class":3877},[3863,8703,8704],{"class":4089},"'max@example.com'",[3863,8706,3776],{"class":3877},[3863,8708,8709],{"class":3964},"24",[3863,8711,5009],{"class":3877},[3863,8713,8714,8716,8718,8720,8722,8724,8726,8728,8731],{"class":3865,"line":4528},[3863,8715,5355],{"class":3881},[3863,8717,3783],{"class":3877},[3863,8719,4941],{"class":3873},[3863,8721,3878],{"class":3877},[3863,8723,4015],{"class":3881},[3863,8725,3783],{"class":3877},[3863,8727,3888],{"class":3881},[3863,8729,8730],{"class":3877},");  ",[3863,8732,8733],{"class":4559},"\u002F\u002F \"Максим\"\n",[3846,8735,8736,8737,8739],{},"Цей код еквівалентний попередньому прикладу, але значно коротший. Модифікатор ",[3753,8738,3775],{}," перед параметром конструктора автоматично створює публічне поле класу і присвоює йому значення параметра.",[4845,8741,8742,8750,8838],{},[3846,8743,8744,8745,4227,8747,8749],{},"Скорочений синтаксис особливо корисний для ",[3796,8746,6388],{},[4229,8748,6391],{},") та простих моделей, де клас в основному служить контейнером даних з мінімальною логікою:",[3854,8751,8753],{"className":3856,"code":8752,"language":3858,"meta":3859,"style":3859},"class CreateUserDto {\n  constructor(\n    public readonly email: string,\n    public readonly password: string,\n    public readonly firstName: string,\n    public readonly lastName: string\n  ) {}\n}\n",[3753,8754,8755,8764,8770,8785,8800,8815,8829,8834],{"__ignoreMap":3859},[3863,8756,8757,8759,8762],{"class":3865,"line":3866},[3863,8758,7514],{"class":3869},[3863,8760,8761],{"class":3894}," CreateUserDto",[3863,8763,3928],{"class":3877},[3863,8765,8766,8768],{"class":3865,"line":3921},[3863,8767,7827],{"class":3869},[3863,8769,8583],{"class":3877},[3863,8771,8772,8774,8777,8779,8781,8783],{"class":3865,"line":3931},[3863,8773,8588],{"class":3869},[3863,8775,8776],{"class":3869}," readonly",[3863,8778,8604],{"class":3881},[3863,8780,3891],{"class":3877},[3863,8782,3895],{"class":3894},[3863,8784,3939],{"class":3877},[3863,8786,8787,8789,8791,8794,8796,8798],{"class":3865,"line":3942},[3863,8788,8588],{"class":3869},[3863,8790,8776],{"class":3869},[3863,8792,8793],{"class":3881}," password",[3863,8795,3891],{"class":3877},[3863,8797,3895],{"class":3894},[3863,8799,3939],{"class":3877},[3863,8801,8802,8804,8806,8809,8811,8813],{"class":3865,"line":3971},[3863,8803,8588],{"class":3869},[3863,8805,8776],{"class":3869},[3863,8807,8808],{"class":3881}," firstName",[3863,8810,3891],{"class":3877},[3863,8812,3895],{"class":3894},[3863,8814,3939],{"class":3877},[3863,8816,8817,8819,8821,8824,8826],{"class":3865,"line":3986},[3863,8818,8588],{"class":3869},[3863,8820,8776],{"class":3869},[3863,8822,8823],{"class":3881}," lastName",[3863,8825,3891],{"class":3877},[3863,8827,8828],{"class":3894},"string\n",[3863,8830,8831],{"class":3865,"line":3992},[3863,8832,8833],{"class":3877},"  ) {}\n",[3863,8835,8836],{"class":3865,"line":3998},[3863,8837,3995],{"class":3877},[3846,8839,8840,8841,8843],{},"Всі поля автоматично стають незмінними (",[3753,8842,4670],{},") властивостями екземпляра, що відповідає семантиці \"об'єкт передачі даних, що не має змінюватися після створення\".",[4237,8845,8847],{"id":8846},"методи-класу","Методи класу",[3846,8849,8850,8851,4671],{},"Методи класу — це функції, що визначені всередині тіла класу і мають доступ до полів екземпляра через ",[3753,8852,6885],{},[3854,8854,8856],{"className":3856,"code":8855,"language":3858,"meta":3859,"style":3859},"class Calculator {\n  constructor(private value: number = 0) {}\n\n  add(n: number): Calculator {\n    this.value += n;\n    return this;  \u002F\u002F повернення this для method chaining\n  }\n\n  subtract(n: number): Calculator {\n    this.value -= n;\n    return this;\n  }\n\n  multiply(n: number): Calculator {\n    this.value *= n;\n    return this;\n  }\n\n  getValue(): number {\n    return this.value;\n  }\n}\n\nconst calc = new Calculator(10);\nconst result = calc.add(5).multiply(2).subtract(3).getValue();\nconsole.log(result);  \u002F\u002F (10 + 5) * 2 - 3 = 27\n",[3753,8857,8858,8867,8889,8893,8914,8930,8941,8945,8949,8968,8983,8991,8995,8999,9018,9033,9041,9045,9049,9060,9072,9076,9080,9084,9104,9155],{"__ignoreMap":3859},[3863,8859,8860,8862,8865],{"class":3865,"line":3866},[3863,8861,7514],{"class":3869},[3863,8863,8864],{"class":3894}," Calculator",[3863,8866,3928],{"class":3877},[3863,8868,8869,8871,8873,8875,8878,8880,8882,8884,8886],{"class":3865,"line":3921},[3863,8870,7827],{"class":3869},[3863,8872,3878],{"class":3877},[3863,8874,3779],{"class":3869},[3863,8876,8877],{"class":3881}," value",[3863,8879,3891],{"class":3877},[3863,8881,3915],{"class":3894},[3863,8883,4167],{"class":3877},[3863,8885,4070],{"class":3964},[3863,8887,8888],{"class":3877},") {}\n",[3863,8890,8891],{"class":3865,"line":3931},[3863,8892,4002],{"emptyLinePlaceholder":4001},[3863,8894,8895,8898,8900,8903,8905,8907,8909,8912],{"class":3865,"line":3942},[3863,8896,8897],{"class":3873},"  add",[3863,8899,3878],{"class":3877},[3863,8901,8902],{"class":3881},"n",[3863,8904,3891],{"class":3877},[3863,8906,3915],{"class":3894},[3863,8908,4326],{"class":3877},[3863,8910,8911],{"class":3894},"Calculator",[3863,8913,3928],{"class":3877},[3863,8915,8916,8918,8920,8923,8926,8928],{"class":3865,"line":3971},[3863,8917,7842],{"class":3869},[3863,8919,3783],{"class":3877},[3863,8921,8922],{"class":3881},"value",[3863,8924,8925],{"class":3877}," += ",[3863,8927,8902],{"class":3881},[3863,8929,4108],{"class":3877},[3863,8931,8932,8934,8936,8938],{"class":3865,"line":3986},[3863,8933,6921],{"class":3924},[3863,8935,6937],{"class":3869},[3863,8937,5394],{"class":3877},[3863,8939,8940],{"class":4559},"\u002F\u002F повернення this для method chaining\n",[3863,8942,8943],{"class":3865,"line":3992},[3863,8944,5098],{"class":3877},[3863,8946,8947],{"class":3865,"line":3998},[3863,8948,4002],{"emptyLinePlaceholder":4001},[3863,8950,8951,8954,8956,8958,8960,8962,8964,8966],{"class":3865,"line":4005},[3863,8952,8953],{"class":3873},"  subtract",[3863,8955,3878],{"class":3877},[3863,8957,8902],{"class":3881},[3863,8959,3891],{"class":3877},[3863,8961,3915],{"class":3894},[3863,8963,4326],{"class":3877},[3863,8965,8911],{"class":3894},[3863,8967,3928],{"class":3877},[3863,8969,8970,8972,8974,8976,8979,8981],{"class":3865,"line":4050},[3863,8971,7842],{"class":3869},[3863,8973,3783],{"class":3877},[3863,8975,8922],{"class":3881},[3863,8977,8978],{"class":3877}," -= ",[3863,8980,8902],{"class":3881},[3863,8982,4108],{"class":3877},[3863,8984,8985,8987,8989],{"class":3865,"line":4111},[3863,8986,6921],{"class":3924},[3863,8988,6937],{"class":3869},[3863,8990,4108],{"class":3877},[3863,8992,8993],{"class":3865,"line":4482},[3863,8994,5098],{"class":3877},[3863,8996,8997],{"class":3865,"line":4487},[3863,8998,4002],{"emptyLinePlaceholder":4001},[3863,9000,9001,9004,9006,9008,9010,9012,9014,9016],{"class":3865,"line":4505},[3863,9002,9003],{"class":3873},"  multiply",[3863,9005,3878],{"class":3877},[3863,9007,8902],{"class":3881},[3863,9009,3891],{"class":3877},[3863,9011,3915],{"class":3894},[3863,9013,4326],{"class":3877},[3863,9015,8911],{"class":3894},[3863,9017,3928],{"class":3877},[3863,9019,9020,9022,9024,9026,9029,9031],{"class":3865,"line":4517},[3863,9021,7842],{"class":3869},[3863,9023,3783],{"class":3877},[3863,9025,8922],{"class":3881},[3863,9027,9028],{"class":3877}," *= ",[3863,9030,8902],{"class":3881},[3863,9032,4108],{"class":3877},[3863,9034,9035,9037,9039],{"class":3865,"line":4528},[3863,9036,6921],{"class":3924},[3863,9038,6937],{"class":3869},[3863,9040,4108],{"class":3877},[3863,9042,9043],{"class":3865,"line":4540},[3863,9044,5098],{"class":3877},[3863,9046,9047],{"class":3865,"line":6647},[3863,9048,4002],{"emptyLinePlaceholder":4001},[3863,9050,9051,9054,9056,9058],{"class":3865,"line":6658},[3863,9052,9053],{"class":3873},"  getValue",[3863,9055,5715],{"class":3877},[3863,9057,3915],{"class":3894},[3863,9059,3928],{"class":3877},[3863,9061,9062,9064,9066,9068,9070],{"class":3865,"line":6667},[3863,9063,6921],{"class":3924},[3863,9065,6937],{"class":3869},[3863,9067,3783],{"class":3877},[3863,9069,8922],{"class":3881},[3863,9071,4108],{"class":3877},[3863,9073,9074],{"class":3865,"line":6918},[3863,9075,5098],{"class":3877},[3863,9077,9078],{"class":3865,"line":6957},[3863,9079,3995],{"class":3877},[3863,9081,9082],{"class":3865,"line":6962},[3863,9083,4002],{"emptyLinePlaceholder":4001},[3863,9085,9086,9088,9091,9093,9095,9097,9099,9102],{"class":3865,"line":7489},[3863,9087,4490],{"class":3869},[3863,9089,9090],{"class":4493}," calc",[3863,9092,4167],{"class":3877},[3863,9094,7639],{"class":3869},[3863,9096,8864],{"class":3873},[3863,9098,3878],{"class":3877},[3863,9100,9101],{"class":3964},"10",[3863,9103,5009],{"class":3877},[3863,9105,9106,9108,9111,9113,9116,9118,9121,9123,9126,9129,9132,9134,9137,9139,9142,9144,9147,9149,9152],{"class":3865,"line":7495},[3863,9107,4490],{"class":3869},[3863,9109,9110],{"class":4493}," result",[3863,9112,4167],{"class":3877},[3863,9114,9115],{"class":3881},"calc",[3863,9117,3783],{"class":3877},[3863,9119,9120],{"class":3873},"add",[3863,9122,3878],{"class":3877},[3863,9124,9125],{"class":3964},"5",[3863,9127,9128],{"class":3877},").",[3863,9130,9131],{"class":3873},"multiply",[3863,9133,3878],{"class":3877},[3863,9135,9136],{"class":3964},"2",[3863,9138,9128],{"class":3877},[3863,9140,9141],{"class":3873},"subtract",[3863,9143,3878],{"class":3877},[3863,9145,9146],{"class":3964},"3",[3863,9148,9128],{"class":3877},[3863,9150,9151],{"class":3873},"getValue",[3863,9153,9154],{"class":3877},"();\n",[3863,9156,9157,9159,9161,9163,9165,9168,9170],{"class":3865,"line":7501},[3863,9158,5355],{"class":3881},[3863,9160,3783],{"class":3877},[3863,9162,4941],{"class":3873},[3863,9164,3878],{"class":3877},[3863,9166,9167],{"class":3881},"result",[3863,9169,8730],{"class":3877},[3863,9171,9172],{"class":4559},"\u002F\u002F (10 + 5) * 2 - 3 = 27\n",[3846,9174,9175,9176,9178,9179,4227,9182,9185,9186,4227,9189,9192],{},"Повернення ",[3753,9177,6885],{}," з методів дозволяє створювати ",[3796,9180,9181],{},"fluent interface",[4229,9183,9184],{},"плавний інтерфейс",") або ",[3796,9187,9188],{},"method chaining",[4229,9190,9191],{},"ланцюжок викликів методів","), що робить код виразнішим та компактнішим.",[4145,9194,9195,9196,9199,9200,9202,9203,9205,9206,9209,9210,9212],{},"Методи класу додаються до ",[3796,9197,9198],{},"прототипу"," класу, а не до кожного екземпляра. Це означає, що якщо створити 1000 екземплярів ",[3753,9201,8911],{},", метод ",[3753,9204,9120],{}," існуватиме в пам'яті лише один раз у ",[3753,9207,9208],{},"Calculator.prototype",", а не 1000 копій. Поля класу (",[3753,9211,8922],{},"), навпаки, зберігаються окремо у кожному екземплярі.",[4237,9214,9216],{"id":9215},"статичні-члени-класу","Статичні члени класу",[3846,9218,9219,4227,9222,9225,9226,9229],{},[3796,9220,9221],{},"Статичні члени",[4229,9223,9224],{},"static members",") належать класу як цілому, а не окремим екземплярам. Вони оголошуються через ключове слово ",[3753,9227,9228],{},"static"," і доступні через ім'я класу, а не через екземпляр:",[3854,9231,9233],{"className":3856,"code":9232,"language":3858,"meta":3859,"style":3859},"class MathUtils {\n  static readonly PI = 3.14159;\n\n  static areaOfCircle(radius: number): number {\n    return MathUtils.PI * radius * radius;\n  }\n\n  static max(a: number, b: number): number {\n    return a > b ? a : b;\n  }\n}\n\nconsole.log(MathUtils.PI);                    \u002F\u002F 3.14159\nconsole.log(MathUtils.areaOfCircle(5));       \u002F\u002F 78.53975\nconsole.log(MathUtils.max(10, 20));           \u002F\u002F 20\n\n\u002F\u002F const utils = new MathUtils();             \u002F\u002F ❌ Error: Cannot create an instance\n",[3753,9234,9235,9244,9261,9265,9287,9309,9313,9317,9348,9369,9373,9377,9381,9404,9431,9463,9467],{"__ignoreMap":3859},[3863,9236,9237,9239,9242],{"class":3865,"line":3866},[3863,9238,7514],{"class":3869},[3863,9240,9241],{"class":3894}," MathUtils",[3863,9243,3928],{"class":3877},[3863,9245,9246,9249,9251,9254,9256,9259],{"class":3865,"line":3921},[3863,9247,9248],{"class":3869},"  static",[3863,9250,8776],{"class":3869},[3863,9252,9253],{"class":3881}," PI",[3863,9255,4167],{"class":3877},[3863,9257,9258],{"class":3964},"3.14159",[3863,9260,4108],{"class":3877},[3863,9262,9263],{"class":3865,"line":3931},[3863,9264,4002],{"emptyLinePlaceholder":4001},[3863,9266,9267,9269,9272,9274,9277,9279,9281,9283,9285],{"class":3865,"line":3942},[3863,9268,9248],{"class":3869},[3863,9270,9271],{"class":3873}," areaOfCircle",[3863,9273,3878],{"class":3877},[3863,9275,9276],{"class":3881},"radius",[3863,9278,3891],{"class":3877},[3863,9280,3915],{"class":3894},[3863,9282,4326],{"class":3877},[3863,9284,3915],{"class":3894},[3863,9286,3928],{"class":3877},[3863,9288,9289,9291,9293,9295,9298,9301,9303,9305,9307],{"class":3865,"line":3971},[3863,9290,6921],{"class":3924},[3863,9292,9241],{"class":3881},[3863,9294,3783],{"class":3877},[3863,9296,9297],{"class":4493},"PI",[3863,9299,9300],{"class":3877}," * ",[3863,9302,9276],{"class":3881},[3863,9304,9300],{"class":3877},[3863,9306,9276],{"class":3881},[3863,9308,4108],{"class":3877},[3863,9310,9311],{"class":3865,"line":3986},[3863,9312,5098],{"class":3877},[3863,9314,9315],{"class":3865,"line":3992},[3863,9316,4002],{"emptyLinePlaceholder":4001},[3863,9318,9319,9321,9324,9326,9329,9331,9333,9335,9338,9340,9342,9344,9346],{"class":3865,"line":3998},[3863,9320,9248],{"class":3869},[3863,9322,9323],{"class":3873}," max",[3863,9325,3878],{"class":3877},[3863,9327,9328],{"class":3881},"a",[3863,9330,3891],{"class":3877},[3863,9332,3915],{"class":3894},[3863,9334,3776],{"class":3877},[3863,9336,9337],{"class":3881},"b",[3863,9339,3891],{"class":3877},[3863,9341,3915],{"class":3894},[3863,9343,4326],{"class":3877},[3863,9345,3915],{"class":3894},[3863,9347,3928],{"class":3877},[3863,9349,9350,9352,9355,9357,9359,9361,9363,9365,9367],{"class":3865,"line":4005},[3863,9351,6921],{"class":3924},[3863,9353,9354],{"class":3881}," a",[3863,9356,4067],{"class":3877},[3863,9358,9337],{"class":3881},[3863,9360,5074],{"class":3877},[3863,9362,9328],{"class":3881},[3863,9364,5088],{"class":3877},[3863,9366,9337],{"class":3881},[3863,9368,4108],{"class":3877},[3863,9370,9371],{"class":3865,"line":4050},[3863,9372,5098],{"class":3877},[3863,9374,9375],{"class":3865,"line":4111},[3863,9376,3995],{"class":3877},[3863,9378,9379],{"class":3865,"line":4482},[3863,9380,4002],{"emptyLinePlaceholder":4001},[3863,9382,9383,9385,9387,9389,9391,9394,9396,9398,9401],{"class":3865,"line":4487},[3863,9384,5355],{"class":3881},[3863,9386,3783],{"class":3877},[3863,9388,4941],{"class":3873},[3863,9390,3878],{"class":3877},[3863,9392,9393],{"class":3881},"MathUtils",[3863,9395,3783],{"class":3877},[3863,9397,9297],{"class":4493},[3863,9399,9400],{"class":3877},");                    ",[3863,9402,9403],{"class":4559},"\u002F\u002F 3.14159\n",[3863,9405,9406,9408,9410,9412,9414,9416,9418,9421,9423,9425,9428],{"class":3865,"line":4505},[3863,9407,5355],{"class":3881},[3863,9409,3783],{"class":3877},[3863,9411,4941],{"class":3873},[3863,9413,3878],{"class":3877},[3863,9415,9393],{"class":3881},[3863,9417,3783],{"class":3877},[3863,9419,9420],{"class":3873},"areaOfCircle",[3863,9422,3878],{"class":3877},[3863,9424,9125],{"class":3964},[3863,9426,9427],{"class":3877},"));       ",[3863,9429,9430],{"class":4559},"\u002F\u002F 78.53975\n",[3863,9432,9433,9435,9437,9439,9441,9443,9445,9448,9450,9452,9454,9457,9460],{"class":3865,"line":4517},[3863,9434,5355],{"class":3881},[3863,9436,3783],{"class":3877},[3863,9438,4941],{"class":3873},[3863,9440,3878],{"class":3877},[3863,9442,9393],{"class":3881},[3863,9444,3783],{"class":3877},[3863,9446,9447],{"class":3873},"max",[3863,9449,3878],{"class":3877},[3863,9451,9101],{"class":3964},[3863,9453,3776],{"class":3877},[3863,9455,9456],{"class":3964},"20",[3863,9458,9459],{"class":3877},"));           ",[3863,9461,9462],{"class":4559},"\u002F\u002F 20\n",[3863,9464,9465],{"class":3865,"line":4528},[3863,9466,4002],{"emptyLinePlaceholder":4001},[3863,9468,9469,9472],{"class":3865,"line":4540},[3863,9470,9471],{"class":4559},"\u002F\u002F const utils = new MathUtils();",[3863,9473,9474],{"class":4559},"             \u002F\u002F ❌ Error: Cannot create an instance\n",[3846,9476,9477,9478,9481,9482,4227,9485,9488],{},"Статичні методи часто використовуються для ",[3796,9479,9480],{},"утилітних функцій",", що логічно пов'язані з класом, але не потребують доступу до стану екземпляра, або для ",[3796,9483,9484],{},"фабричних методів",[4229,9486,9487],{},"factory methods","), що створюють екземпляри класу специфічним чином:",[3854,9490,9492],{"className":3856,"code":9491,"language":3858,"meta":3859,"style":3859},"class User {\n  constructor(\n    public id: string,\n    public name: string,\n    public email: string\n  ) {}\n\n  static fromJSON(json: string): User {\n    const data = JSON.parse(json);\n    return new User(data.id, data.name, data.email);\n  }\n\n  static generateId(): string {\n    return Math.random().toString(36).substring(2, 15);\n  }\n}\n\nconst jsonString = '{\"id\":\"user-123\",\"name\":\"Олег\",\"email\":\"oleg@example.com\"}';\nconst user = User.fromJSON(jsonString);\nconsole.log(user.name);  \u002F\u002F \"Олег\"\n\nconst newId = User.generateId();\nconsole.log(newId);  \u002F\u002F наприклад, \"8f3k2m9q1\"\n",[3753,9493,9494,9502,9508,9520,9532,9542,9546,9550,9572,9596,9630,9634,9638,9651,9685,9689,9693,9697,9711,9733,9754,9758,9776],{"__ignoreMap":3859},[3863,9495,9496,9498,9500],{"class":3865,"line":3866},[3863,9497,7514],{"class":3869},[3863,9499,4258],{"class":3894},[3863,9501,3928],{"class":3877},[3863,9503,9504,9506],{"class":3865,"line":3921},[3863,9505,7827],{"class":3869},[3863,9507,8583],{"class":3877},[3863,9509,9510,9512,9514,9516,9518],{"class":3865,"line":3931},[3863,9511,8588],{"class":3869},[3863,9513,4693],{"class":3881},[3863,9515,3891],{"class":3877},[3863,9517,3895],{"class":3894},[3863,9519,3939],{"class":3877},[3863,9521,9522,9524,9526,9528,9530],{"class":3865,"line":3942},[3863,9523,8588],{"class":3869},[3863,9525,8591],{"class":3881},[3863,9527,3891],{"class":3877},[3863,9529,3895],{"class":3894},[3863,9531,3939],{"class":3877},[3863,9533,9534,9536,9538,9540],{"class":3865,"line":3971},[3863,9535,8588],{"class":3869},[3863,9537,8604],{"class":3881},[3863,9539,3891],{"class":3877},[3863,9541,8828],{"class":3894},[3863,9543,9544],{"class":3865,"line":3986},[3863,9545,8833],{"class":3877},[3863,9547,9548],{"class":3865,"line":3992},[3863,9549,4002],{"emptyLinePlaceholder":4001},[3863,9551,9552,9554,9557,9559,9562,9564,9566,9568,9570],{"class":3865,"line":3998},[3863,9553,9248],{"class":3869},[3863,9555,9556],{"class":3873}," fromJSON",[3863,9558,3878],{"class":3877},[3863,9560,9561],{"class":3881},"json",[3863,9563,3891],{"class":3877},[3863,9565,3895],{"class":3894},[3863,9567,4326],{"class":3877},[3863,9569,4303],{"class":3894},[3863,9571,3928],{"class":3877},[3863,9573,9574,9577,9580,9582,9585,9587,9590,9592,9594],{"class":3865,"line":4005},[3863,9575,9576],{"class":3869},"    const",[3863,9578,9579],{"class":4493}," data",[3863,9581,4167],{"class":3877},[3863,9583,9584],{"class":4493},"JSON",[3863,9586,3783],{"class":3877},[3863,9588,9589],{"class":3873},"parse",[3863,9591,3878],{"class":3877},[3863,9593,9561],{"class":3881},[3863,9595,5009],{"class":3877},[3863,9597,9598,9600,9602,9604,9606,9608,9610,9612,9614,9616,9618,9620,9622,9624,9626,9628],{"class":3865,"line":4050},[3863,9599,6921],{"class":3924},[3863,9601,3977],{"class":3869},[3863,9603,4258],{"class":3873},[3863,9605,3878],{"class":3877},[3863,9607,3882],{"class":3881},[3863,9609,3783],{"class":3877},[3863,9611,4334],{"class":3881},[3863,9613,3776],{"class":3877},[3863,9615,3882],{"class":3881},[3863,9617,3783],{"class":3877},[3863,9619,3888],{"class":3881},[3863,9621,3776],{"class":3877},[3863,9623,3882],{"class":3881},[3863,9625,3783],{"class":3877},[3863,9627,3901],{"class":3881},[3863,9629,5009],{"class":3877},[3863,9631,9632],{"class":3865,"line":4111},[3863,9633,5098],{"class":3877},[3863,9635,9636],{"class":3865,"line":4482},[3863,9637,4002],{"emptyLinePlaceholder":4001},[3863,9639,9640,9642,9645,9647,9649],{"class":3865,"line":4487},[3863,9641,9248],{"class":3869},[3863,9643,9644],{"class":3873}," generateId",[3863,9646,5715],{"class":3877},[3863,9648,3895],{"class":3894},[3863,9650,3928],{"class":3877},[3863,9652,9653,9655,9657,9659,9661,9663,9665,9667,9669,9671,9674,9676,9678,9680,9683],{"class":3865,"line":4505},[3863,9654,6921],{"class":3924},[3863,9656,3948],{"class":3881},[3863,9658,3783],{"class":3877},[3863,9660,3953],{"class":3873},[3863,9662,3956],{"class":3877},[3863,9664,3959],{"class":3873},[3863,9666,3878],{"class":3877},[3863,9668,3965],{"class":3964},[3863,9670,9128],{"class":3877},[3863,9672,9673],{"class":3873},"substring",[3863,9675,3878],{"class":3877},[3863,9677,9136],{"class":3964},[3863,9679,3776],{"class":3877},[3863,9681,9682],{"class":3964},"15",[3863,9684,5009],{"class":3877},[3863,9686,9687],{"class":3865,"line":4517},[3863,9688,5098],{"class":3877},[3863,9690,9691],{"class":3865,"line":4528},[3863,9692,3995],{"class":3877},[3863,9694,9695],{"class":3865,"line":4540},[3863,9696,4002],{"emptyLinePlaceholder":4001},[3863,9698,9699,9701,9704,9706,9709],{"class":3865,"line":6647},[3863,9700,4490],{"class":3869},[3863,9702,9703],{"class":4493}," jsonString",[3863,9705,4167],{"class":3877},[3863,9707,9708],{"class":4089},"'{\"id\":\"user-123\",\"name\":\"Олег\",\"email\":\"oleg@example.com\"}'",[3863,9710,4108],{"class":3877},[3863,9712,9713,9715,9717,9719,9721,9723,9726,9728,9731],{"class":3865,"line":6658},[3863,9714,4490],{"class":3869},[3863,9716,4055],{"class":4493},[3863,9718,4167],{"class":3877},[3863,9720,4303],{"class":3881},[3863,9722,3783],{"class":3877},[3863,9724,9725],{"class":3873},"fromJSON",[3863,9727,3878],{"class":3877},[3863,9729,9730],{"class":3881},"jsonString",[3863,9732,5009],{"class":3877},[3863,9734,9735,9737,9739,9741,9743,9745,9747,9749,9751],{"class":3865,"line":6667},[3863,9736,5355],{"class":3881},[3863,9738,3783],{"class":3877},[3863,9740,4941],{"class":3873},[3863,9742,3878],{"class":3877},[3863,9744,4015],{"class":3881},[3863,9746,3783],{"class":3877},[3863,9748,3888],{"class":3881},[3863,9750,8730],{"class":3877},[3863,9752,9753],{"class":4559},"\u002F\u002F \"Олег\"\n",[3863,9755,9756],{"class":3865,"line":6918},[3863,9757,4002],{"emptyLinePlaceholder":4001},[3863,9759,9760,9762,9765,9767,9769,9771,9774],{"class":3865,"line":6957},[3863,9761,4490],{"class":3869},[3863,9763,9764],{"class":4493}," newId",[3863,9766,4167],{"class":3877},[3863,9768,4303],{"class":3881},[3863,9770,3783],{"class":3877},[3863,9772,9773],{"class":3873},"generateId",[3863,9775,9154],{"class":3877},[3863,9777,9778,9780,9782,9784,9786,9789,9791],{"class":3865,"line":6962},[3863,9779,5355],{"class":3881},[3863,9781,3783],{"class":3877},[3863,9783,4941],{"class":3873},[3863,9785,3878],{"class":3877},[3863,9787,9788],{"class":3881},"newId",[3863,9790,8730],{"class":3877},[3863,9792,9793],{"class":4559},"\u002F\u002F наприклад, \"8f3k2m9q1\"\n",[4845,9795,9796,9799],{},[3846,9797,9798],{},"Статичні члени корисні для:",[3746,9800,9801,9813,9824,9835],{},[3749,9802,9803,9806,9807,3776,9810,3783],{},[3796,9804,9805],{},"Констант",", що належать класу: ",[3753,9808,9809],{},"Math.PI",[3753,9811,9812],{},"Number.MAX_VALUE",[3749,9814,9815,3891,9818,3776,9821,3783],{},[3796,9816,9817],{},"Утилітних функцій",[3753,9819,9820],{},"ArrayUtils.chunk()",[3753,9822,9823],{},"StringUtils.capitalize()",[3749,9825,9826,3891,9829,3776,9832,3783],{},[3796,9827,9828],{},"Фабричних методів",[3753,9830,9831],{},"User.fromJSON()",[3753,9833,9834],{},"Date.parse()",[3749,9836,9837,9840],{},[3796,9838,9839],{},"Лічильників або спільного стану",": підрахунок кількості створених екземплярів класу.",[3838,9842],{},[3841,9844,9846],{"id":9845},"модифікатори-доступу-public-private-protected","Модифікатори доступу: public, private, protected",[3846,9848,9849,9850,4227,9853,9856,9857,3776,9859,3756,9861,9863,9864,9867,9868,9871],{},"TypeScript додає до JavaScript механізм ",[3796,9851,9852],{},"контролю доступу",[4229,9854,9855],{},"access control",") через модифікатори ",[3753,9858,3775],{},[3753,9860,3779],{},[3753,9862,3782],{},". Ці модифікатори діють ",[3796,9865,9866],{},"лише на рівні компіляції"," — у скомпільованому JavaScript коді вони зникають, і всі поля залишаються доступними. Проте на етапі розробки вони забезпечують ",[3796,9869,9870],{},"інкапсуляцію"," та захищають внутрішню реалізацію класу від неправильного використання.",[4237,9873,9875],{"id":9874},"public-за-замовчуванням","Public (за замовчуванням)",[3846,9877,9878,9879,4227,9882,9884],{},"Всі члени класу у TypeScript ",[3796,9880,9881],{},"за замовчуванням є публічними",[3753,9883,3775],{},"), тобто доступні з будь-якого місця коду:",[3854,9886,9888],{"className":3856,"code":9887,"language":3858,"meta":3859,"style":3859},"class Counter {\n  public count: number = 0;\n\n  public increment(): void {\n    this.count++;\n  }\n}\n\nconst counter = new Counter();\ncounter.count = 100;        \u002F\u002F ✅ OK: public поле\ncounter.increment();        \u002F\u002F ✅ OK: public метод\nconsole.log(counter.count); \u002F\u002F 101\n",[3753,9889,9890,9898,9916,9920,9933,9943,9947,9951,9955,9970,9989,10003],{"__ignoreMap":3859},[3863,9891,9892,9894,9896],{"class":3865,"line":3866},[3863,9893,7514],{"class":3869},[3863,9895,8003],{"class":3894},[3863,9897,3928],{"class":3877},[3863,9899,9900,9903,9906,9908,9910,9912,9914],{"class":3865,"line":3921},[3863,9901,9902],{"class":3869},"  public",[3863,9904,9905],{"class":3881}," count",[3863,9907,3891],{"class":3877},[3863,9909,3915],{"class":3894},[3863,9911,4167],{"class":3877},[3863,9913,4070],{"class":3964},[3863,9915,4108],{"class":3877},[3863,9917,9918],{"class":3865,"line":3931},[3863,9919,4002],{"emptyLinePlaceholder":4001},[3863,9921,9922,9924,9927,9929,9931],{"class":3865,"line":3942},[3863,9923,9902],{"class":3869},[3863,9925,9926],{"class":3873}," increment",[3863,9928,5715],{"class":3877},[3863,9930,4898],{"class":3894},[3863,9932,3928],{"class":3877},[3863,9934,9935,9937,9939,9941],{"class":3865,"line":3971},[3863,9936,7842],{"class":3869},[3863,9938,3783],{"class":3877},[3863,9940,8036],{"class":3881},[3863,9942,8039],{"class":3877},[3863,9944,9945],{"class":3865,"line":3986},[3863,9946,5098],{"class":3877},[3863,9948,9949],{"class":3865,"line":3992},[3863,9950,3995],{"class":3877},[3863,9952,9953],{"class":3865,"line":3998},[3863,9954,4002],{"emptyLinePlaceholder":4001},[3863,9956,9957,9959,9962,9964,9966,9968],{"class":3865,"line":4005},[3863,9958,4490],{"class":3869},[3863,9960,9961],{"class":4493}," counter",[3863,9963,4167],{"class":3877},[3863,9965,7639],{"class":3869},[3863,9967,8003],{"class":3873},[3863,9969,9154],{"class":3877},[3863,9971,9972,9975,9977,9979,9981,9984,9986],{"class":3865,"line":4050},[3863,9973,9974],{"class":3881},"counter",[3863,9976,3783],{"class":3877},[3863,9978,8036],{"class":3881},[3863,9980,4167],{"class":3877},[3863,9982,9983],{"class":3964},"100",[3863,9985,4700],{"class":3877},[3863,9987,9988],{"class":4559},"\u002F\u002F ✅ OK: public поле\n",[3863,9990,9991,9993,9995,9997,10000],{"class":3865,"line":4111},[3863,9992,9974],{"class":3881},[3863,9994,3783],{"class":3877},[3863,9996,8132],{"class":3873},[3863,9998,9999],{"class":3877},"();        ",[3863,10001,10002],{"class":4559},"\u002F\u002F ✅ OK: public метод\n",[3863,10004,10005,10007,10009,10011,10013,10015,10017,10019,10022],{"class":3865,"line":4482},[3863,10006,5355],{"class":3881},[3863,10008,3783],{"class":3877},[3863,10010,4941],{"class":3873},[3863,10012,3878],{"class":3877},[3863,10014,9974],{"class":3881},[3863,10016,3783],{"class":3877},[3863,10018,8036],{"class":3881},[3863,10020,10021],{"class":3877},"); ",[3863,10023,10024],{"class":4559},"\u002F\u002F 101\n",[3846,10026,10027,10028,10030,10031,10034],{},"Ключове слово ",[3753,10029,3775],{}," можна опустити — результат ідентичний. Його явне використання має сенс для ",[3796,10032,10033],{},"документування інтенцій",": \"це поле\u002Fметод є частиною публічного API класу\".",[4237,10036,10038],{"id":10037},"private-приватні-члени-класу","Private: приватні члени класу",[3846,10040,10041,10042,3776,10044,10047],{},"Члени класу, позначені як ",[3753,10043,3779],{},[3796,10045,10046],{},"доступні лише всередині самого класу",". Спроба звернутися до приватного поля або методу ззовні класу призводить до помилки компіляції:",[3854,10049,10051],{"className":3856,"code":10050,"language":3858,"meta":3859,"style":3859},"class BankAccount {\n  private balance: number = 0;\n\n  constructor(initialBalance: number) {\n    this.balance = initialBalance;\n  }\n\n  deposit(amount: number): void {\n    if (amount > 0) {\n      this.balance += amount;\n    }\n  }\n\n  withdraw(amount: number): boolean {\n    if (amount > 0 && amount \u003C= this.balance) {\n      this.balance -= amount;\n      return true;\n    }\n    return false;\n  }\n\n  getBalance(): number {\n    return this.balance;\n  }\n}\n\nconst account = new BankAccount(1000);\naccount.deposit(500);\nconsole.log(account.getBalance());  \u002F\u002F 1500\n\n\u002F\u002F account.balance = 5000;           \u002F\u002F ❌ Error: Property 'balance' is private\n",[3753,10052,10053,10062,10080,10084,10099,10114,10118,10122,10142,10157,10172,10176,10180,10184,10203,10230,10244,10254,10258,10267,10271,10275,10286,10298,10302,10306,10310,10331,10348,10371,10376],{"__ignoreMap":3859},[3863,10054,10055,10057,10060],{"class":3865,"line":3866},[3863,10056,7514],{"class":3869},[3863,10058,10059],{"class":3894}," BankAccount",[3863,10061,3928],{"class":3877},[3863,10063,10064,10067,10070,10072,10074,10076,10078],{"class":3865,"line":3921},[3863,10065,10066],{"class":3869},"  private",[3863,10068,10069],{"class":3881}," balance",[3863,10071,3891],{"class":3877},[3863,10073,3915],{"class":3894},[3863,10075,4167],{"class":3877},[3863,10077,4070],{"class":3964},[3863,10079,4108],{"class":3877},[3863,10081,10082],{"class":3865,"line":3931},[3863,10083,4002],{"emptyLinePlaceholder":4001},[3863,10085,10086,10088,10090,10093,10095,10097],{"class":3865,"line":3942},[3863,10087,7827],{"class":3869},[3863,10089,3878],{"class":3877},[3863,10091,10092],{"class":3881},"initialBalance",[3863,10094,3891],{"class":3877},[3863,10096,3915],{"class":3894},[3863,10098,5195],{"class":3877},[3863,10100,10101,10103,10105,10108,10110,10112],{"class":3865,"line":3971},[3863,10102,7842],{"class":3869},[3863,10104,3783],{"class":3877},[3863,10106,10107],{"class":3881},"balance",[3863,10109,4167],{"class":3877},[3863,10111,10092],{"class":3881},[3863,10113,4108],{"class":3877},[3863,10115,10116],{"class":3865,"line":3986},[3863,10117,5098],{"class":3877},[3863,10119,10120],{"class":3865,"line":3992},[3863,10121,4002],{"emptyLinePlaceholder":4001},[3863,10123,10124,10127,10129,10132,10134,10136,10138,10140],{"class":3865,"line":3998},[3863,10125,10126],{"class":3873},"  deposit",[3863,10128,3878],{"class":3877},[3863,10130,10131],{"class":3881},"amount",[3863,10133,3891],{"class":3877},[3863,10135,3915],{"class":3894},[3863,10137,4326],{"class":3877},[3863,10139,4898],{"class":3894},[3863,10141,3928],{"class":3877},[3863,10143,10144,10147,10149,10151,10153,10155],{"class":3865,"line":4005},[3863,10145,10146],{"class":3924},"    if",[3863,10148,4227],{"class":3877},[3863,10150,10131],{"class":3881},[3863,10152,4067],{"class":3877},[3863,10154,4070],{"class":3964},[3863,10156,5195],{"class":3877},[3863,10158,10159,10162,10164,10166,10168,10170],{"class":3865,"line":4050},[3863,10160,10161],{"class":3869},"      this",[3863,10163,3783],{"class":3877},[3863,10165,10107],{"class":3881},[3863,10167,8925],{"class":3877},[3863,10169,10131],{"class":3881},[3863,10171,4108],{"class":3877},[3863,10173,10174],{"class":3865,"line":4111},[3863,10175,8118],{"class":3877},[3863,10177,10178],{"class":3865,"line":4482},[3863,10179,5098],{"class":3877},[3863,10181,10182],{"class":3865,"line":4487},[3863,10183,4002],{"emptyLinePlaceholder":4001},[3863,10185,10186,10189,10191,10193,10195,10197,10199,10201],{"class":3865,"line":4505},[3863,10187,10188],{"class":3873},"  withdraw",[3863,10190,3878],{"class":3877},[3863,10192,10131],{"class":3881},[3863,10194,3891],{"class":3877},[3863,10196,3915],{"class":3894},[3863,10198,4326],{"class":3877},[3863,10200,4045],{"class":3894},[3863,10202,3928],{"class":3877},[3863,10204,10205,10207,10209,10211,10213,10215,10217,10219,10222,10224,10226,10228],{"class":3865,"line":4517},[3863,10206,10146],{"class":3924},[3863,10208,4227],{"class":3877},[3863,10210,10131],{"class":3881},[3863,10212,4067],{"class":3877},[3863,10214,4070],{"class":3964},[3863,10216,4073],{"class":3877},[3863,10218,10131],{"class":3881},[3863,10220,10221],{"class":3877}," \u003C= ",[3863,10223,6885],{"class":3869},[3863,10225,3783],{"class":3877},[3863,10227,10107],{"class":3881},[3863,10229,5195],{"class":3877},[3863,10231,10232,10234,10236,10238,10240,10242],{"class":3865,"line":4528},[3863,10233,10161],{"class":3869},[3863,10235,3783],{"class":3877},[3863,10237,10107],{"class":3881},[3863,10239,8978],{"class":3877},[3863,10241,10131],{"class":3881},[3863,10243,4108],{"class":3877},[3863,10245,10246,10249,10252],{"class":3865,"line":4540},[3863,10247,10248],{"class":3924},"      return",[3863,10250,10251],{"class":3869}," true",[3863,10253,4108],{"class":3877},[3863,10255,10256],{"class":3865,"line":6647},[3863,10257,8118],{"class":3877},[3863,10259,10260,10262,10265],{"class":3865,"line":6658},[3863,10261,6921],{"class":3924},[3863,10263,10264],{"class":3869}," false",[3863,10266,4108],{"class":3877},[3863,10268,10269],{"class":3865,"line":6667},[3863,10270,5098],{"class":3877},[3863,10272,10273],{"class":3865,"line":6918},[3863,10274,4002],{"emptyLinePlaceholder":4001},[3863,10276,10277,10280,10282,10284],{"class":3865,"line":6957},[3863,10278,10279],{"class":3873},"  getBalance",[3863,10281,5715],{"class":3877},[3863,10283,3915],{"class":3894},[3863,10285,3928],{"class":3877},[3863,10287,10288,10290,10292,10294,10296],{"class":3865,"line":6962},[3863,10289,6921],{"class":3924},[3863,10291,6937],{"class":3869},[3863,10293,3783],{"class":3877},[3863,10295,10107],{"class":3881},[3863,10297,4108],{"class":3877},[3863,10299,10300],{"class":3865,"line":7489},[3863,10301,5098],{"class":3877},[3863,10303,10304],{"class":3865,"line":7495},[3863,10305,3995],{"class":3877},[3863,10307,10308],{"class":3865,"line":7501},[3863,10309,4002],{"emptyLinePlaceholder":4001},[3863,10311,10313,10315,10318,10320,10322,10324,10326,10329],{"class":3865,"line":10312},27,[3863,10314,4490],{"class":3869},[3863,10316,10317],{"class":4493}," account",[3863,10319,4167],{"class":3877},[3863,10321,7639],{"class":3869},[3863,10323,10059],{"class":3873},[3863,10325,3878],{"class":3877},[3863,10327,10328],{"class":3964},"1000",[3863,10330,5009],{"class":3877},[3863,10332,10334,10337,10339,10342,10344,10346],{"class":3865,"line":10333},28,[3863,10335,10336],{"class":3881},"account",[3863,10338,3783],{"class":3877},[3863,10340,10341],{"class":3873},"deposit",[3863,10343,3878],{"class":3877},[3863,10345,4181],{"class":3964},[3863,10347,5009],{"class":3877},[3863,10349,10351,10353,10355,10357,10359,10361,10363,10366,10368],{"class":3865,"line":10350},29,[3863,10352,5355],{"class":3881},[3863,10354,3783],{"class":3877},[3863,10356,4941],{"class":3873},[3863,10358,3878],{"class":3877},[3863,10360,10336],{"class":3881},[3863,10362,3783],{"class":3877},[3863,10364,10365],{"class":3873},"getBalance",[3863,10367,7334],{"class":3877},[3863,10369,10370],{"class":4559},"\u002F\u002F 1500\n",[3863,10372,10374],{"class":3865,"line":10373},30,[3863,10375,4002],{"emptyLinePlaceholder":4001},[3863,10377,10379,10382],{"class":3865,"line":10378},31,[3863,10380,10381],{"class":4559},"\u002F\u002F account.balance = 5000;",[3863,10383,10384],{"class":4559},"           \u002F\u002F ❌ Error: Property 'balance' is private\n",[3846,10386,10387,10388,10390,10391,3756,10393,10396],{},"Поле ",[3753,10389,10107],{}," приховане від зовнішнього коду: єдиний спосіб змінити баланс — через публічні методи ",[3753,10392,10341],{},[3753,10394,10395],{},"withdraw",", що містять валідаційну логіку. Це запобігає некоректним станам (наприклад, від'ємному балансу або прямому встановленню довільного значення).",[4145,10398,10399,10422,10556],{},[3846,10400,10401,10404,10405,10407,10408,10410,10411,10414,10415,10418,10419,4671],{},[3796,10402,10403],{},"Важливо:"," у скомпільованому JavaScript коді ",[3753,10406,10107],{}," залишиться звичайним полем, доступним ззовні. TypeScript ",[3753,10409,3779],{}," — це лише захист на рівні ",[3796,10412,10413],{},"статичної типізації часу компіляції",", але не runtime захист. Якщо потрібна справжня приватність у JavaScript runtime, використовуйте ",[3796,10416,10417],{},"приватні поля ECMAScript"," через префікс ",[3753,10420,10421],{},"#",[3854,10423,10425],{"className":3856,"code":10424,"language":3858,"meta":3859,"style":3859},"class SecureAccount {\n  #balance: number = 0;  \u002F\u002F справді приватне поле JavaScript\n\n  constructor(initialBalance: number) {\n    this.#balance = initialBalance;\n  }\n\n  getBalance(): number {\n    return this.#balance;\n  }\n}\n\nconst acc = new SecureAccount(1000);\n\u002F\u002F acc.#balance;  \u002F\u002F ❌ Syntax Error у runtime JavaScript\n",[3753,10426,10427,10436,10454,10458,10472,10487,10491,10495,10505,10517,10521,10525,10529,10548],{"__ignoreMap":3859},[3863,10428,10429,10431,10434],{"class":3865,"line":3866},[3863,10430,7514],{"class":3869},[3863,10432,10433],{"class":3894}," SecureAccount",[3863,10435,3928],{"class":3877},[3863,10437,10438,10441,10443,10445,10447,10449,10451],{"class":3865,"line":3921},[3863,10439,10440],{"class":3881},"  #balance",[3863,10442,3891],{"class":3877},[3863,10444,3915],{"class":3894},[3863,10446,4167],{"class":3877},[3863,10448,4070],{"class":3964},[3863,10450,5394],{"class":3877},[3863,10452,10453],{"class":4559},"\u002F\u002F справді приватне поле JavaScript\n",[3863,10455,10456],{"class":3865,"line":3931},[3863,10457,4002],{"emptyLinePlaceholder":4001},[3863,10459,10460,10462,10464,10466,10468,10470],{"class":3865,"line":3942},[3863,10461,7827],{"class":3869},[3863,10463,3878],{"class":3877},[3863,10465,10092],{"class":3881},[3863,10467,3891],{"class":3877},[3863,10469,3915],{"class":3894},[3863,10471,5195],{"class":3877},[3863,10473,10474,10476,10478,10481,10483,10485],{"class":3865,"line":3971},[3863,10475,7842],{"class":3869},[3863,10477,3783],{"class":3877},[3863,10479,10480],{"class":3881},"#balance",[3863,10482,4167],{"class":3877},[3863,10484,10092],{"class":3881},[3863,10486,4108],{"class":3877},[3863,10488,10489],{"class":3865,"line":3986},[3863,10490,5098],{"class":3877},[3863,10492,10493],{"class":3865,"line":3992},[3863,10494,4002],{"emptyLinePlaceholder":4001},[3863,10496,10497,10499,10501,10503],{"class":3865,"line":3998},[3863,10498,10279],{"class":3873},[3863,10500,5715],{"class":3877},[3863,10502,3915],{"class":3894},[3863,10504,3928],{"class":3877},[3863,10506,10507,10509,10511,10513,10515],{"class":3865,"line":4005},[3863,10508,6921],{"class":3924},[3863,10510,6937],{"class":3869},[3863,10512,3783],{"class":3877},[3863,10514,10480],{"class":3881},[3863,10516,4108],{"class":3877},[3863,10518,10519],{"class":3865,"line":4050},[3863,10520,5098],{"class":3877},[3863,10522,10523],{"class":3865,"line":4111},[3863,10524,3995],{"class":3877},[3863,10526,10527],{"class":3865,"line":4482},[3863,10528,4002],{"emptyLinePlaceholder":4001},[3863,10530,10531,10533,10536,10538,10540,10542,10544,10546],{"class":3865,"line":4487},[3863,10532,4490],{"class":3869},[3863,10534,10535],{"class":4493}," acc",[3863,10537,4167],{"class":3877},[3863,10539,7639],{"class":3869},[3863,10541,10433],{"class":3873},[3863,10543,3878],{"class":3877},[3863,10545,10328],{"class":3964},[3863,10547,5009],{"class":3877},[3863,10549,10550,10553],{"class":3865,"line":4505},[3863,10551,10552],{"class":4559},"\u002F\u002F acc.#balance;",[3863,10554,10555],{"class":4559},"  \u002F\u002F ❌ Syntax Error у runtime JavaScript\n",[3846,10557,10558,10559,10561,10562,10564,10565,10567],{},"Поля з ",[3753,10560,10421],{}," є частиною ECMAScript 2022 і забезпечують справжню приватність навіть після компіляції. TypeScript підтримує обидва синтаксиси: ",[3753,10563,3779],{}," для типізації часу компіляції та ",[3753,10566,10421],{}," для runtime приватності.",[4237,10569,10571],{"id":10570},"protected-доступ-у-нащадках","Protected: доступ у нащадках",[3846,10573,10041,10574,10576,10577,10580],{},[3753,10575,3782],{},", доступні ",[3796,10578,10579],{},"всередині самого класу та у класах-нащадках",", але недоступні ззовні:",[3854,10582,10584],{"className":3856,"code":10583,"language":3858,"meta":3859,"style":3859},"class Animal {\n  protected name: string;\n\n  constructor(name: string) {\n    this.name = name;\n  }\n\n  protected makeSound(): void {\n    console.log('Тварина видає звук');\n  }\n}\n\nclass Dog extends Animal {\n  bark(): void {\n    console.log(`${this.name} каже: Гав-гав!`);\n    this.makeSound();  \u002F\u002F ✅ OK: доступ до protected методу батьківського класу\n  }\n}\n\nconst dog = new Dog('Рекс');\ndog.bark();             \u002F\u002F \"Рекс каже: Гав-гав!\" + \"Тварина видає звук\"\n\u002F\u002F dog.name;            \u002F\u002F ❌ Error: Property 'name' is protected\n\u002F\u002F dog.makeSound();     \u002F\u002F ❌ Error: Property 'makeSound' is protected\n",[3753,10585,10586,10594,10607,10611,10625,10639,10643,10647,10660,10675,10679,10683,10687,10699,10709,10736,10751,10755,10759,10763,10782,10798,10806],{"__ignoreMap":3859},[3863,10587,10588,10590,10592],{"class":3865,"line":3866},[3863,10589,7514],{"class":3869},[3863,10591,5652],{"class":3894},[3863,10593,3928],{"class":3877},[3863,10595,10596,10599,10601,10603,10605],{"class":3865,"line":3921},[3863,10597,10598],{"class":3869},"  protected",[3863,10600,8591],{"class":3881},[3863,10602,3891],{"class":3877},[3863,10604,3895],{"class":3894},[3863,10606,4108],{"class":3877},[3863,10608,10609],{"class":3865,"line":3931},[3863,10610,4002],{"emptyLinePlaceholder":4001},[3863,10612,10613,10615,10617,10619,10621,10623],{"class":3865,"line":3942},[3863,10614,7827],{"class":3869},[3863,10616,3878],{"class":3877},[3863,10618,3888],{"class":3881},[3863,10620,3891],{"class":3877},[3863,10622,3895],{"class":3894},[3863,10624,5195],{"class":3877},[3863,10626,10627,10629,10631,10633,10635,10637],{"class":3865,"line":3971},[3863,10628,7842],{"class":3869},[3863,10630,3783],{"class":3877},[3863,10632,3888],{"class":3881},[3863,10634,4167],{"class":3877},[3863,10636,3888],{"class":3881},[3863,10638,4108],{"class":3877},[3863,10640,10641],{"class":3865,"line":3986},[3863,10642,5098],{"class":3877},[3863,10644,10645],{"class":3865,"line":3992},[3863,10646,4002],{"emptyLinePlaceholder":4001},[3863,10648,10649,10651,10654,10656,10658],{"class":3865,"line":3998},[3863,10650,10598],{"class":3869},[3863,10652,10653],{"class":3873}," makeSound",[3863,10655,5715],{"class":3877},[3863,10657,4898],{"class":3894},[3863,10659,3928],{"class":3877},[3863,10661,10662,10664,10666,10668,10670,10673],{"class":3865,"line":4005},[3863,10663,4986],{"class":3881},[3863,10665,3783],{"class":3877},[3863,10667,4941],{"class":3873},[3863,10669,3878],{"class":3877},[3863,10671,10672],{"class":4089},"'Тварина видає звук'",[3863,10674,5009],{"class":3877},[3863,10676,10677],{"class":3865,"line":4050},[3863,10678,5098],{"class":3877},[3863,10680,10681],{"class":3865,"line":4111},[3863,10682,3995],{"class":3877},[3863,10684,10685],{"class":3865,"line":4482},[3863,10686,4002],{"emptyLinePlaceholder":4001},[3863,10688,10689,10691,10693,10695,10697],{"class":3865,"line":4487},[3863,10690,7514],{"class":3869},[3863,10692,5689],{"class":3894},[3863,10694,5692],{"class":3869},[3863,10696,5652],{"class":3894},[3863,10698,3928],{"class":3877},[3863,10700,10701,10703,10705,10707],{"class":3865,"line":4505},[3863,10702,5712],{"class":3873},[3863,10704,5715],{"class":3877},[3863,10706,4898],{"class":3894},[3863,10708,3928],{"class":3877},[3863,10710,10711,10713,10715,10717,10719,10721,10723,10725,10727,10729,10731,10734],{"class":3865,"line":4517},[3863,10712,4986],{"class":3881},[3863,10714,3783],{"class":3877},[3863,10716,4941],{"class":3873},[3863,10718,3878],{"class":3877},[3863,10720,5006],{"class":4089},[3863,10722,4998],{"class":3869},[3863,10724,6885],{"class":3869},[3863,10726,3783],{"class":6289},[3863,10728,3888],{"class":3881},[3863,10730,5003],{"class":3869},[3863,10732,10733],{"class":4089}," каже: Гав-гав!`",[3863,10735,5009],{"class":3877},[3863,10737,10738,10740,10742,10745,10748],{"class":3865,"line":4528},[3863,10739,7842],{"class":3869},[3863,10741,3783],{"class":3877},[3863,10743,10744],{"class":3873},"makeSound",[3863,10746,10747],{"class":3877},"();  ",[3863,10749,10750],{"class":4559},"\u002F\u002F ✅ OK: доступ до protected методу батьківського класу\n",[3863,10752,10753],{"class":3865,"line":4540},[3863,10754,5098],{"class":3877},[3863,10756,10757],{"class":3865,"line":6647},[3863,10758,3995],{"class":3877},[3863,10760,10761],{"class":3865,"line":6658},[3863,10762,4002],{"emptyLinePlaceholder":4001},[3863,10764,10765,10767,10769,10771,10773,10775,10777,10780],{"class":3865,"line":6667},[3863,10766,4490],{"class":3869},[3863,10768,7092],{"class":4493},[3863,10770,4167],{"class":3877},[3863,10772,7639],{"class":3869},[3863,10774,5689],{"class":3873},[3863,10776,3878],{"class":3877},[3863,10778,10779],{"class":4089},"'Рекс'",[3863,10781,5009],{"class":3877},[3863,10783,10784,10787,10789,10792,10795],{"class":3865,"line":6918},[3863,10785,10786],{"class":3881},"dog",[3863,10788,3783],{"class":3877},[3863,10790,10791],{"class":3873},"bark",[3863,10793,10794],{"class":3877},"();             ",[3863,10796,10797],{"class":4559},"\u002F\u002F \"Рекс каже: Гав-гав!\" + \"Тварина видає звук\"\n",[3863,10799,10800,10803],{"class":3865,"line":6957},[3863,10801,10802],{"class":4559},"\u002F\u002F dog.name;",[3863,10804,10805],{"class":4559},"            \u002F\u002F ❌ Error: Property 'name' is protected\n",[3863,10807,10808,10811],{"class":3865,"line":6962},[3863,10809,10810],{"class":4559},"\u002F\u002F dog.makeSound();",[3863,10812,10813],{"class":4559},"     \u002F\u002F ❌ Error: Property 'makeSound' is protected\n",[3846,10815,10816,10817,10819,10820,10823],{},"Модифікатор ",[3753,10818,3782],{}," дозволяє ",[3796,10821,10822],{},"контрольовано розкрити внутрішню реалізацію"," нащадкам, зберігаючи інкапсуляцію від зовнішнього коду. Це корисно у бібліотеках та фреймворках, де базові класи надають \"точки розширення\" для користувацьких класів-нащадків.",[4237,10825,10827],{"id":10826},"readonly-у-класах","Readonly у класах",[3846,10829,10816,10830,10832,10833,10836],{},[3753,10831,4670],{}," робить поле ",[3796,10834,10835],{},"незмінним після ініціалізації",". Його можна встановити лише у конструкторі або при оголошенні:",[3854,10838,10840],{"className":3856,"code":10839,"language":3858,"meta":3859,"style":3859},"class User {\n  readonly id: string;\n  readonly createdAt: Date;\n  name: string;\n\n  constructor(id: string, name: string) {\n    this.id = id;\n    this.createdAt = new Date();\n    this.name = name;\n  }\n\n  rename(newName: string): void {\n    this.name = newName;           \u002F\u002F ✅ OK: name не readonly\n    \u002F\u002F this.id = 'new-id';         \u002F\u002F ❌ Error: Cannot assign to 'id' because it is a read-only property\n  }\n}\n\nconst user = new User('user-123', 'Ірина');\nuser.rename('Ірина Петрівна');    \u002F\u002F ✅ OK\n\u002F\u002F user.id = 'user-456';           \u002F\u002F ❌ Error: Cannot assign to 'id'\n",[3753,10841,10842,10850,10862,10875,10885,10889,10911,10925,10941,10955,10959,10963,10983,11001,11009,11013,11017,11021,11045,11064],{"__ignoreMap":3859},[3863,10843,10844,10846,10848],{"class":3865,"line":3866},[3863,10845,7514],{"class":3869},[3863,10847,4258],{"class":3894},[3863,10849,3928],{"class":3877},[3863,10851,10852,10854,10856,10858,10860],{"class":3865,"line":3921},[3863,10853,4690],{"class":3869},[3863,10855,4693],{"class":3881},[3863,10857,3891],{"class":3877},[3863,10859,3895],{"class":3894},[3863,10861,4108],{"class":3877},[3863,10863,10864,10866,10869,10871,10873],{"class":3865,"line":3931},[3863,10865,4690],{"class":3869},[3863,10867,10868],{"class":3881}," createdAt",[3863,10870,3891],{"class":3877},[3863,10872,4348],{"class":3894},[3863,10874,4108],{"class":3877},[3863,10876,10877,10879,10881,10883],{"class":3865,"line":3942},[3863,10878,4265],{"class":3881},[3863,10880,3891],{"class":3877},[3863,10882,3895],{"class":3894},[3863,10884,4108],{"class":3877},[3863,10886,10887],{"class":3865,"line":3971},[3863,10888,4002],{"emptyLinePlaceholder":4001},[3863,10890,10891,10893,10895,10897,10899,10901,10903,10905,10907,10909],{"class":3865,"line":3986},[3863,10892,7827],{"class":3869},[3863,10894,3878],{"class":3877},[3863,10896,4334],{"class":3881},[3863,10898,3891],{"class":3877},[3863,10900,3895],{"class":3894},[3863,10902,3776],{"class":3877},[3863,10904,3888],{"class":3881},[3863,10906,3891],{"class":3877},[3863,10908,3895],{"class":3894},[3863,10910,5195],{"class":3877},[3863,10912,10913,10915,10917,10919,10921,10923],{"class":3865,"line":3992},[3863,10914,7842],{"class":3869},[3863,10916,3783],{"class":3877},[3863,10918,4334],{"class":3881},[3863,10920,4167],{"class":3877},[3863,10922,4334],{"class":3881},[3863,10924,4108],{"class":3877},[3863,10926,10927,10929,10931,10933,10935,10937,10939],{"class":3865,"line":3998},[3863,10928,7842],{"class":3869},[3863,10930,3783],{"class":3877},[3863,10932,4343],{"class":3881},[3863,10934,4167],{"class":3877},[3863,10936,7639],{"class":3869},[3863,10938,3980],{"class":3873},[3863,10940,9154],{"class":3877},[3863,10942,10943,10945,10947,10949,10951,10953],{"class":3865,"line":4005},[3863,10944,7842],{"class":3869},[3863,10946,3783],{"class":3877},[3863,10948,3888],{"class":3881},[3863,10950,4167],{"class":3877},[3863,10952,3888],{"class":3881},[3863,10954,4108],{"class":3877},[3863,10956,10957],{"class":3865,"line":4050},[3863,10958,5098],{"class":3877},[3863,10960,10961],{"class":3865,"line":4111},[3863,10962,4002],{"emptyLinePlaceholder":4001},[3863,10964,10965,10968,10970,10973,10975,10977,10979,10981],{"class":3865,"line":4482},[3863,10966,10967],{"class":3873},"  rename",[3863,10969,3878],{"class":3877},[3863,10971,10972],{"class":3881},"newName",[3863,10974,3891],{"class":3877},[3863,10976,3895],{"class":3894},[3863,10978,4326],{"class":3877},[3863,10980,4898],{"class":3894},[3863,10982,3928],{"class":3877},[3863,10984,10985,10987,10989,10991,10993,10995,10998],{"class":3865,"line":4487},[3863,10986,7842],{"class":3869},[3863,10988,3783],{"class":3877},[3863,10990,3888],{"class":3881},[3863,10992,4167],{"class":3877},[3863,10994,10972],{"class":3881},[3863,10996,10997],{"class":3877},";           ",[3863,10999,11000],{"class":4559},"\u002F\u002F ✅ OK: name не readonly\n",[3863,11002,11003,11006],{"class":3865,"line":4505},[3863,11004,11005],{"class":4559},"    \u002F\u002F this.id = 'new-id';",[3863,11007,11008],{"class":4559},"         \u002F\u002F ❌ Error: Cannot assign to 'id' because it is a read-only property\n",[3863,11010,11011],{"class":3865,"line":4517},[3863,11012,5098],{"class":3877},[3863,11014,11015],{"class":3865,"line":4528},[3863,11016,3995],{"class":3877},[3863,11018,11019],{"class":3865,"line":4540},[3863,11020,4002],{"emptyLinePlaceholder":4001},[3863,11022,11023,11025,11027,11029,11031,11033,11035,11038,11040,11043],{"class":3865,"line":6647},[3863,11024,4490],{"class":3869},[3863,11026,4055],{"class":4493},[3863,11028,4167],{"class":3877},[3863,11030,7639],{"class":3869},[3863,11032,4258],{"class":3873},[3863,11034,3878],{"class":3877},[3863,11036,11037],{"class":4089},"'user-123'",[3863,11039,3776],{"class":3877},[3863,11041,11042],{"class":4089},"'Ірина'",[3863,11044,5009],{"class":3877},[3863,11046,11047,11049,11051,11054,11056,11059,11062],{"class":3865,"line":6658},[3863,11048,4015],{"class":3881},[3863,11050,3783],{"class":3877},[3863,11052,11053],{"class":3873},"rename",[3863,11055,3878],{"class":3877},[3863,11057,11058],{"class":4089},"'Ірина Петрівна'",[3863,11060,11061],{"class":3877},");    ",[3863,11063,5397],{"class":4559},[3863,11065,11066,11069],{"class":3865,"line":6667},[3863,11067,11068],{"class":4559},"\u002F\u002F user.id = 'user-456';",[3863,11070,11071],{"class":4559},"           \u002F\u002F ❌ Error: Cannot assign to 'id'\n",[3846,11073,11074,11076],{},[3753,11075,4670],{}," можна комбінувати з модифікаторами доступу:",[3854,11078,11080],{"className":3856,"code":11079,"language":3858,"meta":3859,"style":3859},"class Product {\n  constructor(\n    private readonly id: string,\n    public name: string,\n    public price: number\n  ) {}\n\n  getId(): string {\n    return this.id;  \u002F\u002F доступ до приватного readonly поля всередині класу\n  }\n}\n\nconst product = new Product('prod-001', 'Ноутбук', 25000);\nconsole.log(product.getId());  \u002F\u002F \"prod-001\"\n\u002F\u002F product.id;                 \u002F\u002F ❌ Error: Property 'id' is private\n",[3753,11081,11082,11090,11096,11111,11123,11134,11138,11142,11153,11168,11172,11176,11180,11210,11233],{"__ignoreMap":3859},[3863,11083,11084,11086,11088],{"class":3865,"line":3866},[3863,11085,7514],{"class":3869},[3863,11087,4683],{"class":3894},[3863,11089,3928],{"class":3877},[3863,11091,11092,11094],{"class":3865,"line":3921},[3863,11093,7827],{"class":3869},[3863,11095,8583],{"class":3877},[3863,11097,11098,11101,11103,11105,11107,11109],{"class":3865,"line":3931},[3863,11099,11100],{"class":3869},"    private",[3863,11102,8776],{"class":3869},[3863,11104,4693],{"class":3881},[3863,11106,3891],{"class":3877},[3863,11108,3895],{"class":3894},[3863,11110,3939],{"class":3877},[3863,11112,11113,11115,11117,11119,11121],{"class":3865,"line":3942},[3863,11114,8588],{"class":3869},[3863,11116,8591],{"class":3881},[3863,11118,3891],{"class":3877},[3863,11120,3895],{"class":3894},[3863,11122,3939],{"class":3877},[3863,11124,11125,11127,11130,11132],{"class":3865,"line":3971},[3863,11126,8588],{"class":3869},[3863,11128,11129],{"class":3881}," price",[3863,11131,3891],{"class":3877},[3863,11133,8622],{"class":3894},[3863,11135,11136],{"class":3865,"line":3986},[3863,11137,8833],{"class":3877},[3863,11139,11140],{"class":3865,"line":3992},[3863,11141,4002],{"emptyLinePlaceholder":4001},[3863,11143,11144,11147,11149,11151],{"class":3865,"line":3998},[3863,11145,11146],{"class":3873},"  getId",[3863,11148,5715],{"class":3877},[3863,11150,3895],{"class":3894},[3863,11152,3928],{"class":3877},[3863,11154,11155,11157,11159,11161,11163,11165],{"class":3865,"line":4005},[3863,11156,6921],{"class":3924},[3863,11158,6937],{"class":3869},[3863,11160,3783],{"class":3877},[3863,11162,4334],{"class":3881},[3863,11164,5394],{"class":3877},[3863,11166,11167],{"class":4559},"\u002F\u002F доступ до приватного readonly поля всередині класу\n",[3863,11169,11170],{"class":3865,"line":4050},[3863,11171,5098],{"class":3877},[3863,11173,11174],{"class":3865,"line":4111},[3863,11175,3995],{"class":3877},[3863,11177,11178],{"class":3865,"line":4482},[3863,11179,4002],{"emptyLinePlaceholder":4001},[3863,11181,11182,11184,11187,11189,11191,11193,11195,11198,11200,11203,11205,11208],{"class":3865,"line":4487},[3863,11183,4490],{"class":3869},[3863,11185,11186],{"class":4493}," product",[3863,11188,4167],{"class":3877},[3863,11190,7639],{"class":3869},[3863,11192,4683],{"class":3873},[3863,11194,3878],{"class":3877},[3863,11196,11197],{"class":4089},"'prod-001'",[3863,11199,3776],{"class":3877},[3863,11201,11202],{"class":4089},"'Ноутбук'",[3863,11204,3776],{"class":3877},[3863,11206,11207],{"class":3964},"25000",[3863,11209,5009],{"class":3877},[3863,11211,11212,11214,11216,11218,11220,11223,11225,11228,11230],{"class":3865,"line":4505},[3863,11213,5355],{"class":3881},[3863,11215,3783],{"class":3877},[3863,11217,4941],{"class":3873},[3863,11219,3878],{"class":3877},[3863,11221,11222],{"class":3881},"product",[3863,11224,3783],{"class":3877},[3863,11226,11227],{"class":3873},"getId",[3863,11229,7334],{"class":3877},[3863,11231,11232],{"class":4559},"\u002F\u002F \"prod-001\"\n",[3863,11234,11235,11238],{"class":3865,"line":4517},[3863,11236,11237],{"class":4559},"\u002F\u002F product.id;",[3863,11239,11240],{"class":4559},"                 \u002F\u002F ❌ Error: Property 'id' is private\n",[6447,11242,11243,11267],{},[3846,11244,11245,7780,11253,11255,11256,11259,11260,11262,11263,11266],{},[3796,11246,11247,11248,11250,11251,4671],{},"Відмінність ",[3753,11249,4670],{}," від ",[3753,11252,4490],{},[3753,11254,4490],{}," використовується для змінних і запобігає ",[3796,11257,11258],{},"повторному присвоєнню"," самої змінної. ",[3753,11261,4670],{}," застосовується до властивостей класу та запобігає ",[3796,11264,11265],{},"зміні значення властивості"," після ініціалізації. Не плутайте ці концепції:",[3854,11268,11270],{"className":3856,"code":11269,"language":3858,"meta":3859,"style":3859},"const user = new User('user-123', 'Олексій');\nuser = new User('user-456', 'Марія');  \u002F\u002F ❌ Error: Cannot assign to 'user' because it is a constant\n\nuser.name = 'Олексій Іванович';       \u002F\u002F ✅ OK: сам об'єкт мутабельний, змінна const — ні\n",[3753,11271,11272,11295,11320,11324],{"__ignoreMap":3859},[3863,11273,11274,11276,11278,11280,11282,11284,11286,11288,11290,11293],{"class":3865,"line":3866},[3863,11275,4490],{"class":3869},[3863,11277,4055],{"class":4493},[3863,11279,4167],{"class":3877},[3863,11281,7639],{"class":3869},[3863,11283,4258],{"class":3873},[3863,11285,3878],{"class":3877},[3863,11287,11037],{"class":4089},[3863,11289,3776],{"class":3877},[3863,11291,11292],{"class":4089},"'Олексій'",[3863,11294,5009],{"class":3877},[3863,11296,11297,11299,11301,11303,11305,11307,11310,11312,11315,11317],{"class":3865,"line":3921},[3863,11298,4015],{"class":3881},[3863,11300,4167],{"class":3877},[3863,11302,7639],{"class":3869},[3863,11304,4258],{"class":3873},[3863,11306,3878],{"class":3877},[3863,11308,11309],{"class":4089},"'user-456'",[3863,11311,3776],{"class":3877},[3863,11313,11314],{"class":4089},"'Марія'",[3863,11316,8730],{"class":3877},[3863,11318,11319],{"class":4559},"\u002F\u002F ❌ Error: Cannot assign to 'user' because it is a constant\n",[3863,11321,11322],{"class":3865,"line":3931},[3863,11323,4002],{"emptyLinePlaceholder":4001},[3863,11325,11326,11328,11330,11332,11334,11337,11339],{"class":3865,"line":3942},[3863,11327,4015],{"class":3881},[3863,11329,3783],{"class":3877},[3863,11331,3888],{"class":3881},[3863,11333,4167],{"class":3877},[3863,11335,11336],{"class":4089},"'Олексій Іванович'",[3863,11338,4737],{"class":3877},[3863,11340,11341],{"class":4559},"\u002F\u002F ✅ OK: сам об'єкт мутабельний, змінна const — ні\n",[3838,11343],{},[3841,11345,11347],{"id":11346},"наслідування-класів-через-extends","Наслідування класів через extends",[3846,11349,11350,11351,4227,11353,11355,11356,4227,11359,11362],{},"Класи TypeScript підтримують ",[3796,11352,5636],{},[4229,11354,6467],{},"): клас-нащадок успадковує поля та методи батьківського класу і може додавати власні або ",[3796,11357,11358],{},"перевизначати",[4229,11360,11361],{},"override",") успадковані методи.",[4237,11364,11366],{"id":11365},"базове-наслідування","Базове наслідування",[3854,11368,11370],{"className":3856,"code":11369,"language":3858,"meta":3859,"style":3859},"class Animal {\n  constructor(public name: string) {}\n\n  makeSound(): void {\n    console.log('Тварина видає звук');\n  }\n}\n\nclass Cat extends Animal {\n  meow(): void {\n    console.log(`${this.name} каже: Мяу!`);\n  }\n}\n\nconst cat = new Cat('Мурчик');\ncat.makeSound();  \u002F\u002F \"Тварина видає звук\" (успадкований метод)\ncat.meow();       \u002F\u002F \"Мурчик каже: Мяу!\" (власний метод)\n",[3753,11371,11372,11380,11396,11400,11411,11425,11429,11433,11437,11449,11460,11487,11491,11495,11499,11519,11533],{"__ignoreMap":3859},[3863,11373,11374,11376,11378],{"class":3865,"line":3866},[3863,11375,7514],{"class":3869},[3863,11377,5652],{"class":3894},[3863,11379,3928],{"class":3877},[3863,11381,11382,11384,11386,11388,11390,11392,11394],{"class":3865,"line":3921},[3863,11383,7827],{"class":3869},[3863,11385,3878],{"class":3877},[3863,11387,3775],{"class":3869},[3863,11389,8591],{"class":3881},[3863,11391,3891],{"class":3877},[3863,11393,3895],{"class":3894},[3863,11395,8888],{"class":3877},[3863,11397,11398],{"class":3865,"line":3931},[3863,11399,4002],{"emptyLinePlaceholder":4001},[3863,11401,11402,11405,11407,11409],{"class":3865,"line":3942},[3863,11403,11404],{"class":3873},"  makeSound",[3863,11406,5715],{"class":3877},[3863,11408,4898],{"class":3894},[3863,11410,3928],{"class":3877},[3863,11412,11413,11415,11417,11419,11421,11423],{"class":3865,"line":3971},[3863,11414,4986],{"class":3881},[3863,11416,3783],{"class":3877},[3863,11418,4941],{"class":3873},[3863,11420,3878],{"class":3877},[3863,11422,10672],{"class":4089},[3863,11424,5009],{"class":3877},[3863,11426,11427],{"class":3865,"line":3986},[3863,11428,5098],{"class":3877},[3863,11430,11431],{"class":3865,"line":3992},[3863,11432,3995],{"class":3877},[3863,11434,11435],{"class":3865,"line":3998},[3863,11436,4002],{"emptyLinePlaceholder":4001},[3863,11438,11439,11441,11443,11445,11447],{"class":3865,"line":4005},[3863,11440,7514],{"class":3869},[3863,11442,7146],{"class":3894},[3863,11444,5692],{"class":3869},[3863,11446,5652],{"class":3894},[3863,11448,3928],{"class":3877},[3863,11450,11451,11454,11456,11458],{"class":3865,"line":4050},[3863,11452,11453],{"class":3873},"  meow",[3863,11455,5715],{"class":3877},[3863,11457,4898],{"class":3894},[3863,11459,3928],{"class":3877},[3863,11461,11462,11464,11466,11468,11470,11472,11474,11476,11478,11480,11482,11485],{"class":3865,"line":4111},[3863,11463,4986],{"class":3881},[3863,11465,3783],{"class":3877},[3863,11467,4941],{"class":3873},[3863,11469,3878],{"class":3877},[3863,11471,5006],{"class":4089},[3863,11473,4998],{"class":3869},[3863,11475,6885],{"class":3869},[3863,11477,3783],{"class":6289},[3863,11479,3888],{"class":3881},[3863,11481,5003],{"class":3869},[3863,11483,11484],{"class":4089}," каже: Мяу!`",[3863,11486,5009],{"class":3877},[3863,11488,11489],{"class":3865,"line":4482},[3863,11490,5098],{"class":3877},[3863,11492,11493],{"class":3865,"line":4487},[3863,11494,3995],{"class":3877},[3863,11496,11497],{"class":3865,"line":4505},[3863,11498,4002],{"emptyLinePlaceholder":4001},[3863,11500,11501,11503,11506,11508,11510,11512,11514,11517],{"class":3865,"line":4517},[3863,11502,4490],{"class":3869},[3863,11504,11505],{"class":4493}," cat",[3863,11507,4167],{"class":3877},[3863,11509,7639],{"class":3869},[3863,11511,7146],{"class":3873},[3863,11513,3878],{"class":3877},[3863,11515,11516],{"class":4089},"'Мурчик'",[3863,11518,5009],{"class":3877},[3863,11520,11521,11524,11526,11528,11530],{"class":3865,"line":4528},[3863,11522,11523],{"class":3881},"cat",[3863,11525,3783],{"class":3877},[3863,11527,10744],{"class":3873},[3863,11529,10747],{"class":3877},[3863,11531,11532],{"class":4559},"\u002F\u002F \"Тварина видає звук\" (успадкований метод)\n",[3863,11534,11535,11537,11539,11542,11545],{"class":3865,"line":4540},[3863,11536,11523],{"class":3881},[3863,11538,3783],{"class":3877},[3863,11540,11541],{"class":3873},"meow",[3863,11543,11544],{"class":3877},"();       ",[3863,11546,11547],{"class":4559},"\u002F\u002F \"Мурчик каже: Мяу!\" (власний метод)\n",[3846,11549,11550,11551,11553,11554,11556,11557,11250,11559,11561,11562,3783],{},"Клас ",[3753,11552,7200],{}," автоматично отримує поле ",[3753,11555,3888],{}," та метод ",[3753,11558,10744],{},[3753,11560,5852],{}," та додає власний метод ",[3753,11563,11541],{},[4237,11565,11567],{"id":11566},"виклик-конструктора-батьківського-класу-через-super","Виклик конструктора батьківського класу через super()",[3846,11569,11570,11571,7780,11574,11577,11578,4671],{},"Якщо клас-нащадок має власний конструктор, він ",[3796,11572,11573],{},"обов'язково має викликати",[3753,11575,11576],{},"super()"," — конструктор батьківського класу — ",[3796,11579,11580,11581],{},"до звернення до ",[3753,11582,6885],{},[3854,11584,11586],{"className":3856,"code":11585,"language":3858,"meta":3859,"style":3859},"class Vehicle {\n  constructor(public brand: string, public year: number) {}\n}\n\nclass Car extends Vehicle {\n  constructor(brand: string, year: number, public model: string) {\n    super(brand, year);  \u002F\u002F виклик конструктора Vehicle\n    this.model = model;\n  }\n\n  getInfo(): string {\n    return `${this.brand} ${this.model} (${this.year})`;\n  }\n}\n\nconst car = new Car('Toyota', 2022, 'Camry');\nconsole.log(car.getInfo());  \u002F\u002F \"Toyota Camry (2022)\"\n",[3753,11587,11588,11597,11625,11629,11633,11646,11681,11699,11714,11718,11722,11733,11778,11782,11786,11790,11820],{"__ignoreMap":3859},[3863,11589,11590,11592,11595],{"class":3865,"line":3866},[3863,11591,7514],{"class":3869},[3863,11593,11594],{"class":3894}," Vehicle",[3863,11596,3928],{"class":3877},[3863,11598,11599,11601,11603,11605,11608,11610,11612,11614,11616,11619,11621,11623],{"class":3865,"line":3921},[3863,11600,7827],{"class":3869},[3863,11602,3878],{"class":3877},[3863,11604,3775],{"class":3869},[3863,11606,11607],{"class":3881}," brand",[3863,11609,3891],{"class":3877},[3863,11611,3895],{"class":3894},[3863,11613,3776],{"class":3877},[3863,11615,3775],{"class":3869},[3863,11617,11618],{"class":3881}," year",[3863,11620,3891],{"class":3877},[3863,11622,3915],{"class":3894},[3863,11624,8888],{"class":3877},[3863,11626,11627],{"class":3865,"line":3931},[3863,11628,3995],{"class":3877},[3863,11630,11631],{"class":3865,"line":3942},[3863,11632,4002],{"emptyLinePlaceholder":4001},[3863,11634,11635,11637,11640,11642,11644],{"class":3865,"line":3971},[3863,11636,7514],{"class":3869},[3863,11638,11639],{"class":3894}," Car",[3863,11641,5692],{"class":3869},[3863,11643,11594],{"class":3894},[3863,11645,3928],{"class":3877},[3863,11647,11648,11650,11652,11655,11657,11659,11661,11664,11666,11668,11670,11672,11675,11677,11679],{"class":3865,"line":3986},[3863,11649,7827],{"class":3869},[3863,11651,3878],{"class":3877},[3863,11653,11654],{"class":3881},"brand",[3863,11656,3891],{"class":3877},[3863,11658,3895],{"class":3894},[3863,11660,3776],{"class":3877},[3863,11662,11663],{"class":3881},"year",[3863,11665,3891],{"class":3877},[3863,11667,3915],{"class":3894},[3863,11669,3776],{"class":3877},[3863,11671,3775],{"class":3869},[3863,11673,11674],{"class":3881}," model",[3863,11676,3891],{"class":3877},[3863,11678,3895],{"class":3894},[3863,11680,5195],{"class":3877},[3863,11682,11683,11686,11688,11690,11692,11694,11696],{"class":3865,"line":3992},[3863,11684,11685],{"class":3869},"    super",[3863,11687,3878],{"class":3877},[3863,11689,11654],{"class":3881},[3863,11691,3776],{"class":3877},[3863,11693,11663],{"class":3881},[3863,11695,8730],{"class":3877},[3863,11697,11698],{"class":4559},"\u002F\u002F виклик конструктора Vehicle\n",[3863,11700,11701,11703,11705,11708,11710,11712],{"class":3865,"line":3998},[3863,11702,7842],{"class":3869},[3863,11704,3783],{"class":3877},[3863,11706,11707],{"class":3881},"model",[3863,11709,4167],{"class":3877},[3863,11711,11707],{"class":3881},[3863,11713,4108],{"class":3877},[3863,11715,11716],{"class":3865,"line":4005},[3863,11717,5098],{"class":3877},[3863,11719,11720],{"class":3865,"line":4050},[3863,11721,4002],{"emptyLinePlaceholder":4001},[3863,11723,11724,11727,11729,11731],{"class":3865,"line":4111},[3863,11725,11726],{"class":3873},"  getInfo",[3863,11728,5715],{"class":3877},[3863,11730,3895],{"class":3894},[3863,11732,3928],{"class":3877},[3863,11734,11735,11737,11740,11742,11744,11746,11748,11750,11753,11755,11757,11759,11761,11763,11765,11767,11769,11771,11773,11776],{"class":3865,"line":4482},[3863,11736,6921],{"class":3924},[3863,11738,11739],{"class":4089}," `",[3863,11741,4998],{"class":3869},[3863,11743,6885],{"class":3869},[3863,11745,3783],{"class":6289},[3863,11747,11654],{"class":3881},[3863,11749,5003],{"class":3869},[3863,11751,11752],{"class":3869}," ${",[3863,11754,6885],{"class":3869},[3863,11756,3783],{"class":6289},[3863,11758,11707],{"class":3881},[3863,11760,5003],{"class":3869},[3863,11762,4227],{"class":4089},[3863,11764,4998],{"class":3869},[3863,11766,6885],{"class":3869},[3863,11768,3783],{"class":6289},[3863,11770,11663],{"class":3881},[3863,11772,5003],{"class":3869},[3863,11774,11775],{"class":4089},")`",[3863,11777,4108],{"class":3877},[3863,11779,11780],{"class":3865,"line":4487},[3863,11781,5098],{"class":3877},[3863,11783,11784],{"class":3865,"line":4505},[3863,11785,3995],{"class":3877},[3863,11787,11788],{"class":3865,"line":4517},[3863,11789,4002],{"emptyLinePlaceholder":4001},[3863,11791,11792,11794,11797,11799,11801,11803,11805,11808,11810,11813,11815,11818],{"class":3865,"line":4528},[3863,11793,4490],{"class":3869},[3863,11795,11796],{"class":4493}," car",[3863,11798,4167],{"class":3877},[3863,11800,7639],{"class":3869},[3863,11802,11639],{"class":3873},[3863,11804,3878],{"class":3877},[3863,11806,11807],{"class":4089},"'Toyota'",[3863,11809,3776],{"class":3877},[3863,11811,11812],{"class":3964},"2022",[3863,11814,3776],{"class":3877},[3863,11816,11817],{"class":4089},"'Camry'",[3863,11819,5009],{"class":3877},[3863,11821,11822,11824,11826,11828,11830,11833,11835,11838,11840],{"class":3865,"line":4540},[3863,11823,5355],{"class":3881},[3863,11825,3783],{"class":3877},[3863,11827,4941],{"class":3873},[3863,11829,3878],{"class":3877},[3863,11831,11832],{"class":3881},"car",[3863,11834,3783],{"class":3877},[3863,11836,11837],{"class":3873},"getInfo",[3863,11839,7334],{"class":3877},[3863,11841,11842],{"class":4559},"\u002F\u002F \"Toyota Camry (2022)\"\n",[3846,11844,11845,11846,11848],{},"Якщо забути викликати ",[3753,11847,11576],{},", TypeScript видасть помилку:",[3854,11850,11852],{"className":3856,"code":11851,"language":3858,"meta":3859,"style":3859},"class Truck extends Vehicle {\n  constructor(brand: string, year: number, public capacity: number) {\n    \u002F\u002F ❌ Error: A 'super' call must be the first statement in the constructor\n    this.capacity = capacity;\n    super(brand, year);\n  }\n}\n",[3753,11853,11854,11867,11900,11905,11920,11934,11938],{"__ignoreMap":3859},[3863,11855,11856,11858,11861,11863,11865],{"class":3865,"line":3866},[3863,11857,7514],{"class":3869},[3863,11859,11860],{"class":3894}," Truck",[3863,11862,5692],{"class":3869},[3863,11864,11594],{"class":3894},[3863,11866,3928],{"class":3877},[3863,11868,11869,11871,11873,11875,11877,11879,11881,11883,11885,11887,11889,11891,11894,11896,11898],{"class":3865,"line":3921},[3863,11870,7827],{"class":3869},[3863,11872,3878],{"class":3877},[3863,11874,11654],{"class":3881},[3863,11876,3891],{"class":3877},[3863,11878,3895],{"class":3894},[3863,11880,3776],{"class":3877},[3863,11882,11663],{"class":3881},[3863,11884,3891],{"class":3877},[3863,11886,3915],{"class":3894},[3863,11888,3776],{"class":3877},[3863,11890,3775],{"class":3869},[3863,11892,11893],{"class":3881}," capacity",[3863,11895,3891],{"class":3877},[3863,11897,3915],{"class":3894},[3863,11899,5195],{"class":3877},[3863,11901,11902],{"class":3865,"line":3931},[3863,11903,11904],{"class":4559},"    \u002F\u002F ❌ Error: A 'super' call must be the first statement in the constructor\n",[3863,11906,11907,11909,11911,11914,11916,11918],{"class":3865,"line":3942},[3863,11908,7842],{"class":3869},[3863,11910,3783],{"class":3877},[3863,11912,11913],{"class":3881},"capacity",[3863,11915,4167],{"class":3877},[3863,11917,11913],{"class":3881},[3863,11919,4108],{"class":3877},[3863,11921,11922,11924,11926,11928,11930,11932],{"class":3865,"line":3971},[3863,11923,11685],{"class":3869},[3863,11925,3878],{"class":3877},[3863,11927,11654],{"class":3881},[3863,11929,3776],{"class":3877},[3863,11931,11663],{"class":3881},[3863,11933,5009],{"class":3877},[3863,11935,11936],{"class":3865,"line":3986},[3863,11937,5098],{"class":3877},[3863,11939,11940],{"class":3865,"line":3992},[3863,11941,3995],{"class":3877},[4145,11943,11944,11950,11951,11953,11954,11956,11957,11959],{},[3796,11945,11946,11947,11949],{},"Чому ",[3753,11948,11576],{}," обов'язковий?"," У JavaScript конструктор класу-нащадка не створює новий об'єкт самостійно — це робить конструктор батьківського класу. Виклик ",[3753,11952,11576],{}," ініціалізує ",[3753,11955,6885],{}," через батьківський конструктор. Без цього виклику ",[3753,11958,6885],{}," залишається неініціалізованим, і будь-які звернення до нього призведуть до помилки runtime.",[4237,11961,11963],{"id":11962},"перевизначення-методів-method-overriding","Перевизначення методів (Method Overriding)",[3846,11965,11966,11967,4227,11970,11972],{},"Клас-нащадок може ",[3796,11968,11969],{},"перевизначити",[4229,11971,11361],{},") метод батьківського класу, надавши власну реалізацію:",[3854,11974,11976],{"className":3856,"code":11975,"language":3858,"meta":3859,"style":3859},"class Animal {\n  constructor(public name: string) {}\n\n  makeSound(): void {\n    console.log('Тварина видає невизначений звук');\n  }\n}\n\nclass Dog extends Animal {\n  makeSound(): void {\n    console.log(`${this.name} гавкає: Гав-гав!`);\n  }\n}\n\nclass Cat extends Animal {\n  makeSound(): void {\n    console.log(`${this.name} нявкає: Мяу!`);\n  }\n}\n\nconst animals: Animal[] = [\n  new Dog('Бобік'),\n  new Cat('Мурка'),\n  new Animal('Невідома тварина')\n];\n\nanimals.forEach(animal => animal.makeSound());\n\u002F\u002F \"Бобік гавкає: Гав-гав!\"\n\u002F\u002F \"Мурка нявкає: Мяу!\"\n\u002F\u002F \"Невідома тварина видає невизначений звук\"\n",[3753,11977,11978,11986,12002,12006,12016,12031,12035,12039,12043,12055,12065,12092,12096,12100,12104,12116,12126,12153,12157,12161,12165,12179,12193,12206,12220,12225,12229,12256,12261,12266],{"__ignoreMap":3859},[3863,11979,11980,11982,11984],{"class":3865,"line":3866},[3863,11981,7514],{"class":3869},[3863,11983,5652],{"class":3894},[3863,11985,3928],{"class":3877},[3863,11987,11988,11990,11992,11994,11996,11998,12000],{"class":3865,"line":3921},[3863,11989,7827],{"class":3869},[3863,11991,3878],{"class":3877},[3863,11993,3775],{"class":3869},[3863,11995,8591],{"class":3881},[3863,11997,3891],{"class":3877},[3863,11999,3895],{"class":3894},[3863,12001,8888],{"class":3877},[3863,12003,12004],{"class":3865,"line":3931},[3863,12005,4002],{"emptyLinePlaceholder":4001},[3863,12007,12008,12010,12012,12014],{"class":3865,"line":3942},[3863,12009,11404],{"class":3873},[3863,12011,5715],{"class":3877},[3863,12013,4898],{"class":3894},[3863,12015,3928],{"class":3877},[3863,12017,12018,12020,12022,12024,12026,12029],{"class":3865,"line":3971},[3863,12019,4986],{"class":3881},[3863,12021,3783],{"class":3877},[3863,12023,4941],{"class":3873},[3863,12025,3878],{"class":3877},[3863,12027,12028],{"class":4089},"'Тварина видає невизначений звук'",[3863,12030,5009],{"class":3877},[3863,12032,12033],{"class":3865,"line":3986},[3863,12034,5098],{"class":3877},[3863,12036,12037],{"class":3865,"line":3992},[3863,12038,3995],{"class":3877},[3863,12040,12041],{"class":3865,"line":3998},[3863,12042,4002],{"emptyLinePlaceholder":4001},[3863,12044,12045,12047,12049,12051,12053],{"class":3865,"line":4005},[3863,12046,7514],{"class":3869},[3863,12048,5689],{"class":3894},[3863,12050,5692],{"class":3869},[3863,12052,5652],{"class":3894},[3863,12054,3928],{"class":3877},[3863,12056,12057,12059,12061,12063],{"class":3865,"line":4050},[3863,12058,11404],{"class":3873},[3863,12060,5715],{"class":3877},[3863,12062,4898],{"class":3894},[3863,12064,3928],{"class":3877},[3863,12066,12067,12069,12071,12073,12075,12077,12079,12081,12083,12085,12087,12090],{"class":3865,"line":4111},[3863,12068,4986],{"class":3881},[3863,12070,3783],{"class":3877},[3863,12072,4941],{"class":3873},[3863,12074,3878],{"class":3877},[3863,12076,5006],{"class":4089},[3863,12078,4998],{"class":3869},[3863,12080,6885],{"class":3869},[3863,12082,3783],{"class":6289},[3863,12084,3888],{"class":3881},[3863,12086,5003],{"class":3869},[3863,12088,12089],{"class":4089}," гавкає: Гав-гав!`",[3863,12091,5009],{"class":3877},[3863,12093,12094],{"class":3865,"line":4482},[3863,12095,5098],{"class":3877},[3863,12097,12098],{"class":3865,"line":4487},[3863,12099,3995],{"class":3877},[3863,12101,12102],{"class":3865,"line":4505},[3863,12103,4002],{"emptyLinePlaceholder":4001},[3863,12105,12106,12108,12110,12112,12114],{"class":3865,"line":4517},[3863,12107,7514],{"class":3869},[3863,12109,7146],{"class":3894},[3863,12111,5692],{"class":3869},[3863,12113,5652],{"class":3894},[3863,12115,3928],{"class":3877},[3863,12117,12118,12120,12122,12124],{"class":3865,"line":4528},[3863,12119,11404],{"class":3873},[3863,12121,5715],{"class":3877},[3863,12123,4898],{"class":3894},[3863,12125,3928],{"class":3877},[3863,12127,12128,12130,12132,12134,12136,12138,12140,12142,12144,12146,12148,12151],{"class":3865,"line":4540},[3863,12129,4986],{"class":3881},[3863,12131,3783],{"class":3877},[3863,12133,4941],{"class":3873},[3863,12135,3878],{"class":3877},[3863,12137,5006],{"class":4089},[3863,12139,4998],{"class":3869},[3863,12141,6885],{"class":3869},[3863,12143,3783],{"class":6289},[3863,12145,3888],{"class":3881},[3863,12147,5003],{"class":3869},[3863,12149,12150],{"class":4089}," нявкає: Мяу!`",[3863,12152,5009],{"class":3877},[3863,12154,12155],{"class":3865,"line":6647},[3863,12156,5098],{"class":3877},[3863,12158,12159],{"class":3865,"line":6658},[3863,12160,3995],{"class":3877},[3863,12162,12163],{"class":3865,"line":6667},[3863,12164,4002],{"emptyLinePlaceholder":4001},[3863,12166,12167,12169,12172,12174,12176],{"class":3865,"line":6918},[3863,12168,4490],{"class":3869},[3863,12170,12171],{"class":4493}," animals",[3863,12173,3891],{"class":3877},[3863,12175,5852],{"class":3894},[3863,12177,12178],{"class":3877},"[] = [\n",[3863,12180,12181,12184,12186,12188,12191],{"class":3865,"line":6957},[3863,12182,12183],{"class":3869},"  new",[3863,12185,5689],{"class":3873},[3863,12187,3878],{"class":3877},[3863,12189,12190],{"class":4089},"'Бобік'",[3863,12192,3968],{"class":3877},[3863,12194,12195,12197,12199,12201,12204],{"class":3865,"line":6962},[3863,12196,12183],{"class":3869},[3863,12198,7146],{"class":3873},[3863,12200,3878],{"class":3877},[3863,12202,12203],{"class":4089},"'Мурка'",[3863,12205,3968],{"class":3877},[3863,12207,12208,12210,12212,12214,12217],{"class":3865,"line":7489},[3863,12209,12183],{"class":3869},[3863,12211,5652],{"class":3873},[3863,12213,3878],{"class":3877},[3863,12215,12216],{"class":4089},"'Невідома тварина'",[3863,12218,12219],{"class":3877},")\n",[3863,12221,12222],{"class":3865,"line":7495},[3863,12223,12224],{"class":3877},"];\n",[3863,12226,12227],{"class":3865,"line":7501},[3863,12228,4002],{"emptyLinePlaceholder":4001},[3863,12230,12231,12234,12236,12239,12241,12244,12247,12250,12252,12254],{"class":3865,"line":10312},[3863,12232,12233],{"class":3881},"animals",[3863,12235,3783],{"class":3877},[3863,12237,12238],{"class":3873},"forEach",[3863,12240,3878],{"class":3877},[3863,12242,12243],{"class":3881},"animal",[3863,12245,12246],{"class":3869}," =>",[3863,12248,12249],{"class":3881}," animal",[3863,12251,3783],{"class":3877},[3863,12253,10744],{"class":3873},[3863,12255,7956],{"class":3877},[3863,12257,12258],{"class":3865,"line":10333},[3863,12259,12260],{"class":4559},"\u002F\u002F \"Бобік гавкає: Гав-гав!\"\n",[3863,12262,12263],{"class":3865,"line":10350},[3863,12264,12265],{"class":4559},"\u002F\u002F \"Мурка нявкає: Мяу!\"\n",[3863,12267,12268],{"class":3865,"line":10373},[3863,12269,12270],{"class":4559},"\u002F\u002F \"Невідома тварина видає невизначений звук\"\n",[3846,12272,12273,12274,4227,12277,12280,12281,12284,12285,3776,12287,3776,12289,12291,12292,12295],{},"Це демонструє ",[3796,12275,12276],{},"поліморфізм",[4229,12278,12279],{},"polymorphism","): масив типу ",[3753,12282,12283],{},"Animal[]"," містить екземпляри різних класів (",[3753,12286,5739],{},[3753,12288,7200],{},[3753,12290,5852],{},"), і виклик ",[3753,12293,12294],{},"makeSound()"," на кожному елементі виконує відповідну реалізацію залежно від фактичного типу об'єкта у runtime.",[4237,12297,12299],{"id":12298},"виклик-методу-батьківського-класу-через-super","Виклик методу батьківського класу через super",[3846,12301,12302,12303,12306,12307,4671],{},"Всередині перевизначеного методу можна викликати ",[3796,12304,12305],{},"оригінальну реалізацію"," батьківського методу через ",[3753,12308,12309],{},"super.methodName()",[3854,12311,12313],{"className":3856,"code":12312,"language":3858,"meta":3859,"style":3859},"class Logger {\n  log(message: string): void {\n    console.log(`[LOG] ${message}`);\n  }\n}\n\nclass TimestampedLogger extends Logger {\n  log(message: string): void {\n    const timestamp = new Date().toISOString();\n    super.log(`${timestamp} - ${message}`);  \u002F\u002F виклик батьківського log()\n  }\n}\n\nconst logger = new TimestampedLogger();\nlogger.log('Сервер запущено');\n\u002F\u002F \"[LOG] 2026-08-30T12:34:56.789Z - Сервер запущено\"\n",[3753,12314,12315,12323,12341,12363,12367,12371,12375,12388,12406,12426,12461,12465,12469,12473,12488,12503],{"__ignoreMap":3859},[3863,12316,12317,12319,12321],{"class":3865,"line":3866},[3863,12318,7514],{"class":3869},[3863,12320,4877],{"class":3894},[3863,12322,3928],{"class":3877},[3863,12324,12325,12327,12329,12331,12333,12335,12337,12339],{"class":3865,"line":3921},[3863,12326,4884],{"class":3873},[3863,12328,3878],{"class":3877},[3863,12330,4889],{"class":3881},[3863,12332,3891],{"class":3877},[3863,12334,3895],{"class":3894},[3863,12336,4326],{"class":3877},[3863,12338,4898],{"class":3894},[3863,12340,3928],{"class":3877},[3863,12342,12343,12345,12347,12349,12351,12353,12355,12357,12359,12361],{"class":3865,"line":3931},[3863,12344,4986],{"class":3881},[3863,12346,3783],{"class":3877},[3863,12348,4941],{"class":3873},[3863,12350,3878],{"class":3877},[3863,12352,4995],{"class":4089},[3863,12354,4998],{"class":3869},[3863,12356,4889],{"class":3881},[3863,12358,5003],{"class":3869},[3863,12360,5006],{"class":4089},[3863,12362,5009],{"class":3877},[3863,12364,12365],{"class":3865,"line":3942},[3863,12366,5098],{"class":3877},[3863,12368,12369],{"class":3865,"line":3971},[3863,12370,3995],{"class":3877},[3863,12372,12373],{"class":3865,"line":3986},[3863,12374,4002],{"emptyLinePlaceholder":4001},[3863,12376,12377,12379,12382,12384,12386],{"class":3865,"line":3992},[3863,12378,7514],{"class":3869},[3863,12380,12381],{"class":3894}," TimestampedLogger",[3863,12383,5692],{"class":3869},[3863,12385,4877],{"class":3894},[3863,12387,3928],{"class":3877},[3863,12389,12390,12392,12394,12396,12398,12400,12402,12404],{"class":3865,"line":3998},[3863,12391,4884],{"class":3873},[3863,12393,3878],{"class":3877},[3863,12395,4889],{"class":3881},[3863,12397,3891],{"class":3877},[3863,12399,3895],{"class":3894},[3863,12401,4326],{"class":3877},[3863,12403,4898],{"class":3894},[3863,12405,3928],{"class":3877},[3863,12407,12408,12410,12413,12415,12417,12419,12421,12424],{"class":3865,"line":4005},[3863,12409,9576],{"class":3869},[3863,12411,12412],{"class":4493}," timestamp",[3863,12414,4167],{"class":3877},[3863,12416,7639],{"class":3869},[3863,12418,3980],{"class":3873},[3863,12420,3956],{"class":3877},[3863,12422,12423],{"class":3873},"toISOString",[3863,12425,9154],{"class":3877},[3863,12427,12428,12430,12432,12434,12436,12438,12440,12443,12445,12448,12450,12452,12454,12456,12458],{"class":3865,"line":4050},[3863,12429,11685],{"class":3869},[3863,12431,3783],{"class":3877},[3863,12433,4941],{"class":3873},[3863,12435,3878],{"class":3877},[3863,12437,5006],{"class":4089},[3863,12439,4998],{"class":3869},[3863,12441,12442],{"class":3881},"timestamp",[3863,12444,5003],{"class":3869},[3863,12446,12447],{"class":4089}," - ",[3863,12449,4998],{"class":3869},[3863,12451,4889],{"class":3881},[3863,12453,5003],{"class":3869},[3863,12455,5006],{"class":4089},[3863,12457,8730],{"class":3877},[3863,12459,12460],{"class":4559},"\u002F\u002F виклик батьківського log()\n",[3863,12462,12463],{"class":3865,"line":4111},[3863,12464,5098],{"class":3877},[3863,12466,12467],{"class":3865,"line":4482},[3863,12468,3995],{"class":3877},[3863,12470,12471],{"class":3865,"line":4487},[3863,12472,4002],{"emptyLinePlaceholder":4001},[3863,12474,12475,12477,12480,12482,12484,12486],{"class":3865,"line":4505},[3863,12476,4490],{"class":3869},[3863,12478,12479],{"class":4493}," logger",[3863,12481,4167],{"class":3877},[3863,12483,7639],{"class":3869},[3863,12485,12381],{"class":3873},[3863,12487,9154],{"class":3877},[3863,12489,12490,12492,12494,12496,12498,12501],{"class":3865,"line":4517},[3863,12491,5188],{"class":3881},[3863,12493,3783],{"class":3877},[3863,12495,4941],{"class":3873},[3863,12497,3878],{"class":3877},[3863,12499,12500],{"class":4089},"'Сервер запущено'",[3863,12502,5009],{"class":3877},[3863,12504,12505],{"class":3865,"line":4528},[3863,12506,12507],{"class":4559},"\u002F\u002F \"[LOG] 2026-08-30T12:34:56.789Z - Сервер запущено\"\n",[3846,12509,12510,12511,12514],{},"Виклик ",[3753,12512,12513],{},"super.log()"," делегує виконання базовій реалізації, дозволяючи уникнути дублювання логіки та розширити поведінку, а не повністю замінити її.",[4845,12516,12517,12525],{},[3846,12518,12519],{},[3796,12520,6349,12521,12524],{},[3753,12522,12523],{},"super"," у методах:",[3746,12526,12527,12533,12536],{},[3749,12528,12529,12530,12532],{},"Коли потрібно ",[3796,12531,6992],{}," поведінку батьківського методу, а не замінити його повністю.",[3749,12534,12535],{},"Коли базовий клас виконує важливі операції (валідацію, логування, оновлення внутрішнього стану), які не варто дублювати у нащадку.",[3749,12537,12538,12539,12542],{},"Коли ви хочете зберегти ",[3796,12540,12541],{},"узгодженість поведінки"," між базовим класом та нащадками.",[3838,12544],{},[3841,12546,12548],{"id":12547},"реалізація-інтерфейсів-через-implements","Реалізація інтерфейсів через implements",[3846,12550,12551,12552,4227,12555,12558,12559,12562],{},"Класи TypeScript можуть ",[3796,12553,12554],{},"реалізовувати",[4229,12556,12557],{},"implement",") один або кілька інтерфейсів, оголошуючи, що вони задовольняють контракт цих інтерфейсів. Ключове слово ",[3753,12560,12561],{},"implements"," використовується для цього:",[3854,12564,12566],{"className":3856,"code":12565,"language":3858,"meta":3859,"style":3859},"interface Loggable {\n  log(message: string): void;\n}\n\ninterface Serializable {\n  toJSON(): string;\n}\n\nclass User implements Loggable, Serializable {\n  constructor(\n    public id: string,\n    public name: string,\n    public email: string\n  ) {}\n\n  log(message: string): void {\n    console.log(`[User ${this.id}] ${message}`);\n  }\n\n  toJSON(): string {\n    return JSON.stringify({\n      id: this.id,\n      name: this.name,\n      email: this.email\n    });\n  }\n}\n\nconst user = new User('user-001', 'Дмитро', 'dmytro@example.com');\nuser.log('Користувач створений');\nconsole.log(user.toJSON());\n",[3753,12567,12568,12576,12594,12598,12602,12610,12620,12624,12628,12645,12651,12663,12675,12685,12689,12693,12711,12746,12750,12754,12764,12777,12790,12803,12815,12820,12824,12828,12832,12861,12876],{"__ignoreMap":3859},[3863,12569,12570,12572,12574],{"class":3865,"line":3866},[3863,12571,3755],{"class":3869},[3863,12573,6714],{"class":3894},[3863,12575,3928],{"class":3877},[3863,12577,12578,12580,12582,12584,12586,12588,12590,12592],{"class":3865,"line":3921},[3863,12579,4884],{"class":3873},[3863,12581,3878],{"class":3877},[3863,12583,4889],{"class":3881},[3863,12585,3891],{"class":3877},[3863,12587,3895],{"class":3894},[3863,12589,4326],{"class":3877},[3863,12591,4898],{"class":3894},[3863,12593,4108],{"class":3877},[3863,12595,12596],{"class":3865,"line":3931},[3863,12597,3995],{"class":3877},[3863,12599,12600],{"class":3865,"line":3942},[3863,12601,4002],{"emptyLinePlaceholder":4001},[3863,12603,12604,12606,12608],{"class":3865,"line":3971},[3863,12605,3755],{"class":3869},[3863,12607,6749],{"class":3894},[3863,12609,3928],{"class":3877},[3863,12611,12612,12614,12616,12618],{"class":3865,"line":3986},[3863,12613,6756],{"class":3873},[3863,12615,5715],{"class":3877},[3863,12617,3895],{"class":3894},[3863,12619,4108],{"class":3877},[3863,12621,12622],{"class":3865,"line":3992},[3863,12623,3995],{"class":3877},[3863,12625,12626],{"class":3865,"line":3998},[3863,12627,4002],{"emptyLinePlaceholder":4001},[3863,12629,12630,12632,12634,12637,12639,12641,12643],{"class":3865,"line":4005},[3863,12631,7514],{"class":3869},[3863,12633,4258],{"class":3894},[3863,12635,12636],{"class":3869}," implements",[3863,12638,6714],{"class":3894},[3863,12640,3776],{"class":3877},[3863,12642,6786],{"class":3894},[3863,12644,3928],{"class":3877},[3863,12646,12647,12649],{"class":3865,"line":4050},[3863,12648,7827],{"class":3869},[3863,12650,8583],{"class":3877},[3863,12652,12653,12655,12657,12659,12661],{"class":3865,"line":4111},[3863,12654,8588],{"class":3869},[3863,12656,4693],{"class":3881},[3863,12658,3891],{"class":3877},[3863,12660,3895],{"class":3894},[3863,12662,3939],{"class":3877},[3863,12664,12665,12667,12669,12671,12673],{"class":3865,"line":4482},[3863,12666,8588],{"class":3869},[3863,12668,8591],{"class":3881},[3863,12670,3891],{"class":3877},[3863,12672,3895],{"class":3894},[3863,12674,3939],{"class":3877},[3863,12676,12677,12679,12681,12683],{"class":3865,"line":4487},[3863,12678,8588],{"class":3869},[3863,12680,8604],{"class":3881},[3863,12682,3891],{"class":3877},[3863,12684,8828],{"class":3894},[3863,12686,12687],{"class":3865,"line":4505},[3863,12688,8833],{"class":3877},[3863,12690,12691],{"class":3865,"line":4517},[3863,12692,4002],{"emptyLinePlaceholder":4001},[3863,12694,12695,12697,12699,12701,12703,12705,12707,12709],{"class":3865,"line":4528},[3863,12696,4884],{"class":3873},[3863,12698,3878],{"class":3877},[3863,12700,4889],{"class":3881},[3863,12702,3891],{"class":3877},[3863,12704,3895],{"class":3894},[3863,12706,4326],{"class":3877},[3863,12708,4898],{"class":3894},[3863,12710,3928],{"class":3877},[3863,12712,12713,12715,12717,12719,12721,12724,12726,12728,12730,12732,12734,12736,12738,12740,12742,12744],{"class":3865,"line":4540},[3863,12714,4986],{"class":3881},[3863,12716,3783],{"class":3877},[3863,12718,4941],{"class":3873},[3863,12720,3878],{"class":3877},[3863,12722,12723],{"class":4089},"`[User ",[3863,12725,4998],{"class":3869},[3863,12727,6885],{"class":3869},[3863,12729,3783],{"class":6289},[3863,12731,4334],{"class":3881},[3863,12733,5003],{"class":3869},[3863,12735,6894],{"class":4089},[3863,12737,4998],{"class":3869},[3863,12739,4889],{"class":3881},[3863,12741,5003],{"class":3869},[3863,12743,5006],{"class":4089},[3863,12745,5009],{"class":3877},[3863,12747,12748],{"class":3865,"line":6647},[3863,12749,5098],{"class":3877},[3863,12751,12752],{"class":3865,"line":6658},[3863,12753,4002],{"emptyLinePlaceholder":4001},[3863,12755,12756,12758,12760,12762],{"class":3865,"line":6667},[3863,12757,6756],{"class":3873},[3863,12759,5715],{"class":3877},[3863,12761,3895],{"class":3894},[3863,12763,3928],{"class":3877},[3863,12765,12766,12768,12770,12772,12774],{"class":3865,"line":6918},[3863,12767,6921],{"class":3924},[3863,12769,6924],{"class":4493},[3863,12771,3783],{"class":3877},[3863,12773,6929],{"class":3873},[3863,12775,12776],{"class":3877},"({\n",[3863,12778,12779,12782,12784,12786,12788],{"class":3865,"line":6957},[3863,12780,12781],{"class":3881},"      id:",[3863,12783,6937],{"class":3869},[3863,12785,3783],{"class":3877},[3863,12787,4334],{"class":3881},[3863,12789,3939],{"class":3877},[3863,12791,12792,12795,12797,12799,12801],{"class":3865,"line":6962},[3863,12793,12794],{"class":3881},"      name:",[3863,12796,6937],{"class":3869},[3863,12798,3783],{"class":3877},[3863,12800,3888],{"class":3881},[3863,12802,3939],{"class":3877},[3863,12804,12805,12808,12810,12812],{"class":3865,"line":7489},[3863,12806,12807],{"class":3881},"      email:",[3863,12809,6937],{"class":3869},[3863,12811,3783],{"class":3877},[3863,12813,12814],{"class":3881},"email\n",[3863,12816,12817],{"class":3865,"line":7495},[3863,12818,12819],{"class":3877},"    });\n",[3863,12821,12822],{"class":3865,"line":7501},[3863,12823,5098],{"class":3877},[3863,12825,12826],{"class":3865,"line":10312},[3863,12827,3995],{"class":3877},[3863,12829,12830],{"class":3865,"line":10333},[3863,12831,4002],{"emptyLinePlaceholder":4001},[3863,12833,12834,12836,12838,12840,12842,12844,12846,12849,12851,12854,12856,12859],{"class":3865,"line":10350},[3863,12835,4490],{"class":3869},[3863,12837,4055],{"class":4493},[3863,12839,4167],{"class":3877},[3863,12841,7639],{"class":3869},[3863,12843,4258],{"class":3873},[3863,12845,3878],{"class":3877},[3863,12847,12848],{"class":4089},"'user-001'",[3863,12850,3776],{"class":3877},[3863,12852,12853],{"class":4089},"'Дмитро'",[3863,12855,3776],{"class":3877},[3863,12857,12858],{"class":4089},"'dmytro@example.com'",[3863,12860,5009],{"class":3877},[3863,12862,12863,12865,12867,12869,12871,12874],{"class":3865,"line":10373},[3863,12864,4015],{"class":3881},[3863,12866,3783],{"class":3877},[3863,12868,4941],{"class":3873},[3863,12870,3878],{"class":3877},[3863,12872,12873],{"class":4089},"'Користувач створений'",[3863,12875,5009],{"class":3877},[3863,12877,12878,12880,12882,12884,12886,12888,12890,12893],{"class":3865,"line":10378},[3863,12879,5355],{"class":3881},[3863,12881,3783],{"class":3877},[3863,12883,4941],{"class":3873},[3863,12885,3878],{"class":3877},[3863,12887,4015],{"class":3881},[3863,12889,3783],{"class":3877},[3863,12891,12892],{"class":3873},"toJSON",[3863,12894,7956],{"class":3877},[3846,12896,12897,12898,12900,12901,3756,12903,12905],{},"Компілятор TypeScript перевіряє, що клас ",[3753,12899,4303],{}," надає всі методи та властивості, визначені в інтерфейсах ",[3753,12902,6972],{},[3753,12904,6786],{},". Якщо хоча б один метод відсутній або має невірну сигнатуру, виникне помилка компіляції:",[3854,12907,12909],{"className":3856,"code":12908,"language":3858,"meta":3859,"style":3859},"class Product implements Loggable {\n  constructor(public name: string) {}\n\n  \u002F\u002F ❌ Error: Class 'Product' incorrectly implements interface 'Loggable'.\n  \u002F\u002F           Property 'log' is missing in type 'Product' but required in type 'Loggable'.\n}\n",[3753,12910,12911,12923,12939,12943,12948,12953],{"__ignoreMap":3859},[3863,12912,12913,12915,12917,12919,12921],{"class":3865,"line":3866},[3863,12914,7514],{"class":3869},[3863,12916,4683],{"class":3894},[3863,12918,12636],{"class":3869},[3863,12920,6714],{"class":3894},[3863,12922,3928],{"class":3877},[3863,12924,12925,12927,12929,12931,12933,12935,12937],{"class":3865,"line":3921},[3863,12926,7827],{"class":3869},[3863,12928,3878],{"class":3877},[3863,12930,3775],{"class":3869},[3863,12932,8591],{"class":3881},[3863,12934,3891],{"class":3877},[3863,12936,3895],{"class":3894},[3863,12938,8888],{"class":3877},[3863,12940,12941],{"class":3865,"line":3931},[3863,12942,4002],{"emptyLinePlaceholder":4001},[3863,12944,12945],{"class":3865,"line":3942},[3863,12946,12947],{"class":4559},"  \u002F\u002F ❌ Error: Class 'Product' incorrectly implements interface 'Loggable'.\n",[3863,12949,12950],{"class":3865,"line":3971},[3863,12951,12952],{"class":4559},"  \u002F\u002F           Property 'log' is missing in type 'Product' but required in type 'Loggable'.\n",[3863,12954,12955],{"class":3865,"line":3986},[3863,12956,3995],{"class":3877},[4237,12958,12960],{"id":12959},"відмінність-між-implements-та-extends","Відмінність між implements та extends",[3746,12962,12963,12977],{},[3749,12964,12965,12969,12970,12973,12974,12976],{},[3796,12966,12967],{},[3753,12968,5640],{}," використовується для ",[3796,12971,12972],{},"наслідування класів",": нащадок успадковує ",[3796,12975,5152],{}," (код) батьківського класу.",[3749,12978,12979,12969,12983,12986,12987,12989],{},[3796,12980,12981],{},[3753,12982,12561],{},[3796,12984,12985],{},"реалізації інтерфейсів",": клас зобов'язується надати ",[3796,12988,5152],{}," контракту інтерфейсу, але не успадковує жодного коду.",[3846,12991,12992,12993,12995,12996,12998],{},"Клас може одночасно успадковувати інший клас (",[3753,12994,5640],{},") та реалізовувати інтерфейси (",[3753,12997,12561],{},"):",[3854,13000,13002],{"className":3856,"code":13001,"language":3858,"meta":3859,"style":3859},"interface Timestamped {\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nclass BaseEntity {\n  constructor(public id: string) {}\n}\n\nclass Article extends BaseEntity implements Timestamped {\n  createdAt: Date;\n  updatedAt: Date;\n\n  constructor(id: string, public title: string, public content: string) {\n    super(id);\n    this.createdAt = new Date();\n    this.updatedAt = new Date();\n  }\n\n  updateContent(newContent: string): void {\n    this.content = newContent;\n    this.updatedAt = new Date();\n  }\n}\n\nconst article = new Article('article-001', 'TypeScript Classes', 'Вступ до класів...');\nconsole.log(article.id);         \u002F\u002F успадковано від BaseEntity\nconsole.log(article.createdAt);  \u002F\u002F реалізовано з Timestamped\n",[3753,13003,13004,13013,13023,13034,13038,13042,13051,13067,13071,13075,13092,13102,13112,13116,13152,13162,13178,13195,13199,13203,13223,13238,13254,13258,13262,13266,13296,13319],{"__ignoreMap":3859},[3863,13005,13006,13008,13011],{"class":3865,"line":3866},[3863,13007,3755],{"class":3869},[3863,13009,13010],{"class":3894}," Timestamped",[3863,13012,3928],{"class":3877},[3863,13014,13015,13017,13019,13021],{"class":3865,"line":3921},[3863,13016,6804],{"class":3881},[3863,13018,3891],{"class":3877},[3863,13020,4348],{"class":3894},[3863,13022,4108],{"class":3877},[3863,13024,13025,13028,13030,13032],{"class":3865,"line":3931},[3863,13026,13027],{"class":3881},"  updatedAt",[3863,13029,3891],{"class":3877},[3863,13031,4348],{"class":3894},[3863,13033,4108],{"class":3877},[3863,13035,13036],{"class":3865,"line":3942},[3863,13037,3995],{"class":3877},[3863,13039,13040],{"class":3865,"line":3971},[3863,13041,4002],{"emptyLinePlaceholder":4001},[3863,13043,13044,13046,13049],{"class":3865,"line":3986},[3863,13045,7514],{"class":3869},[3863,13047,13048],{"class":3894}," BaseEntity",[3863,13050,3928],{"class":3877},[3863,13052,13053,13055,13057,13059,13061,13063,13065],{"class":3865,"line":3992},[3863,13054,7827],{"class":3869},[3863,13056,3878],{"class":3877},[3863,13058,3775],{"class":3869},[3863,13060,4693],{"class":3881},[3863,13062,3891],{"class":3877},[3863,13064,3895],{"class":3894},[3863,13066,8888],{"class":3877},[3863,13068,13069],{"class":3865,"line":3998},[3863,13070,3995],{"class":3877},[3863,13072,13073],{"class":3865,"line":4005},[3863,13074,4002],{"emptyLinePlaceholder":4001},[3863,13076,13077,13079,13082,13084,13086,13088,13090],{"class":3865,"line":4050},[3863,13078,7514],{"class":3869},[3863,13080,13081],{"class":3894}," Article",[3863,13083,5692],{"class":3869},[3863,13085,13048],{"class":3894},[3863,13087,12636],{"class":3869},[3863,13089,13010],{"class":3894},[3863,13091,3928],{"class":3877},[3863,13093,13094,13096,13098,13100],{"class":3865,"line":4111},[3863,13095,6804],{"class":3881},[3863,13097,3891],{"class":3877},[3863,13099,4348],{"class":3894},[3863,13101,4108],{"class":3877},[3863,13103,13104,13106,13108,13110],{"class":3865,"line":4482},[3863,13105,13027],{"class":3881},[3863,13107,3891],{"class":3877},[3863,13109,4348],{"class":3894},[3863,13111,4108],{"class":3877},[3863,13113,13114],{"class":3865,"line":4487},[3863,13115,4002],{"emptyLinePlaceholder":4001},[3863,13117,13118,13120,13122,13124,13126,13128,13130,13132,13135,13137,13139,13141,13143,13146,13148,13150],{"class":3865,"line":4505},[3863,13119,7827],{"class":3869},[3863,13121,3878],{"class":3877},[3863,13123,4334],{"class":3881},[3863,13125,3891],{"class":3877},[3863,13127,3895],{"class":3894},[3863,13129,3776],{"class":3877},[3863,13131,3775],{"class":3869},[3863,13133,13134],{"class":3881}," title",[3863,13136,3891],{"class":3877},[3863,13138,3895],{"class":3894},[3863,13140,3776],{"class":3877},[3863,13142,3775],{"class":3869},[3863,13144,13145],{"class":3881}," content",[3863,13147,3891],{"class":3877},[3863,13149,3895],{"class":3894},[3863,13151,5195],{"class":3877},[3863,13153,13154,13156,13158,13160],{"class":3865,"line":4517},[3863,13155,11685],{"class":3869},[3863,13157,3878],{"class":3877},[3863,13159,4334],{"class":3881},[3863,13161,5009],{"class":3877},[3863,13163,13164,13166,13168,13170,13172,13174,13176],{"class":3865,"line":4528},[3863,13165,7842],{"class":3869},[3863,13167,3783],{"class":3877},[3863,13169,4343],{"class":3881},[3863,13171,4167],{"class":3877},[3863,13173,7639],{"class":3869},[3863,13175,3980],{"class":3873},[3863,13177,9154],{"class":3877},[3863,13179,13180,13182,13184,13187,13189,13191,13193],{"class":3865,"line":4540},[3863,13181,7842],{"class":3869},[3863,13183,3783],{"class":3877},[3863,13185,13186],{"class":3881},"updatedAt",[3863,13188,4167],{"class":3877},[3863,13190,7639],{"class":3869},[3863,13192,3980],{"class":3873},[3863,13194,9154],{"class":3877},[3863,13196,13197],{"class":3865,"line":6647},[3863,13198,5098],{"class":3877},[3863,13200,13201],{"class":3865,"line":6658},[3863,13202,4002],{"emptyLinePlaceholder":4001},[3863,13204,13205,13208,13210,13213,13215,13217,13219,13221],{"class":3865,"line":6667},[3863,13206,13207],{"class":3873},"  updateContent",[3863,13209,3878],{"class":3877},[3863,13211,13212],{"class":3881},"newContent",[3863,13214,3891],{"class":3877},[3863,13216,3895],{"class":3894},[3863,13218,4326],{"class":3877},[3863,13220,4898],{"class":3894},[3863,13222,3928],{"class":3877},[3863,13224,13225,13227,13229,13232,13234,13236],{"class":3865,"line":6918},[3863,13226,7842],{"class":3869},[3863,13228,3783],{"class":3877},[3863,13230,13231],{"class":3881},"content",[3863,13233,4167],{"class":3877},[3863,13235,13212],{"class":3881},[3863,13237,4108],{"class":3877},[3863,13239,13240,13242,13244,13246,13248,13250,13252],{"class":3865,"line":6957},[3863,13241,7842],{"class":3869},[3863,13243,3783],{"class":3877},[3863,13245,13186],{"class":3881},[3863,13247,4167],{"class":3877},[3863,13249,7639],{"class":3869},[3863,13251,3980],{"class":3873},[3863,13253,9154],{"class":3877},[3863,13255,13256],{"class":3865,"line":6962},[3863,13257,5098],{"class":3877},[3863,13259,13260],{"class":3865,"line":7489},[3863,13261,3995],{"class":3877},[3863,13263,13264],{"class":3865,"line":7495},[3863,13265,4002],{"emptyLinePlaceholder":4001},[3863,13267,13268,13270,13273,13275,13277,13279,13281,13284,13286,13289,13291,13294],{"class":3865,"line":7501},[3863,13269,4490],{"class":3869},[3863,13271,13272],{"class":4493}," article",[3863,13274,4167],{"class":3877},[3863,13276,7639],{"class":3869},[3863,13278,13081],{"class":3873},[3863,13280,3878],{"class":3877},[3863,13282,13283],{"class":4089},"'article-001'",[3863,13285,3776],{"class":3877},[3863,13287,13288],{"class":4089},"'TypeScript Classes'",[3863,13290,3776],{"class":3877},[3863,13292,13293],{"class":4089},"'Вступ до класів...'",[3863,13295,5009],{"class":3877},[3863,13297,13298,13300,13302,13304,13306,13309,13311,13313,13316],{"class":3865,"line":10312},[3863,13299,5355],{"class":3881},[3863,13301,3783],{"class":3877},[3863,13303,4941],{"class":3873},[3863,13305,3878],{"class":3877},[3863,13307,13308],{"class":3881},"article",[3863,13310,3783],{"class":3877},[3863,13312,4334],{"class":3881},[3863,13314,13315],{"class":3877},");         ",[3863,13317,13318],{"class":4559},"\u002F\u002F успадковано від BaseEntity\n",[3863,13320,13321,13323,13325,13327,13329,13331,13333,13335,13337],{"class":3865,"line":10333},[3863,13322,5355],{"class":3881},[3863,13324,3783],{"class":3877},[3863,13326,4941],{"class":3873},[3863,13328,3878],{"class":3877},[3863,13330,13308],{"class":3881},[3863,13332,3783],{"class":3877},[3863,13334,4343],{"class":3881},[3863,13336,8730],{"class":3877},[3863,13338,13339],{"class":4559},"\u002F\u002F реалізовано з Timestamped\n",[4145,13341,13342,13356,13623],{},[3846,13343,13344,13348,13349,3756,13352,13355],{},[3796,13345,6349,13346,4664],{},[3753,13347,12561],{}," Реалізація інтерфейсів корисна для ",[3796,13350,13351],{},"dependency injection",[3796,13353,13354],{},"інверсії залежностей",": замість того, щоб код залежав від конкретного класу, він залежить від інтерфейсу, що дозволяє підставляти різні реалізації:",[3854,13357,13359],{"className":3856,"code":13358,"language":3858,"meta":3859,"style":3859},"interface PaymentGateway {\n  processPayment(amount: number): Promise\u003Cboolean>;\n}\n\nclass StripeGateway implements PaymentGateway {\n  async processPayment(amount: number): Promise\u003Cboolean> {\n    \u002F\u002F інтеграція зі Stripe API\n    return true;\n  }\n}\n\nclass PayPalGateway implements PaymentGateway {\n  async processPayment(amount: number): Promise\u003Cboolean> {\n    \u002F\u002F інтеграція з PayPal API\n    return true;\n  }\n}\n\nfunction checkout(gateway: PaymentGateway, amount: number) {\n  return gateway.processPayment(amount);\n}\n\n\u002F\u002F Можна передати будь-яку реалізацію PaymentGateway\ncheckout(new StripeGateway(), 100);\ncheckout(new PayPalGateway(), 200);\n",[3753,13360,13361,13370,13396,13400,13404,13417,13444,13449,13457,13461,13465,13469,13482,13506,13511,13519,13523,13527,13531,13558,13576,13580,13584,13589,13607],{"__ignoreMap":3859},[3863,13362,13363,13365,13368],{"class":3865,"line":3866},[3863,13364,3755],{"class":3869},[3863,13366,13367],{"class":3894}," PaymentGateway",[3863,13369,3928],{"class":3877},[3863,13371,13372,13375,13377,13379,13381,13383,13385,13388,13391,13393],{"class":3865,"line":3921},[3863,13373,13374],{"class":3873},"  processPayment",[3863,13376,3878],{"class":3877},[3863,13378,10131],{"class":3881},[3863,13380,3891],{"class":3877},[3863,13382,3915],{"class":3894},[3863,13384,4326],{"class":3877},[3863,13386,13387],{"class":3894},"Promise",[3863,13389,13390],{"class":3877},"\u003C",[3863,13392,4045],{"class":3894},[3863,13394,13395],{"class":3877},">;\n",[3863,13397,13398],{"class":3865,"line":3931},[3863,13399,3995],{"class":3877},[3863,13401,13402],{"class":3865,"line":3942},[3863,13403,4002],{"emptyLinePlaceholder":4001},[3863,13405,13406,13408,13411,13413,13415],{"class":3865,"line":3971},[3863,13407,7514],{"class":3869},[3863,13409,13410],{"class":3894}," StripeGateway",[3863,13412,12636],{"class":3869},[3863,13414,13367],{"class":3894},[3863,13416,3928],{"class":3877},[3863,13418,13419,13422,13425,13427,13429,13431,13433,13435,13437,13439,13441],{"class":3865,"line":3986},[3863,13420,13421],{"class":3869},"  async",[3863,13423,13424],{"class":3873}," processPayment",[3863,13426,3878],{"class":3877},[3863,13428,10131],{"class":3881},[3863,13430,3891],{"class":3877},[3863,13432,3915],{"class":3894},[3863,13434,4326],{"class":3877},[3863,13436,13387],{"class":3894},[3863,13438,13390],{"class":3877},[3863,13440,4045],{"class":3894},[3863,13442,13443],{"class":3877},"> {\n",[3863,13445,13446],{"class":3865,"line":3992},[3863,13447,13448],{"class":4559},"    \u002F\u002F інтеграція зі Stripe API\n",[3863,13450,13451,13453,13455],{"class":3865,"line":3998},[3863,13452,6921],{"class":3924},[3863,13454,10251],{"class":3869},[3863,13456,4108],{"class":3877},[3863,13458,13459],{"class":3865,"line":4005},[3863,13460,5098],{"class":3877},[3863,13462,13463],{"class":3865,"line":4050},[3863,13464,3995],{"class":3877},[3863,13466,13467],{"class":3865,"line":4111},[3863,13468,4002],{"emptyLinePlaceholder":4001},[3863,13470,13471,13473,13476,13478,13480],{"class":3865,"line":4482},[3863,13472,7514],{"class":3869},[3863,13474,13475],{"class":3894}," PayPalGateway",[3863,13477,12636],{"class":3869},[3863,13479,13367],{"class":3894},[3863,13481,3928],{"class":3877},[3863,13483,13484,13486,13488,13490,13492,13494,13496,13498,13500,13502,13504],{"class":3865,"line":4487},[3863,13485,13421],{"class":3869},[3863,13487,13424],{"class":3873},[3863,13489,3878],{"class":3877},[3863,13491,10131],{"class":3881},[3863,13493,3891],{"class":3877},[3863,13495,3915],{"class":3894},[3863,13497,4326],{"class":3877},[3863,13499,13387],{"class":3894},[3863,13501,13390],{"class":3877},[3863,13503,4045],{"class":3894},[3863,13505,13443],{"class":3877},[3863,13507,13508],{"class":3865,"line":4505},[3863,13509,13510],{"class":4559},"    \u002F\u002F інтеграція з PayPal API\n",[3863,13512,13513,13515,13517],{"class":3865,"line":4517},[3863,13514,6921],{"class":3924},[3863,13516,10251],{"class":3869},[3863,13518,4108],{"class":3877},[3863,13520,13521],{"class":3865,"line":4528},[3863,13522,5098],{"class":3877},[3863,13524,13525],{"class":3865,"line":4540},[3863,13526,3995],{"class":3877},[3863,13528,13529],{"class":3865,"line":6647},[3863,13530,4002],{"emptyLinePlaceholder":4001},[3863,13532,13533,13535,13538,13540,13543,13545,13548,13550,13552,13554,13556],{"class":3865,"line":6658},[3863,13534,3870],{"class":3869},[3863,13536,13537],{"class":3873}," checkout",[3863,13539,3878],{"class":3877},[3863,13541,13542],{"class":3881},"gateway",[3863,13544,3891],{"class":3877},[3863,13546,13547],{"class":3894},"PaymentGateway",[3863,13549,3776],{"class":3877},[3863,13551,10131],{"class":3881},[3863,13553,3891],{"class":3877},[3863,13555,3915],{"class":3894},[3863,13557,5195],{"class":3877},[3863,13559,13560,13562,13565,13567,13570,13572,13574],{"class":3865,"line":6667},[3863,13561,3925],{"class":3924},[3863,13563,13564],{"class":3881}," gateway",[3863,13566,3783],{"class":3877},[3863,13568,13569],{"class":3873},"processPayment",[3863,13571,3878],{"class":3877},[3863,13573,10131],{"class":3881},[3863,13575,5009],{"class":3877},[3863,13577,13578],{"class":3865,"line":6918},[3863,13579,3995],{"class":3877},[3863,13581,13582],{"class":3865,"line":6957},[3863,13583,4002],{"emptyLinePlaceholder":4001},[3863,13585,13586],{"class":3865,"line":6962},[3863,13587,13588],{"class":4559},"\u002F\u002F Можна передати будь-яку реалізацію PaymentGateway\n",[3863,13590,13591,13594,13596,13598,13600,13603,13605],{"class":3865,"line":7489},[3863,13592,13593],{"class":3873},"checkout",[3863,13595,3878],{"class":3877},[3863,13597,7639],{"class":3869},[3863,13599,13410],{"class":3873},[3863,13601,13602],{"class":3877},"(), ",[3863,13604,9983],{"class":3964},[3863,13606,5009],{"class":3877},[3863,13608,13609,13611,13613,13615,13617,13619,13621],{"class":3865,"line":7495},[3863,13610,13593],{"class":3873},[3863,13612,3878],{"class":3877},[3863,13614,7639],{"class":3869},[3863,13616,13475],{"class":3873},[3863,13618,13602],{"class":3877},[3863,13620,4170],{"class":3964},[3863,13622,5009],{"class":3877},[3846,13624,13625,13626,4227,13629,9128],{},"Це робить код ",[3796,13627,13628],{},"гнучким, тестованим та слабко зв'язаним",[4229,13630,13631],{},"loosely coupled",[3838,13633],{},[3841,13635,13637],{"id":13636},"абстрактні-класи-шаблони-для-наслідування","Абстрактні класи: шаблони для наслідування",[3846,13639,13640,4227,13643,13646,13647,13650,13651,13654],{},[3796,13641,13642],{},"Абстрактний клас",[4229,13644,13645],{},"abstract class",") — це клас, що не може бути інстанційований напряму і призначений виключно для наслідування. Він може містити як ",[3796,13648,13649],{},"реалізовані методи"," (зі звичайним кодом), так і ",[3796,13652,13653],{},"абстрактні методи"," (без реалізації), які нащадки зобов'язані реалізувати.",[4237,13656,13658],{"id":13657},"оголошення-абстрактного-класу","Оголошення абстрактного класу",[3846,13660,13661,13662,4671],{},"Абстрактний клас оголошується через ключове слово ",[3753,13663,13664],{},"abstract",[3854,13666,13668],{"className":3856,"code":13667,"language":3858,"meta":3859,"style":3859},"abstract class Shape {\n  constructor(public color: string) {}\n\n  abstract getArea(): number;       \u002F\u002F абстрактний метод: без реалізації\n  abstract getPerimeter(): number;\n\n  describe(): string {               \u002F\u002F звичайний метод: з реалізацією\n    return `Фігура кольору ${this.color} з площею ${this.getArea()}`;\n  }\n}\n\n\u002F\u002F const shape = new Shape('червоний');  \u002F\u002F ❌ Error: Cannot create an instance of an abstract class\n",[3753,13669,13670,13682,13699,13703,13720,13733,13737,13752,13791,13795,13799,13803],{"__ignoreMap":3859},[3863,13671,13672,13674,13677,13680],{"class":3865,"line":3866},[3863,13673,13664],{"class":3869},[3863,13675,13676],{"class":3869}," class",[3863,13678,13679],{"class":3894}," Shape",[3863,13681,3928],{"class":3877},[3863,13683,13684,13686,13688,13690,13693,13695,13697],{"class":3865,"line":3921},[3863,13685,7827],{"class":3869},[3863,13687,3878],{"class":3877},[3863,13689,3775],{"class":3869},[3863,13691,13692],{"class":3881}," color",[3863,13694,3891],{"class":3877},[3863,13696,3895],{"class":3894},[3863,13698,8888],{"class":3877},[3863,13700,13701],{"class":3865,"line":3931},[3863,13702,4002],{"emptyLinePlaceholder":4001},[3863,13704,13705,13708,13711,13713,13715,13717],{"class":3865,"line":3942},[3863,13706,13707],{"class":3869},"  abstract",[3863,13709,13710],{"class":3873}," getArea",[3863,13712,5715],{"class":3877},[3863,13714,3915],{"class":3894},[3863,13716,4737],{"class":3877},[3863,13718,13719],{"class":4559},"\u002F\u002F абстрактний метод: без реалізації\n",[3863,13721,13722,13724,13727,13729,13731],{"class":3865,"line":3971},[3863,13723,13707],{"class":3869},[3863,13725,13726],{"class":3873}," getPerimeter",[3863,13728,5715],{"class":3877},[3863,13730,3915],{"class":3894},[3863,13732,4108],{"class":3877},[3863,13734,13735],{"class":3865,"line":3986},[3863,13736,4002],{"emptyLinePlaceholder":4001},[3863,13738,13739,13742,13744,13746,13749],{"class":3865,"line":3992},[3863,13740,13741],{"class":3873},"  describe",[3863,13743,5715],{"class":3877},[3863,13745,3895],{"class":3894},[3863,13747,13748],{"class":3877}," {               ",[3863,13750,13751],{"class":4559},"\u002F\u002F звичайний метод: з реалізацією\n",[3863,13753,13754,13756,13759,13761,13763,13765,13768,13770,13773,13775,13777,13779,13782,13785,13787,13789],{"class":3865,"line":3998},[3863,13755,6921],{"class":3924},[3863,13757,13758],{"class":4089}," `Фігура кольору ",[3863,13760,4998],{"class":3869},[3863,13762,6885],{"class":3869},[3863,13764,3783],{"class":6289},[3863,13766,13767],{"class":3881},"color",[3863,13769,5003],{"class":3869},[3863,13771,13772],{"class":4089}," з площею ",[3863,13774,4998],{"class":3869},[3863,13776,6885],{"class":3869},[3863,13778,3783],{"class":6289},[3863,13780,13781],{"class":3873},"getArea",[3863,13783,13784],{"class":6289},"()",[3863,13786,5003],{"class":3869},[3863,13788,5006],{"class":4089},[3863,13790,4108],{"class":3877},[3863,13792,13793],{"class":3865,"line":4005},[3863,13794,5098],{"class":3877},[3863,13796,13797],{"class":3865,"line":4050},[3863,13798,3995],{"class":3877},[3863,13800,13801],{"class":3865,"line":4111},[3863,13802,4002],{"emptyLinePlaceholder":4001},[3863,13804,13805,13808],{"class":3865,"line":4482},[3863,13806,13807],{"class":4559},"\u002F\u002F const shape = new Shape('червоний');",[3863,13809,13810],{"class":4559},"  \u002F\u002F ❌ Error: Cannot create an instance of an abstract class\n",[3846,13812,13813,13814,4671],{},"Спроба створити екземпляр абстрактного класу призводить до помилки. Абстрактний клас можна лише ",[3796,13815,13816],{},"успадковувати",[3854,13818,13820],{"className":3856,"code":13819,"language":3858,"meta":3859,"style":3859},"class Circle extends Shape {\n  constructor(color: string, public radius: number) {\n    super(color);\n  }\n\n  getArea(): number {\n    return Math.PI * this.radius * this.radius;\n  }\n\n  getPerimeter(): number {\n    return 2 * Math.PI * this.radius;\n  }\n}\n\nclass Rectangle extends Shape {\n  constructor(color: string, public width: number, public height: number) {\n    super(color);\n  }\n\n  getArea(): number {\n    return this.width * this.height;\n  }\n\n  getPerimeter(): number {\n    return 2 * (this.width + this.height);\n  }\n}\n\nconst circle = new Circle('синій', 5);\nconsole.log(circle.describe());  \u002F\u002F \"Фігура кольору синій з площею 78.53981633974483\"\n\nconst rect = new Rectangle('зелений', 10, 20);\nconsole.log(rect.describe());    \u002F\u002F \"Фігура кольору зелений з площею 200\"\n",[3753,13821,13822,13835,13860,13870,13874,13878,13889,13917,13921,13925,13936,13962,13966,13970,13974,13987,14023,14033,14037,14041,14051,14073,14077,14081,14091,14117,14121,14125,14129,14153,14176,14180,14209],{"__ignoreMap":3859},[3863,13823,13824,13826,13829,13831,13833],{"class":3865,"line":3866},[3863,13825,7514],{"class":3869},[3863,13827,13828],{"class":3894}," Circle",[3863,13830,5692],{"class":3869},[3863,13832,13679],{"class":3894},[3863,13834,3928],{"class":3877},[3863,13836,13837,13839,13841,13843,13845,13847,13849,13851,13854,13856,13858],{"class":3865,"line":3921},[3863,13838,7827],{"class":3869},[3863,13840,3878],{"class":3877},[3863,13842,13767],{"class":3881},[3863,13844,3891],{"class":3877},[3863,13846,3895],{"class":3894},[3863,13848,3776],{"class":3877},[3863,13850,3775],{"class":3869},[3863,13852,13853],{"class":3881}," radius",[3863,13855,3891],{"class":3877},[3863,13857,3915],{"class":3894},[3863,13859,5195],{"class":3877},[3863,13861,13862,13864,13866,13868],{"class":3865,"line":3931},[3863,13863,11685],{"class":3869},[3863,13865,3878],{"class":3877},[3863,13867,13767],{"class":3881},[3863,13869,5009],{"class":3877},[3863,13871,13872],{"class":3865,"line":3942},[3863,13873,5098],{"class":3877},[3863,13875,13876],{"class":3865,"line":3971},[3863,13877,4002],{"emptyLinePlaceholder":4001},[3863,13879,13880,13883,13885,13887],{"class":3865,"line":3986},[3863,13881,13882],{"class":3873},"  getArea",[3863,13884,5715],{"class":3877},[3863,13886,3915],{"class":3894},[3863,13888,3928],{"class":3877},[3863,13890,13891,13893,13895,13897,13899,13901,13903,13905,13907,13909,13911,13913,13915],{"class":3865,"line":3992},[3863,13892,6921],{"class":3924},[3863,13894,3948],{"class":3881},[3863,13896,3783],{"class":3877},[3863,13898,9297],{"class":4493},[3863,13900,9300],{"class":3877},[3863,13902,6885],{"class":3869},[3863,13904,3783],{"class":3877},[3863,13906,9276],{"class":3881},[3863,13908,9300],{"class":3877},[3863,13910,6885],{"class":3869},[3863,13912,3783],{"class":3877},[3863,13914,9276],{"class":3881},[3863,13916,4108],{"class":3877},[3863,13918,13919],{"class":3865,"line":3998},[3863,13920,5098],{"class":3877},[3863,13922,13923],{"class":3865,"line":4005},[3863,13924,4002],{"emptyLinePlaceholder":4001},[3863,13926,13927,13930,13932,13934],{"class":3865,"line":4050},[3863,13928,13929],{"class":3873},"  getPerimeter",[3863,13931,5715],{"class":3877},[3863,13933,3915],{"class":3894},[3863,13935,3928],{"class":3877},[3863,13937,13938,13940,13943,13945,13948,13950,13952,13954,13956,13958,13960],{"class":3865,"line":4111},[3863,13939,6921],{"class":3924},[3863,13941,13942],{"class":3964}," 2",[3863,13944,9300],{"class":3877},[3863,13946,13947],{"class":3881},"Math",[3863,13949,3783],{"class":3877},[3863,13951,9297],{"class":4493},[3863,13953,9300],{"class":3877},[3863,13955,6885],{"class":3869},[3863,13957,3783],{"class":3877},[3863,13959,9276],{"class":3881},[3863,13961,4108],{"class":3877},[3863,13963,13964],{"class":3865,"line":4482},[3863,13965,5098],{"class":3877},[3863,13967,13968],{"class":3865,"line":4487},[3863,13969,3995],{"class":3877},[3863,13971,13972],{"class":3865,"line":4505},[3863,13973,4002],{"emptyLinePlaceholder":4001},[3863,13975,13976,13978,13981,13983,13985],{"class":3865,"line":4517},[3863,13977,7514],{"class":3869},[3863,13979,13980],{"class":3894}," Rectangle",[3863,13982,5692],{"class":3869},[3863,13984,13679],{"class":3894},[3863,13986,3928],{"class":3877},[3863,13988,13989,13991,13993,13995,13997,13999,14001,14003,14006,14008,14010,14012,14014,14017,14019,14021],{"class":3865,"line":4528},[3863,13990,7827],{"class":3869},[3863,13992,3878],{"class":3877},[3863,13994,13767],{"class":3881},[3863,13996,3891],{"class":3877},[3863,13998,3895],{"class":3894},[3863,14000,3776],{"class":3877},[3863,14002,3775],{"class":3869},[3863,14004,14005],{"class":3881}," width",[3863,14007,3891],{"class":3877},[3863,14009,3915],{"class":3894},[3863,14011,3776],{"class":3877},[3863,14013,3775],{"class":3869},[3863,14015,14016],{"class":3881}," height",[3863,14018,3891],{"class":3877},[3863,14020,3915],{"class":3894},[3863,14022,5195],{"class":3877},[3863,14024,14025,14027,14029,14031],{"class":3865,"line":4540},[3863,14026,11685],{"class":3869},[3863,14028,3878],{"class":3877},[3863,14030,13767],{"class":3881},[3863,14032,5009],{"class":3877},[3863,14034,14035],{"class":3865,"line":6647},[3863,14036,5098],{"class":3877},[3863,14038,14039],{"class":3865,"line":6658},[3863,14040,4002],{"emptyLinePlaceholder":4001},[3863,14042,14043,14045,14047,14049],{"class":3865,"line":6667},[3863,14044,13882],{"class":3873},[3863,14046,5715],{"class":3877},[3863,14048,3915],{"class":3894},[3863,14050,3928],{"class":3877},[3863,14052,14053,14055,14057,14059,14062,14064,14066,14068,14071],{"class":3865,"line":6918},[3863,14054,6921],{"class":3924},[3863,14056,6937],{"class":3869},[3863,14058,3783],{"class":3877},[3863,14060,14061],{"class":3881},"width",[3863,14063,9300],{"class":3877},[3863,14065,6885],{"class":3869},[3863,14067,3783],{"class":3877},[3863,14069,14070],{"class":3881},"height",[3863,14072,4108],{"class":3877},[3863,14074,14075],{"class":3865,"line":6957},[3863,14076,5098],{"class":3877},[3863,14078,14079],{"class":3865,"line":6962},[3863,14080,4002],{"emptyLinePlaceholder":4001},[3863,14082,14083,14085,14087,14089],{"class":3865,"line":7489},[3863,14084,13929],{"class":3873},[3863,14086,5715],{"class":3877},[3863,14088,3915],{"class":3894},[3863,14090,3928],{"class":3877},[3863,14092,14093,14095,14097,14100,14102,14104,14106,14109,14111,14113,14115],{"class":3865,"line":7495},[3863,14094,6921],{"class":3924},[3863,14096,13942],{"class":3964},[3863,14098,14099],{"class":3877}," * (",[3863,14101,6885],{"class":3869},[3863,14103,3783],{"class":3877},[3863,14105,14061],{"class":3881},[3863,14107,14108],{"class":3877}," + ",[3863,14110,6885],{"class":3869},[3863,14112,3783],{"class":3877},[3863,14114,14070],{"class":3881},[3863,14116,5009],{"class":3877},[3863,14118,14119],{"class":3865,"line":7501},[3863,14120,5098],{"class":3877},[3863,14122,14123],{"class":3865,"line":10312},[3863,14124,3995],{"class":3877},[3863,14126,14127],{"class":3865,"line":10333},[3863,14128,4002],{"emptyLinePlaceholder":4001},[3863,14130,14131,14133,14136,14138,14140,14142,14144,14147,14149,14151],{"class":3865,"line":10350},[3863,14132,4490],{"class":3869},[3863,14134,14135],{"class":4493}," circle",[3863,14137,4167],{"class":3877},[3863,14139,7639],{"class":3869},[3863,14141,13828],{"class":3873},[3863,14143,3878],{"class":3877},[3863,14145,14146],{"class":4089},"'синій'",[3863,14148,3776],{"class":3877},[3863,14150,9125],{"class":3964},[3863,14152,5009],{"class":3877},[3863,14154,14155,14157,14159,14161,14163,14166,14168,14171,14173],{"class":3865,"line":10373},[3863,14156,5355],{"class":3881},[3863,14158,3783],{"class":3877},[3863,14160,4941],{"class":3873},[3863,14162,3878],{"class":3877},[3863,14164,14165],{"class":3881},"circle",[3863,14167,3783],{"class":3877},[3863,14169,14170],{"class":3873},"describe",[3863,14172,7334],{"class":3877},[3863,14174,14175],{"class":4559},"\u002F\u002F \"Фігура кольору синій з площею 78.53981633974483\"\n",[3863,14177,14178],{"class":3865,"line":10378},[3863,14179,4002],{"emptyLinePlaceholder":4001},[3863,14181,14183,14185,14188,14190,14192,14194,14196,14199,14201,14203,14205,14207],{"class":3865,"line":14182},32,[3863,14184,4490],{"class":3869},[3863,14186,14187],{"class":4493}," rect",[3863,14189,4167],{"class":3877},[3863,14191,7639],{"class":3869},[3863,14193,13980],{"class":3873},[3863,14195,3878],{"class":3877},[3863,14197,14198],{"class":4089},"'зелений'",[3863,14200,3776],{"class":3877},[3863,14202,9101],{"class":3964},[3863,14204,3776],{"class":3877},[3863,14206,9456],{"class":3964},[3863,14208,5009],{"class":3877},[3863,14210,14212,14214,14216,14218,14220,14223,14225,14227,14230],{"class":3865,"line":14211},33,[3863,14213,5355],{"class":3881},[3863,14215,3783],{"class":3877},[3863,14217,4941],{"class":3873},[3863,14219,3878],{"class":3877},[3863,14221,14222],{"class":3881},"rect",[3863,14224,3783],{"class":3877},[3863,14226,14170],{"class":3873},[3863,14228,14229],{"class":3877},"());    ",[3863,14231,14232],{"class":4559},"\u002F\u002F \"Фігура кольору зелений з площею 200\"\n",[4237,14234,14236],{"id":14235},"абстрактні-методи-контракт-для-нащадків","Абстрактні методи: контракт для нащадків",[3846,14238,14239,14240,14242,14243,14246,14247,14250],{},"Абстрактні методи оголошуються через ",[3753,14241,13664],{}," і ",[3796,14244,14245],{},"не мають тіла"," (лише сигнатура). Кожен нащадок абстрактного класу ",[3796,14248,14249],{},"зобов'язаний"," надати реалізацію всіх абстрактних методів, інакше компілятор видасть помилку:",[3854,14252,14254],{"className":3856,"code":14253,"language":3858,"meta":3859,"style":3859},"class Triangle extends Shape {\n  constructor(color: string, public base: number, public height: number) {\n    super(color);\n  }\n\n  getArea(): number {\n    return 0.5 * this.base * this.height;\n  }\n\n  \u002F\u002F ❌ Error: Non-abstract class 'Triangle' does not implement inherited abstract member 'getPerimeter'\n}\n",[3753,14255,14256,14269,14304,14314,14318,14322,14332,14358,14362,14366,14371],{"__ignoreMap":3859},[3863,14257,14258,14260,14263,14265,14267],{"class":3865,"line":3866},[3863,14259,7514],{"class":3869},[3863,14261,14262],{"class":3894}," Triangle",[3863,14264,5692],{"class":3869},[3863,14266,13679],{"class":3894},[3863,14268,3928],{"class":3877},[3863,14270,14271,14273,14275,14277,14279,14281,14283,14285,14288,14290,14292,14294,14296,14298,14300,14302],{"class":3865,"line":3921},[3863,14272,7827],{"class":3869},[3863,14274,3878],{"class":3877},[3863,14276,13767],{"class":3881},[3863,14278,3891],{"class":3877},[3863,14280,3895],{"class":3894},[3863,14282,3776],{"class":3877},[3863,14284,3775],{"class":3869},[3863,14286,14287],{"class":3881}," base",[3863,14289,3891],{"class":3877},[3863,14291,3915],{"class":3894},[3863,14293,3776],{"class":3877},[3863,14295,3775],{"class":3869},[3863,14297,14016],{"class":3881},[3863,14299,3891],{"class":3877},[3863,14301,3915],{"class":3894},[3863,14303,5195],{"class":3877},[3863,14305,14306,14308,14310,14312],{"class":3865,"line":3931},[3863,14307,11685],{"class":3869},[3863,14309,3878],{"class":3877},[3863,14311,13767],{"class":3881},[3863,14313,5009],{"class":3877},[3863,14315,14316],{"class":3865,"line":3942},[3863,14317,5098],{"class":3877},[3863,14319,14320],{"class":3865,"line":3971},[3863,14321,4002],{"emptyLinePlaceholder":4001},[3863,14323,14324,14326,14328,14330],{"class":3865,"line":3986},[3863,14325,13882],{"class":3873},[3863,14327,5715],{"class":3877},[3863,14329,3915],{"class":3894},[3863,14331,3928],{"class":3877},[3863,14333,14334,14336,14339,14341,14343,14345,14348,14350,14352,14354,14356],{"class":3865,"line":3992},[3863,14335,6921],{"class":3924},[3863,14337,14338],{"class":3964}," 0.5",[3863,14340,9300],{"class":3877},[3863,14342,6885],{"class":3869},[3863,14344,3783],{"class":3877},[3863,14346,14347],{"class":3881},"base",[3863,14349,9300],{"class":3877},[3863,14351,6885],{"class":3869},[3863,14353,3783],{"class":3877},[3863,14355,14070],{"class":3881},[3863,14357,4108],{"class":3877},[3863,14359,14360],{"class":3865,"line":3998},[3863,14361,5098],{"class":3877},[3863,14363,14364],{"class":3865,"line":4005},[3863,14365,4002],{"emptyLinePlaceholder":4001},[3863,14367,14368],{"class":3865,"line":4050},[3863,14369,14370],{"class":4559},"  \u002F\u002F ❌ Error: Non-abstract class 'Triangle' does not implement inherited abstract member 'getPerimeter'\n",[3863,14372,14373],{"class":3865,"line":4111},[3863,14374,3995],{"class":3877},[3846,14376,14377,14378,4671],{},"Щоб усунути помилку, треба реалізувати ",[3753,14379,14380],{},"getPerimeter()",[3854,14382,14384],{"className":3856,"code":14383,"language":3858,"meta":3859,"style":3859},"class Triangle extends Shape {\n  constructor(color: string, public a: number, public b: number, public c: number) {\n    super(color);\n  }\n\n  getArea(): number {\n    const s = (this.a + this.b + this.c) \u002F 2;\n    return Math.sqrt(s * (s - this.a) * (s - this.b) * (s - this.c));\n  }\n\n  getPerimeter(): number {\n    return this.a + this.b + this.c;\n  }\n}\n\nconst triangle = new Triangle('жовтий', 3, 4, 5);\nconsole.log(triangle.describe());  \u002F\u002F \"Фігура кольору жовтий з площею 6\"\n",[3753,14385,14386,14398,14444,14454,14458,14462,14472,14511,14567,14571,14575,14585,14613,14617,14621,14625,14658],{"__ignoreMap":3859},[3863,14387,14388,14390,14392,14394,14396],{"class":3865,"line":3866},[3863,14389,7514],{"class":3869},[3863,14391,14262],{"class":3894},[3863,14393,5692],{"class":3869},[3863,14395,13679],{"class":3894},[3863,14397,3928],{"class":3877},[3863,14399,14400,14402,14404,14406,14408,14410,14412,14414,14416,14418,14420,14422,14424,14427,14429,14431,14433,14435,14438,14440,14442],{"class":3865,"line":3921},[3863,14401,7827],{"class":3869},[3863,14403,3878],{"class":3877},[3863,14405,13767],{"class":3881},[3863,14407,3891],{"class":3877},[3863,14409,3895],{"class":3894},[3863,14411,3776],{"class":3877},[3863,14413,3775],{"class":3869},[3863,14415,9354],{"class":3881},[3863,14417,3891],{"class":3877},[3863,14419,3915],{"class":3894},[3863,14421,3776],{"class":3877},[3863,14423,3775],{"class":3869},[3863,14425,14426],{"class":3881}," b",[3863,14428,3891],{"class":3877},[3863,14430,3915],{"class":3894},[3863,14432,3776],{"class":3877},[3863,14434,3775],{"class":3869},[3863,14436,14437],{"class":3881}," c",[3863,14439,3891],{"class":3877},[3863,14441,3915],{"class":3894},[3863,14443,5195],{"class":3877},[3863,14445,14446,14448,14450,14452],{"class":3865,"line":3931},[3863,14447,11685],{"class":3869},[3863,14449,3878],{"class":3877},[3863,14451,13767],{"class":3881},[3863,14453,5009],{"class":3877},[3863,14455,14456],{"class":3865,"line":3942},[3863,14457,5098],{"class":3877},[3863,14459,14460],{"class":3865,"line":3971},[3863,14461,4002],{"emptyLinePlaceholder":4001},[3863,14463,14464,14466,14468,14470],{"class":3865,"line":3986},[3863,14465,13882],{"class":3873},[3863,14467,5715],{"class":3877},[3863,14469,3915],{"class":3894},[3863,14471,3928],{"class":3877},[3863,14473,14474,14476,14479,14481,14483,14485,14487,14489,14491,14493,14495,14497,14499,14501,14504,14507,14509],{"class":3865,"line":3992},[3863,14475,9576],{"class":3869},[3863,14477,14478],{"class":4493}," s",[3863,14480,6131],{"class":3877},[3863,14482,6885],{"class":3869},[3863,14484,3783],{"class":3877},[3863,14486,9328],{"class":3881},[3863,14488,14108],{"class":3877},[3863,14490,6885],{"class":3869},[3863,14492,3783],{"class":3877},[3863,14494,9337],{"class":3881},[3863,14496,14108],{"class":3877},[3863,14498,6885],{"class":3869},[3863,14500,3783],{"class":3877},[3863,14502,14503],{"class":3881},"c",[3863,14505,14506],{"class":3877},") \u002F ",[3863,14508,9136],{"class":3964},[3863,14510,4108],{"class":3877},[3863,14512,14513,14515,14517,14519,14522,14524,14527,14529,14531,14533,14535,14537,14539,14542,14544,14546,14548,14550,14552,14554,14556,14558,14560,14562,14564],{"class":3865,"line":3998},[3863,14514,6921],{"class":3924},[3863,14516,3948],{"class":3881},[3863,14518,3783],{"class":3877},[3863,14520,14521],{"class":3873},"sqrt",[3863,14523,3878],{"class":3877},[3863,14525,14526],{"class":3881},"s",[3863,14528,14099],{"class":3877},[3863,14530,14526],{"class":3881},[3863,14532,12447],{"class":3877},[3863,14534,6885],{"class":3869},[3863,14536,3783],{"class":3877},[3863,14538,9328],{"class":3881},[3863,14540,14541],{"class":3877},") * (",[3863,14543,14526],{"class":3881},[3863,14545,12447],{"class":3877},[3863,14547,6885],{"class":3869},[3863,14549,3783],{"class":3877},[3863,14551,9337],{"class":3881},[3863,14553,14541],{"class":3877},[3863,14555,14526],{"class":3881},[3863,14557,12447],{"class":3877},[3863,14559,6885],{"class":3869},[3863,14561,3783],{"class":3877},[3863,14563,14503],{"class":3881},[3863,14565,14566],{"class":3877},"));\n",[3863,14568,14569],{"class":3865,"line":4005},[3863,14570,5098],{"class":3877},[3863,14572,14573],{"class":3865,"line":4050},[3863,14574,4002],{"emptyLinePlaceholder":4001},[3863,14576,14577,14579,14581,14583],{"class":3865,"line":4111},[3863,14578,13929],{"class":3873},[3863,14580,5715],{"class":3877},[3863,14582,3915],{"class":3894},[3863,14584,3928],{"class":3877},[3863,14586,14587,14589,14591,14593,14595,14597,14599,14601,14603,14605,14607,14609,14611],{"class":3865,"line":4482},[3863,14588,6921],{"class":3924},[3863,14590,6937],{"class":3869},[3863,14592,3783],{"class":3877},[3863,14594,9328],{"class":3881},[3863,14596,14108],{"class":3877},[3863,14598,6885],{"class":3869},[3863,14600,3783],{"class":3877},[3863,14602,9337],{"class":3881},[3863,14604,14108],{"class":3877},[3863,14606,6885],{"class":3869},[3863,14608,3783],{"class":3877},[3863,14610,14503],{"class":3881},[3863,14612,4108],{"class":3877},[3863,14614,14615],{"class":3865,"line":4487},[3863,14616,5098],{"class":3877},[3863,14618,14619],{"class":3865,"line":4505},[3863,14620,3995],{"class":3877},[3863,14622,14623],{"class":3865,"line":4517},[3863,14624,4002],{"emptyLinePlaceholder":4001},[3863,14626,14627,14629,14632,14634,14636,14638,14640,14643,14645,14647,14649,14652,14654,14656],{"class":3865,"line":4528},[3863,14628,4490],{"class":3869},[3863,14630,14631],{"class":4493}," triangle",[3863,14633,4167],{"class":3877},[3863,14635,7639],{"class":3869},[3863,14637,14262],{"class":3873},[3863,14639,3878],{"class":3877},[3863,14641,14642],{"class":4089},"'жовтий'",[3863,14644,3776],{"class":3877},[3863,14646,9146],{"class":3964},[3863,14648,3776],{"class":3877},[3863,14650,14651],{"class":3964},"4",[3863,14653,3776],{"class":3877},[3863,14655,9125],{"class":3964},[3863,14657,5009],{"class":3877},[3863,14659,14660,14662,14664,14666,14668,14671,14673,14675,14677],{"class":3865,"line":4540},[3863,14661,5355],{"class":3881},[3863,14663,3783],{"class":3877},[3863,14665,4941],{"class":3873},[3863,14667,3878],{"class":3877},[3863,14669,14670],{"class":3881},"triangle",[3863,14672,3783],{"class":3877},[3863,14674,14170],{"class":3873},[3863,14676,7334],{"class":3877},[3863,14678,14679],{"class":4559},"\u002F\u002F \"Фігура кольору жовтий з площею 6\"\n",[4237,14681,14683],{"id":14682},"абстрактні-класи-vs-інтерфейси","Абстрактні класи vs Інтерфейси",[3846,14685,14686],{},"Обидва механізми дозволяють визначити контракт, але мають різне призначення та можливості:",[14688,14689,14690,14704],"table",{},[14691,14692,14693],"thead",{},[14694,14695,14696,14700,14702],"tr",{},[14697,14698,14699],"th",{},"Характеристика",[14697,14701,13642],{},[14697,14703,4226],{},[14705,14706,14707,14721,14733,14746,14758,14778],"tbody",{},[14694,14708,14709,14715,14718],{},[14710,14711,14712],"td",{},[3796,14713,14714],{},"Реалізація методів",[14710,14716,14717],{},"Може містити методи з реалізацією",[14710,14719,14720],{},"Лише сигнатури, без реалізації",[14694,14722,14723,14727,14730],{},[14710,14724,14725],{},[3796,14726,8430],{},[14710,14728,14729],{},"Може мати конструктор",[14710,14731,14732],{},"Не може мати конструктора",[14694,14734,14735,14740,14743],{},[14710,14736,14737],{},[3796,14738,14739],{},"Поля класу",[14710,14741,14742],{},"Може мати поля з ініціалізацією",[14710,14744,14745],{},"Не може мати полів (лише опис типу)",[14694,14747,14748,14752,14755],{},[14710,14749,14750],{},[3796,14751,6695],{},[14710,14753,14754],{},"Неможливо (клас може успадковувати лише один клас)",[14710,14756,14757],{},"Можливо (клас може реалізовувати кілька інтерфейсів)",[14694,14759,14760,14765,14775],{},[14710,14761,14762],{},[3796,14763,14764],{},"Модифікатори доступу",[14710,14766,14767,14768,3776,14770,3776,14772,14774],{},"Підтримуються (",[3753,14769,3779],{},[3753,14771,3782],{},[3753,14773,3775],{},")",[14710,14776,14777],{},"Не підтримуються (всі члени публічні)",[14694,14779,14780,14785,14788],{},[14710,14781,14782],{},[3796,14783,14784],{},"Використання",[14710,14786,14787],{},"Базовий клас з частковою реалізацією",[14710,14789,14790],{},"Контракт поведінки без реалізації",[4845,14792,14793,14798,14821,14826],{},[3846,14794,14795],{},[3796,14796,14797],{},"Коли використовувати абстрактний клас:",[3746,14799,14800,14807,14814],{},[3749,14801,14802,14803,14806],{},"Коли потрібна ",[3796,14804,14805],{},"спільна реалізація"," частини функціональності для всіх нащадків (щоб уникнути дублювання коду).",[3749,14808,14809,14810,14813],{},"Коли базовий клас має містити ",[3796,14811,14812],{},"приватні або protected поля"," та методи, недоступні ззовні.",[3749,14815,14816,14817,14820],{},"Коли моделюєте ",[3796,14818,14819],{},"IS-A зв'язок"," (Circle IS-A Shape, Dog IS-A Animal).",[3846,14822,14823],{},[3796,14824,14825],{},"Коли використовувати інтерфейс:",[3746,14827,14828,14835,14842],{},[3749,14829,14830,14831,14834],{},"Коли потрібен ",[3796,14832,14833],{},"чистий контракт поведінки"," без реалізації.",[3749,14836,14837,14838,14841],{},"Коли клас має реалізовувати ",[3796,14839,14840],{},"кілька контрактів"," одночасно (множинна реалізація інтерфейсів).",[3749,14843,14844,14845,14848],{},"Коли описуєте ",[3796,14846,14847],{},"CAN-DO зв'язок"," (Car CAN-DO Drivable, Logger CAN-DO Serializable).",[3838,14850],{},[3841,14852,14854],{"id":14853},"getters-та-setters-контрольований-доступ-до-полів","Getters та Setters: контрольований доступ до полів",[3846,14856,14857,3756,14860,14863,14864,14867],{},[3796,14858,14859],{},"Getters",[3796,14861,14862],{},"setters"," (акцесори, ",[4229,14865,14866],{},"accessors",") дозволяють контролювати доступ до полів класу, додаючи логіку при читанні або записі значення. Вони виглядають як звичайні властивості під час використання, але насправді є методами.",[4237,14869,14871],{"id":14870},"синтаксис-getters-та-setters","Синтаксис getters та setters",[3846,14873,14874,14875,14878,14879,4671],{},"Getter оголошується через ",[3753,14876,14877],{},"get"," перед назвою методу, setter — через ",[3753,14880,14881],{},"set",[3854,14883,14885],{"className":3856,"code":14884,"language":3858,"meta":3859,"style":3859},"class Temperature {\n  private _celsius: number = 0;\n\n  get celsius(): number {\n    return this._celsius;\n  }\n\n  set celsius(value: number) {\n    if (value \u003C -273.15) {\n      throw new Error('Температура не може бути нижчою за абсолютний нуль');\n    }\n    this._celsius = value;\n  }\n\n  get fahrenheit(): number {\n    return this._celsius * 9\u002F5 + 32;\n  }\n\n  set fahrenheit(value: number) {\n    this.celsius = (value - 32) * 5\u002F9;  \u002F\u002F конвертуємо у Цельсій через setter\n  }\n}\n\nconst temp = new Temperature();\ntemp.celsius = 25;               \u002F\u002F викликається setter celsius\nconsole.log(temp.celsius);       \u002F\u002F 25 (викликається getter celsius)\nconsole.log(temp.fahrenheit);    \u002F\u002F 77 (викликається getter fahrenheit)\n\ntemp.fahrenheit = 86;            \u002F\u002F викликається setter fahrenheit\nconsole.log(temp.celsius);       \u002F\u002F 30\n\n\u002F\u002F temp.celsius = -300;          \u002F\u002F ❌ Error: Температура не може бути нижчою за абсолютний нуль\n",[3753,14886,14887,14896,14913,14917,14931,14944,14948,14952,14969,14985,15002,15006,15020,15024,15028,15041,15067,15071,15075,15091,15122,15126,15130,15134,15149,15169,15191,15213,15217,15236,15257,15261],{"__ignoreMap":3859},[3863,14888,14889,14891,14894],{"class":3865,"line":3866},[3863,14890,7514],{"class":3869},[3863,14892,14893],{"class":3894}," Temperature",[3863,14895,3928],{"class":3877},[3863,14897,14898,14900,14903,14905,14907,14909,14911],{"class":3865,"line":3921},[3863,14899,10066],{"class":3869},[3863,14901,14902],{"class":3881}," _celsius",[3863,14904,3891],{"class":3877},[3863,14906,3915],{"class":3894},[3863,14908,4167],{"class":3877},[3863,14910,4070],{"class":3964},[3863,14912,4108],{"class":3877},[3863,14914,14915],{"class":3865,"line":3931},[3863,14916,4002],{"emptyLinePlaceholder":4001},[3863,14918,14919,14922,14925,14927,14929],{"class":3865,"line":3942},[3863,14920,14921],{"class":3869},"  get",[3863,14923,14924],{"class":3873}," celsius",[3863,14926,5715],{"class":3877},[3863,14928,3915],{"class":3894},[3863,14930,3928],{"class":3877},[3863,14932,14933,14935,14937,14939,14942],{"class":3865,"line":3971},[3863,14934,6921],{"class":3924},[3863,14936,6937],{"class":3869},[3863,14938,3783],{"class":3877},[3863,14940,14941],{"class":3881},"_celsius",[3863,14943,4108],{"class":3877},[3863,14945,14946],{"class":3865,"line":3986},[3863,14947,5098],{"class":3877},[3863,14949,14950],{"class":3865,"line":3992},[3863,14951,4002],{"emptyLinePlaceholder":4001},[3863,14953,14954,14957,14959,14961,14963,14965,14967],{"class":3865,"line":3998},[3863,14955,14956],{"class":3869},"  set",[3863,14958,14924],{"class":3873},[3863,14960,3878],{"class":3877},[3863,14962,8922],{"class":3881},[3863,14964,3891],{"class":3877},[3863,14966,3915],{"class":3894},[3863,14968,5195],{"class":3877},[3863,14970,14971,14973,14975,14977,14980,14983],{"class":3865,"line":4005},[3863,14972,10146],{"class":3924},[3863,14974,4227],{"class":3877},[3863,14976,8922],{"class":3881},[3863,14978,14979],{"class":3877}," \u003C -",[3863,14981,14982],{"class":3964},"273.15",[3863,14984,5195],{"class":3877},[3863,14986,14987,14990,14992,14995,14997,15000],{"class":3865,"line":4050},[3863,14988,14989],{"class":3924},"      throw",[3863,14991,3977],{"class":3869},[3863,14993,14994],{"class":3873}," Error",[3863,14996,3878],{"class":3877},[3863,14998,14999],{"class":4089},"'Температура не може бути нижчою за абсолютний нуль'",[3863,15001,5009],{"class":3877},[3863,15003,15004],{"class":3865,"line":4111},[3863,15005,8118],{"class":3877},[3863,15007,15008,15010,15012,15014,15016,15018],{"class":3865,"line":4482},[3863,15009,7842],{"class":3869},[3863,15011,3783],{"class":3877},[3863,15013,14941],{"class":3881},[3863,15015,4167],{"class":3877},[3863,15017,8922],{"class":3881},[3863,15019,4108],{"class":3877},[3863,15021,15022],{"class":3865,"line":4487},[3863,15023,5098],{"class":3877},[3863,15025,15026],{"class":3865,"line":4505},[3863,15027,4002],{"emptyLinePlaceholder":4001},[3863,15029,15030,15032,15035,15037,15039],{"class":3865,"line":4517},[3863,15031,14921],{"class":3869},[3863,15033,15034],{"class":3873}," fahrenheit",[3863,15036,5715],{"class":3877},[3863,15038,3915],{"class":3894},[3863,15040,3928],{"class":3877},[3863,15042,15043,15045,15047,15049,15051,15053,15056,15059,15061,15063,15065],{"class":3865,"line":4528},[3863,15044,6921],{"class":3924},[3863,15046,6937],{"class":3869},[3863,15048,3783],{"class":3877},[3863,15050,14941],{"class":3881},[3863,15052,9300],{"class":3877},[3863,15054,15055],{"class":3964},"9",[3863,15057,15058],{"class":3877},"\u002F",[3863,15060,9125],{"class":3964},[3863,15062,14108],{"class":3877},[3863,15064,7935],{"class":3964},[3863,15066,4108],{"class":3877},[3863,15068,15069],{"class":3865,"line":4540},[3863,15070,5098],{"class":3877},[3863,15072,15073],{"class":3865,"line":6647},[3863,15074,4002],{"emptyLinePlaceholder":4001},[3863,15076,15077,15079,15081,15083,15085,15087,15089],{"class":3865,"line":6658},[3863,15078,14956],{"class":3869},[3863,15080,15034],{"class":3873},[3863,15082,3878],{"class":3877},[3863,15084,8922],{"class":3881},[3863,15086,3891],{"class":3877},[3863,15088,3915],{"class":3894},[3863,15090,5195],{"class":3877},[3863,15092,15093,15095,15097,15100,15102,15104,15106,15108,15111,15113,15115,15117,15119],{"class":3865,"line":6667},[3863,15094,7842],{"class":3869},[3863,15096,3783],{"class":3877},[3863,15098,15099],{"class":3881},"celsius",[3863,15101,6131],{"class":3877},[3863,15103,8922],{"class":3881},[3863,15105,12447],{"class":3877},[3863,15107,7935],{"class":3964},[3863,15109,15110],{"class":3877},") * ",[3863,15112,9125],{"class":3964},[3863,15114,15058],{"class":3877},[3863,15116,15055],{"class":3964},[3863,15118,5394],{"class":3877},[3863,15120,15121],{"class":4559},"\u002F\u002F конвертуємо у Цельсій через setter\n",[3863,15123,15124],{"class":3865,"line":6918},[3863,15125,5098],{"class":3877},[3863,15127,15128],{"class":3865,"line":6957},[3863,15129,3995],{"class":3877},[3863,15131,15132],{"class":3865,"line":6962},[3863,15133,4002],{"emptyLinePlaceholder":4001},[3863,15135,15136,15138,15141,15143,15145,15147],{"class":3865,"line":7489},[3863,15137,4490],{"class":3869},[3863,15139,15140],{"class":4493}," temp",[3863,15142,4167],{"class":3877},[3863,15144,7639],{"class":3869},[3863,15146,14893],{"class":3873},[3863,15148,9154],{"class":3877},[3863,15150,15151,15154,15156,15158,15160,15163,15166],{"class":3865,"line":7495},[3863,15152,15153],{"class":3881},"temp",[3863,15155,3783],{"class":3877},[3863,15157,15099],{"class":3881},[3863,15159,4167],{"class":3877},[3863,15161,15162],{"class":3964},"25",[3863,15164,15165],{"class":3877},";               ",[3863,15167,15168],{"class":4559},"\u002F\u002F викликається setter celsius\n",[3863,15170,15171,15173,15175,15177,15179,15181,15183,15185,15188],{"class":3865,"line":7501},[3863,15172,5355],{"class":3881},[3863,15174,3783],{"class":3877},[3863,15176,4941],{"class":3873},[3863,15178,3878],{"class":3877},[3863,15180,15153],{"class":3881},[3863,15182,3783],{"class":3877},[3863,15184,15099],{"class":3881},[3863,15186,15187],{"class":3877},");       ",[3863,15189,15190],{"class":4559},"\u002F\u002F 25 (викликається getter celsius)\n",[3863,15192,15193,15195,15197,15199,15201,15203,15205,15208,15210],{"class":3865,"line":10312},[3863,15194,5355],{"class":3881},[3863,15196,3783],{"class":3877},[3863,15198,4941],{"class":3873},[3863,15200,3878],{"class":3877},[3863,15202,15153],{"class":3881},[3863,15204,3783],{"class":3877},[3863,15206,15207],{"class":3881},"fahrenheit",[3863,15209,11061],{"class":3877},[3863,15211,15212],{"class":4559},"\u002F\u002F 77 (викликається getter fahrenheit)\n",[3863,15214,15215],{"class":3865,"line":10333},[3863,15216,4002],{"emptyLinePlaceholder":4001},[3863,15218,15219,15221,15223,15225,15227,15230,15233],{"class":3865,"line":10350},[3863,15220,15153],{"class":3881},[3863,15222,3783],{"class":3877},[3863,15224,15207],{"class":3881},[3863,15226,4167],{"class":3877},[3863,15228,15229],{"class":3964},"86",[3863,15231,15232],{"class":3877},";            ",[3863,15234,15235],{"class":4559},"\u002F\u002F викликається setter fahrenheit\n",[3863,15237,15238,15240,15242,15244,15246,15248,15250,15252,15254],{"class":3865,"line":10373},[3863,15239,5355],{"class":3881},[3863,15241,3783],{"class":3877},[3863,15243,4941],{"class":3873},[3863,15245,3878],{"class":3877},[3863,15247,15153],{"class":3881},[3863,15249,3783],{"class":3877},[3863,15251,15099],{"class":3881},[3863,15253,15187],{"class":3877},[3863,15255,15256],{"class":4559},"\u002F\u002F 30\n",[3863,15258,15259],{"class":3865,"line":10378},[3863,15260,4002],{"emptyLinePlaceholder":4001},[3863,15262,15263,15266],{"class":3865,"line":14182},[3863,15264,15265],{"class":4559},"\u002F\u002F temp.celsius = -300;",[3863,15267,15268],{"class":4559},"          \u002F\u002F ❌ Error: Температура не може бути нижчою за абсолютний нуль\n",[3846,15270,15271,15272,3756,15274,15276],{},"Зовні клас виглядає так, ніби ",[3753,15273,15099],{},[3753,15275,15207],{}," є звичайними властивостями, але насправді кожне звернення проходить через getter\u002Fsetter, де виконується валідація та конвертація.",[4145,15278,15279,15282,15283,15286,15287,15289,15290,15292],{},[3796,15280,15281],{},"Конвенція іменування:"," Часто приватне поле, що стоїть за getter\u002Fsetter, іменується з префіксом ",[3753,15284,15285],{},"_"," (наприклад, ",[3753,15288,14941],{},"), щоб уникнути конфлікту імен з акцесором. Getter та setter мають однакову назву без префіксу (",[3753,15291,15099],{},"), що дозволяє використовувати їх як властивість.",[4237,15294,15296],{"id":15295},"переваги-використання-getters-та-setters","Переваги використання getters та setters",[3746,15298,15299,15305,15314,15320,15326],{},[3749,15300,15301,15304],{},[3796,15302,15303],{},"Валідація:"," Можна перевіряти значення перед присвоєнням та кидати помилки при некоректних даних.",[3749,15306,15307,15310,15311,15313],{},[3796,15308,15309],{},"Обчислювані властивості:"," Getter може повертати значення, обчислене на основі інших полів (як ",[3753,15312,15207],{}," у прикладі вище).",[3749,15315,15316,15319],{},[3796,15317,15318],{},"Логування та моніторинг:"," Можна додати логування кожного звернення до поля для діагностики.",[3749,15321,15322,15325],{},[3796,15323,15324],{},"Зворотна сумісність:"," Якщо публічне поле потрібно замінити на getter\u002Fsetter (щоб додати валідацію), зовнішній код не потребуватиме змін — синтаксис використання залишається тим самим.",[3749,15327,15328,15331],{},[3796,15329,15330],{},"Lazy initialization:"," Getter може ініціалізувати значення лише при першому зверненні:",[3854,15333,15335],{"className":3856,"code":15334,"language":3858,"meta":3859,"style":3859},"class Database {\n  private _connection: Connection | null = null;\n\n  get connection(): Connection {\n    if (!this._connection) {\n      this._connection = createConnection();  \u002F\u002F ініціалізація при першому зверненні\n      console.log('З'єднання з базою даних встановлено');\n    }\n    return this._connection;\n  }\n}\n",[3753,15336,15337,15346,15368,15372,15385,15401,15419,15454,15458,15470,15474],{"__ignoreMap":3859},[3863,15338,15339,15341,15344],{"class":3865,"line":3866},[3863,15340,7514],{"class":3869},[3863,15342,15343],{"class":3894}," Database",[3863,15345,3928],{"class":3877},[3863,15347,15348,15350,15353,15355,15358,15360,15362,15364,15366],{"class":3865,"line":3921},[3863,15349,10066],{"class":3869},[3863,15351,15352],{"class":3881}," _connection",[3863,15354,3891],{"class":3877},[3863,15356,15357],{"class":3894},"Connection",[3863,15359,4173],{"class":3877},[3863,15361,7029],{"class":3894},[3863,15363,4167],{"class":3877},[3863,15365,7029],{"class":3869},[3863,15367,4108],{"class":3877},[3863,15369,15370],{"class":3865,"line":3931},[3863,15371,4002],{"emptyLinePlaceholder":4001},[3863,15373,15374,15376,15379,15381,15383],{"class":3865,"line":3942},[3863,15375,14921],{"class":3869},[3863,15377,15378],{"class":3873}," connection",[3863,15380,5715],{"class":3877},[3863,15382,15357],{"class":3894},[3863,15384,3928],{"class":3877},[3863,15386,15387,15389,15392,15394,15396,15399],{"class":3865,"line":3971},[3863,15388,10146],{"class":3924},[3863,15390,15391],{"class":3877}," (!",[3863,15393,6885],{"class":3869},[3863,15395,3783],{"class":3877},[3863,15397,15398],{"class":3881},"_connection",[3863,15400,5195],{"class":3877},[3863,15402,15403,15405,15407,15409,15411,15414,15416],{"class":3865,"line":3986},[3863,15404,10161],{"class":3869},[3863,15406,3783],{"class":3877},[3863,15408,15398],{"class":3881},[3863,15410,4167],{"class":3877},[3863,15412,15413],{"class":3873},"createConnection",[3863,15415,10747],{"class":3877},[3863,15417,15418],{"class":4559},"\u002F\u002F ініціалізація при першому зверненні\n",[3863,15420,15421,15424,15426,15428,15430,15433,15436,15439,15442,15445,15448,15451],{"class":3865,"line":3992},[3863,15422,15423],{"class":3881},"      console",[3863,15425,3783],{"class":3877},[3863,15427,4941],{"class":3873},[3863,15429,3878],{"class":3877},[3863,15431,15432],{"class":4089},"'З'",[3863,15434,15435],{"class":3881},"єднання",[3863,15437,15438],{"class":3881}," з",[3863,15440,15441],{"class":3881}," базою",[3863,15443,15444],{"class":3881}," даних",[3863,15446,15447],{"class":3881}," встановлено",[3863,15449,15450],{"class":4089},"')",[3863,15452,4108],{"class":15453},"se1LK",[3863,15455,15456],{"class":3865,"line":3998},[3863,15457,8118],{"class":3877},[3863,15459,15460,15462,15464,15466,15468],{"class":3865,"line":4005},[3863,15461,6921],{"class":3881},[3863,15463,6937],{"class":3869},[3863,15465,3783],{"class":3877},[3863,15467,15398],{"class":3881},[3863,15469,4108],{"class":3877},[3863,15471,15472],{"class":3865,"line":4050},[3863,15473,5098],{"class":3877},[3863,15475,15476],{"class":3865,"line":4111},[3863,15477,3995],{"class":3877},[6447,15479,15480,15481,15483],{},"Не зловживайте getters\u002Fsetters: якщо акцесор просто повертає або встановлює поле без жодної логіки, краще залишити поле публічним (або використати ",[3753,15482,4670],{}," для read-only властивостей). Додавання getter\u002Fsetter \"на всяк випадок\" ускладнює код без реальної користі.",[3838,15485],{},[3841,15487,15489],{"id":15488},"композиція-замість-наслідування-практичний-приклад","Композиція замість наслідування: практичний приклад",[3846,15491,15492,15493,15496,15497,4227,15500,15503],{},"Наслідування — потужний інструмент, але надмірне його використання призводить до ",[3796,15494,15495],{},"жорстких ієрархій класів",", де зміна базового класу впливає на всі нащадки. У багатьох випадках ",[3796,15498,15499],{},"композиція",[4229,15501,15502],{},"composition",") — підхід, при якому клас містить екземпляри інших класів як поля — виявляється гнучкішим та простішим у підтримці.",[3846,15505,15506],{},"Розглянемо класичну проблему: моделювання тварин з різними здібностями (літати, плавати, бігати). Через наслідування це швидко стає заплутаним:",[3854,15508,15510],{"className":3856,"code":15509,"language":3858,"meta":3859,"style":3859},"\u002F\u002F ❌ Проблематична ієрархія через наслідування\nclass Animal {\n  constructor(public name: string) {}\n}\n\nclass FlyingAnimal extends Animal {\n  fly() { console.log(`${this.name} літає`); }\n}\n\nclass SwimmingAnimal extends Animal {\n  swim() { console.log(`${this.name} плаває`); }\n}\n\n\u002F\u002F Але що робити з качкою, яка і літає, і плаває?\n\u002F\u002F TypeScript не підтримує множинне наслідування класів\n",[3753,15511,15512,15517,15525,15541,15545,15549,15562,15594,15598,15602,15615,15647,15651,15655,15660],{"__ignoreMap":3859},[3863,15513,15514],{"class":3865,"line":3866},[3863,15515,15516],{"class":4559},"\u002F\u002F ❌ Проблематична ієрархія через наслідування\n",[3863,15518,15519,15521,15523],{"class":3865,"line":3921},[3863,15520,7514],{"class":3869},[3863,15522,5652],{"class":3894},[3863,15524,3928],{"class":3877},[3863,15526,15527,15529,15531,15533,15535,15537,15539],{"class":3865,"line":3931},[3863,15528,7827],{"class":3869},[3863,15530,3878],{"class":3877},[3863,15532,3775],{"class":3869},[3863,15534,8591],{"class":3881},[3863,15536,3891],{"class":3877},[3863,15538,3895],{"class":3894},[3863,15540,8888],{"class":3877},[3863,15542,15543],{"class":3865,"line":3942},[3863,15544,3995],{"class":3877},[3863,15546,15547],{"class":3865,"line":3971},[3863,15548,4002],{"emptyLinePlaceholder":4001},[3863,15550,15551,15553,15556,15558,15560],{"class":3865,"line":3986},[3863,15552,7514],{"class":3869},[3863,15554,15555],{"class":3894}," FlyingAnimal",[3863,15557,5692],{"class":3869},[3863,15559,5652],{"class":3894},[3863,15561,3928],{"class":3877},[3863,15563,15564,15567,15569,15571,15573,15575,15577,15579,15581,15583,15585,15587,15589,15592],{"class":3865,"line":3992},[3863,15565,15566],{"class":3873},"  fly",[3863,15568,5776],{"class":3877},[3863,15570,5355],{"class":3881},[3863,15572,3783],{"class":3877},[3863,15574,4941],{"class":3873},[3863,15576,3878],{"class":3877},[3863,15578,5006],{"class":4089},[3863,15580,4998],{"class":3869},[3863,15582,6885],{"class":3869},[3863,15584,3783],{"class":6289},[3863,15586,3888],{"class":3881},[3863,15588,5003],{"class":3869},[3863,15590,15591],{"class":4089}," літає`",[3863,15593,5790],{"class":3877},[3863,15595,15596],{"class":3865,"line":3998},[3863,15597,3995],{"class":3877},[3863,15599,15600],{"class":3865,"line":4005},[3863,15601,4002],{"emptyLinePlaceholder":4001},[3863,15603,15604,15606,15609,15611,15613],{"class":3865,"line":4050},[3863,15605,7514],{"class":3869},[3863,15607,15608],{"class":3894}," SwimmingAnimal",[3863,15610,5692],{"class":3869},[3863,15612,5652],{"class":3894},[3863,15614,3928],{"class":3877},[3863,15616,15617,15620,15622,15624,15626,15628,15630,15632,15634,15636,15638,15640,15642,15645],{"class":3865,"line":4111},[3863,15618,15619],{"class":3873},"  swim",[3863,15621,5776],{"class":3877},[3863,15623,5355],{"class":3881},[3863,15625,3783],{"class":3877},[3863,15627,4941],{"class":3873},[3863,15629,3878],{"class":3877},[3863,15631,5006],{"class":4089},[3863,15633,4998],{"class":3869},[3863,15635,6885],{"class":3869},[3863,15637,3783],{"class":6289},[3863,15639,3888],{"class":3881},[3863,15641,5003],{"class":3869},[3863,15643,15644],{"class":4089}," плаває`",[3863,15646,5790],{"class":3877},[3863,15648,15649],{"class":3865,"line":4482},[3863,15650,3995],{"class":3877},[3863,15652,15653],{"class":3865,"line":4487},[3863,15654,4002],{"emptyLinePlaceholder":4001},[3863,15656,15657],{"class":3865,"line":4505},[3863,15658,15659],{"class":4559},"\u002F\u002F Але що робити з качкою, яка і літає, і плаває?\n",[3863,15661,15662],{"class":3865,"line":4517},[3863,15663,15664],{"class":4559},"\u002F\u002F TypeScript не підтримує множинне наслідування класів\n",[3846,15666,15667,15668,3756,15671,4671],{},"Рішення через ",[3796,15669,15670],{},"композицію",[3796,15672,15673],{},"інтерфейси",[3854,15675,15677],{"className":3856,"code":15676,"language":3858,"meta":3859,"style":3859},"\u002F\u002F Поведінка виділена у окремі класи\nclass FlyingAbility {\n  fly(name: string): void {\n    console.log(`${name} літає`);\n  }\n}\n\nclass SwimmingAbility {\n  swim(name: string): void {\n    console.log(`${name} плаває`);\n  }\n}\n\nclass RunningAbility {\n  run(name: string): void {\n    console.log(`${name} біжить`);\n  }\n}\n\n\u002F\u002F Інтерфейси описують здібності\ninterface CanFly {\n  fly(): void;\n}\n\ninterface CanSwim {\n  swim(): void;\n}\n\ninterface CanRun {\n  run(): void;\n}\n\n\u002F\u002F Качка реалізує обидва інтерфейси через композицію\nclass Duck implements CanFly, CanSwim {\n  private flyingAbility = new FlyingAbility();\n  private swimmingAbility = new SwimmingAbility();\n\n  constructor(public name: string) {}\n\n  fly(): void {\n    this.flyingAbility.fly(this.name);\n  }\n\n  swim(): void {\n    this.swimmingAbility.swim(this.name);\n  }\n}\n\n\u002F\u002F Собака бігає та плаває\nclass Dog implements CanRun, CanSwim {\n  private runningAbility = new RunningAbility();\n  private swimmingAbility = new SwimmingAbility();\n\n  constructor(public name: string) {}\n\n  run(): void {\n    this.runningAbility.run(this.name);\n  }\n\n  swim(): void {\n    this.swimmingAbility.swim(this.name);\n  }\n}\n\nconst duck = new Duck('Дональд');\nduck.fly();   \u002F\u002F \"Дональд літає\"\nduck.swim();  \u002F\u002F \"Дональд плаває\"\n\nconst dog = new Dog('Рекс');\ndog.run();    \u002F\u002F \"Рекс біжить\"\ndog.swim();   \u002F\u002F \"Рекс плаває\"\n",[3753,15678,15679,15684,15693,15711,15733,15737,15741,15745,15754,15772,15794,15798,15802,15806,15815,15834,15857,15861,15865,15869,15874,15883,15893,15897,15901,15910,15920,15924,15928,15937,15947,15951,15955,15960,15979,15995,16011,16016,16033,16038,16049,16074,16079,16084,16095,16120,16125,16130,16135,16141,16158,16174,16189,16194,16211,16216,16227,16252,16257,16262,16273,16296,16301,16306,16311,16332,16348,16362,16367,16386,16401],{"__ignoreMap":3859},[3863,15680,15681],{"class":3865,"line":3866},[3863,15682,15683],{"class":4559},"\u002F\u002F Поведінка виділена у окремі класи\n",[3863,15685,15686,15688,15691],{"class":3865,"line":3921},[3863,15687,7514],{"class":3869},[3863,15689,15690],{"class":3894}," FlyingAbility",[3863,15692,3928],{"class":3877},[3863,15694,15695,15697,15699,15701,15703,15705,15707,15709],{"class":3865,"line":3931},[3863,15696,15566],{"class":3873},[3863,15698,3878],{"class":3877},[3863,15700,3888],{"class":3881},[3863,15702,3891],{"class":3877},[3863,15704,3895],{"class":3894},[3863,15706,4326],{"class":3877},[3863,15708,4898],{"class":3894},[3863,15710,3928],{"class":3877},[3863,15712,15713,15715,15717,15719,15721,15723,15725,15727,15729,15731],{"class":3865,"line":3942},[3863,15714,4986],{"class":3881},[3863,15716,3783],{"class":3877},[3863,15718,4941],{"class":3873},[3863,15720,3878],{"class":3877},[3863,15722,5006],{"class":4089},[3863,15724,4998],{"class":3869},[3863,15726,3888],{"class":3881},[3863,15728,5003],{"class":3869},[3863,15730,15591],{"class":4089},[3863,15732,5009],{"class":3877},[3863,15734,15735],{"class":3865,"line":3971},[3863,15736,5098],{"class":3877},[3863,15738,15739],{"class":3865,"line":3986},[3863,15740,3995],{"class":3877},[3863,15742,15743],{"class":3865,"line":3992},[3863,15744,4002],{"emptyLinePlaceholder":4001},[3863,15746,15747,15749,15752],{"class":3865,"line":3998},[3863,15748,7514],{"class":3869},[3863,15750,15751],{"class":3894}," SwimmingAbility",[3863,15753,3928],{"class":3877},[3863,15755,15756,15758,15760,15762,15764,15766,15768,15770],{"class":3865,"line":4005},[3863,15757,15619],{"class":3873},[3863,15759,3878],{"class":3877},[3863,15761,3888],{"class":3881},[3863,15763,3891],{"class":3877},[3863,15765,3895],{"class":3894},[3863,15767,4326],{"class":3877},[3863,15769,4898],{"class":3894},[3863,15771,3928],{"class":3877},[3863,15773,15774,15776,15778,15780,15782,15784,15786,15788,15790,15792],{"class":3865,"line":4050},[3863,15775,4986],{"class":3881},[3863,15777,3783],{"class":3877},[3863,15779,4941],{"class":3873},[3863,15781,3878],{"class":3877},[3863,15783,5006],{"class":4089},[3863,15785,4998],{"class":3869},[3863,15787,3888],{"class":3881},[3863,15789,5003],{"class":3869},[3863,15791,15644],{"class":4089},[3863,15793,5009],{"class":3877},[3863,15795,15796],{"class":3865,"line":4111},[3863,15797,5098],{"class":3877},[3863,15799,15800],{"class":3865,"line":4482},[3863,15801,3995],{"class":3877},[3863,15803,15804],{"class":3865,"line":4487},[3863,15805,4002],{"emptyLinePlaceholder":4001},[3863,15807,15808,15810,15813],{"class":3865,"line":4505},[3863,15809,7514],{"class":3869},[3863,15811,15812],{"class":3894}," RunningAbility",[3863,15814,3928],{"class":3877},[3863,15816,15817,15820,15822,15824,15826,15828,15830,15832],{"class":3865,"line":4517},[3863,15818,15819],{"class":3873},"  run",[3863,15821,3878],{"class":3877},[3863,15823,3888],{"class":3881},[3863,15825,3891],{"class":3877},[3863,15827,3895],{"class":3894},[3863,15829,4326],{"class":3877},[3863,15831,4898],{"class":3894},[3863,15833,3928],{"class":3877},[3863,15835,15836,15838,15840,15842,15844,15846,15848,15850,15852,15855],{"class":3865,"line":4528},[3863,15837,4986],{"class":3881},[3863,15839,3783],{"class":3877},[3863,15841,4941],{"class":3873},[3863,15843,3878],{"class":3877},[3863,15845,5006],{"class":4089},[3863,15847,4998],{"class":3869},[3863,15849,3888],{"class":3881},[3863,15851,5003],{"class":3869},[3863,15853,15854],{"class":4089}," біжить`",[3863,15856,5009],{"class":3877},[3863,15858,15859],{"class":3865,"line":4540},[3863,15860,5098],{"class":3877},[3863,15862,15863],{"class":3865,"line":6647},[3863,15864,3995],{"class":3877},[3863,15866,15867],{"class":3865,"line":6658},[3863,15868,4002],{"emptyLinePlaceholder":4001},[3863,15870,15871],{"class":3865,"line":6667},[3863,15872,15873],{"class":4559},"\u002F\u002F Інтерфейси описують здібності\n",[3863,15875,15876,15878,15881],{"class":3865,"line":6918},[3863,15877,3755],{"class":3869},[3863,15879,15880],{"class":3894}," CanFly",[3863,15882,3928],{"class":3877},[3863,15884,15885,15887,15889,15891],{"class":3865,"line":6957},[3863,15886,15566],{"class":3873},[3863,15888,5715],{"class":3877},[3863,15890,4898],{"class":3894},[3863,15892,4108],{"class":3877},[3863,15894,15895],{"class":3865,"line":6962},[3863,15896,3995],{"class":3877},[3863,15898,15899],{"class":3865,"line":7489},[3863,15900,4002],{"emptyLinePlaceholder":4001},[3863,15902,15903,15905,15908],{"class":3865,"line":7495},[3863,15904,3755],{"class":3869},[3863,15906,15907],{"class":3894}," CanSwim",[3863,15909,3928],{"class":3877},[3863,15911,15912,15914,15916,15918],{"class":3865,"line":7501},[3863,15913,15619],{"class":3873},[3863,15915,5715],{"class":3877},[3863,15917,4898],{"class":3894},[3863,15919,4108],{"class":3877},[3863,15921,15922],{"class":3865,"line":10312},[3863,15923,3995],{"class":3877},[3863,15925,15926],{"class":3865,"line":10333},[3863,15927,4002],{"emptyLinePlaceholder":4001},[3863,15929,15930,15932,15935],{"class":3865,"line":10350},[3863,15931,3755],{"class":3869},[3863,15933,15934],{"class":3894}," CanRun",[3863,15936,3928],{"class":3877},[3863,15938,15939,15941,15943,15945],{"class":3865,"line":10373},[3863,15940,15819],{"class":3873},[3863,15942,5715],{"class":3877},[3863,15944,4898],{"class":3894},[3863,15946,4108],{"class":3877},[3863,15948,15949],{"class":3865,"line":10378},[3863,15950,3995],{"class":3877},[3863,15952,15953],{"class":3865,"line":14182},[3863,15954,4002],{"emptyLinePlaceholder":4001},[3863,15956,15957],{"class":3865,"line":14211},[3863,15958,15959],{"class":4559},"\u002F\u002F Качка реалізує обидва інтерфейси через композицію\n",[3863,15961,15963,15965,15968,15970,15972,15974,15977],{"class":3865,"line":15962},34,[3863,15964,7514],{"class":3869},[3863,15966,15967],{"class":3894}," Duck",[3863,15969,12636],{"class":3869},[3863,15971,15880],{"class":3894},[3863,15973,3776],{"class":3877},[3863,15975,15976],{"class":3894},"CanSwim",[3863,15978,3928],{"class":3877},[3863,15980,15982,15984,15987,15989,15991,15993],{"class":3865,"line":15981},35,[3863,15983,10066],{"class":3869},[3863,15985,15986],{"class":3881}," flyingAbility",[3863,15988,4167],{"class":3877},[3863,15990,7639],{"class":3869},[3863,15992,15690],{"class":3873},[3863,15994,9154],{"class":3877},[3863,15996,15998,16000,16003,16005,16007,16009],{"class":3865,"line":15997},36,[3863,15999,10066],{"class":3869},[3863,16001,16002],{"class":3881}," swimmingAbility",[3863,16004,4167],{"class":3877},[3863,16006,7639],{"class":3869},[3863,16008,15751],{"class":3873},[3863,16010,9154],{"class":3877},[3863,16012,16014],{"class":3865,"line":16013},37,[3863,16015,4002],{"emptyLinePlaceholder":4001},[3863,16017,16019,16021,16023,16025,16027,16029,16031],{"class":3865,"line":16018},38,[3863,16020,7827],{"class":3869},[3863,16022,3878],{"class":3877},[3863,16024,3775],{"class":3869},[3863,16026,8591],{"class":3881},[3863,16028,3891],{"class":3877},[3863,16030,3895],{"class":3894},[3863,16032,8888],{"class":3877},[3863,16034,16036],{"class":3865,"line":16035},39,[3863,16037,4002],{"emptyLinePlaceholder":4001},[3863,16039,16041,16043,16045,16047],{"class":3865,"line":16040},40,[3863,16042,15566],{"class":3873},[3863,16044,5715],{"class":3877},[3863,16046,4898],{"class":3894},[3863,16048,3928],{"class":3877},[3863,16050,16052,16054,16056,16059,16061,16064,16066,16068,16070,16072],{"class":3865,"line":16051},41,[3863,16053,7842],{"class":3869},[3863,16055,3783],{"class":3877},[3863,16057,16058],{"class":3881},"flyingAbility",[3863,16060,3783],{"class":3877},[3863,16062,16063],{"class":3873},"fly",[3863,16065,3878],{"class":3877},[3863,16067,6885],{"class":3869},[3863,16069,3783],{"class":3877},[3863,16071,3888],{"class":3881},[3863,16073,5009],{"class":3877},[3863,16075,16077],{"class":3865,"line":16076},42,[3863,16078,5098],{"class":3877},[3863,16080,16082],{"class":3865,"line":16081},43,[3863,16083,4002],{"emptyLinePlaceholder":4001},[3863,16085,16087,16089,16091,16093],{"class":3865,"line":16086},44,[3863,16088,15619],{"class":3873},[3863,16090,5715],{"class":3877},[3863,16092,4898],{"class":3894},[3863,16094,3928],{"class":3877},[3863,16096,16098,16100,16102,16105,16107,16110,16112,16114,16116,16118],{"class":3865,"line":16097},45,[3863,16099,7842],{"class":3869},[3863,16101,3783],{"class":3877},[3863,16103,16104],{"class":3881},"swimmingAbility",[3863,16106,3783],{"class":3877},[3863,16108,16109],{"class":3873},"swim",[3863,16111,3878],{"class":3877},[3863,16113,6885],{"class":3869},[3863,16115,3783],{"class":3877},[3863,16117,3888],{"class":3881},[3863,16119,5009],{"class":3877},[3863,16121,16123],{"class":3865,"line":16122},46,[3863,16124,5098],{"class":3877},[3863,16126,16128],{"class":3865,"line":16127},47,[3863,16129,3995],{"class":3877},[3863,16131,16133],{"class":3865,"line":16132},48,[3863,16134,4002],{"emptyLinePlaceholder":4001},[3863,16136,16138],{"class":3865,"line":16137},49,[3863,16139,16140],{"class":4559},"\u002F\u002F Собака бігає та плаває\n",[3863,16142,16144,16146,16148,16150,16152,16154,16156],{"class":3865,"line":16143},50,[3863,16145,7514],{"class":3869},[3863,16147,5689],{"class":3894},[3863,16149,12636],{"class":3869},[3863,16151,15934],{"class":3894},[3863,16153,3776],{"class":3877},[3863,16155,15976],{"class":3894},[3863,16157,3928],{"class":3877},[3863,16159,16161,16163,16166,16168,16170,16172],{"class":3865,"line":16160},51,[3863,16162,10066],{"class":3869},[3863,16164,16165],{"class":3881}," runningAbility",[3863,16167,4167],{"class":3877},[3863,16169,7639],{"class":3869},[3863,16171,15812],{"class":3873},[3863,16173,9154],{"class":3877},[3863,16175,16177,16179,16181,16183,16185,16187],{"class":3865,"line":16176},52,[3863,16178,10066],{"class":3869},[3863,16180,16002],{"class":3881},[3863,16182,4167],{"class":3877},[3863,16184,7639],{"class":3869},[3863,16186,15751],{"class":3873},[3863,16188,9154],{"class":3877},[3863,16190,16192],{"class":3865,"line":16191},53,[3863,16193,4002],{"emptyLinePlaceholder":4001},[3863,16195,16197,16199,16201,16203,16205,16207,16209],{"class":3865,"line":16196},54,[3863,16198,7827],{"class":3869},[3863,16200,3878],{"class":3877},[3863,16202,3775],{"class":3869},[3863,16204,8591],{"class":3881},[3863,16206,3891],{"class":3877},[3863,16208,3895],{"class":3894},[3863,16210,8888],{"class":3877},[3863,16212,16214],{"class":3865,"line":16213},55,[3863,16215,4002],{"emptyLinePlaceholder":4001},[3863,16217,16219,16221,16223,16225],{"class":3865,"line":16218},56,[3863,16220,15819],{"class":3873},[3863,16222,5715],{"class":3877},[3863,16224,4898],{"class":3894},[3863,16226,3928],{"class":3877},[3863,16228,16230,16232,16234,16237,16239,16242,16244,16246,16248,16250],{"class":3865,"line":16229},57,[3863,16231,7842],{"class":3869},[3863,16233,3783],{"class":3877},[3863,16235,16236],{"class":3881},"runningAbility",[3863,16238,3783],{"class":3877},[3863,16240,16241],{"class":3873},"run",[3863,16243,3878],{"class":3877},[3863,16245,6885],{"class":3869},[3863,16247,3783],{"class":3877},[3863,16249,3888],{"class":3881},[3863,16251,5009],{"class":3877},[3863,16253,16255],{"class":3865,"line":16254},58,[3863,16256,5098],{"class":3877},[3863,16258,16260],{"class":3865,"line":16259},59,[3863,16261,4002],{"emptyLinePlaceholder":4001},[3863,16263,16265,16267,16269,16271],{"class":3865,"line":16264},60,[3863,16266,15619],{"class":3873},[3863,16268,5715],{"class":3877},[3863,16270,4898],{"class":3894},[3863,16272,3928],{"class":3877},[3863,16274,16276,16278,16280,16282,16284,16286,16288,16290,16292,16294],{"class":3865,"line":16275},61,[3863,16277,7842],{"class":3869},[3863,16279,3783],{"class":3877},[3863,16281,16104],{"class":3881},[3863,16283,3783],{"class":3877},[3863,16285,16109],{"class":3873},[3863,16287,3878],{"class":3877},[3863,16289,6885],{"class":3869},[3863,16291,3783],{"class":3877},[3863,16293,3888],{"class":3881},[3863,16295,5009],{"class":3877},[3863,16297,16299],{"class":3865,"line":16298},62,[3863,16300,5098],{"class":3877},[3863,16302,16304],{"class":3865,"line":16303},63,[3863,16305,3995],{"class":3877},[3863,16307,16309],{"class":3865,"line":16308},64,[3863,16310,4002],{"emptyLinePlaceholder":4001},[3863,16312,16314,16316,16319,16321,16323,16325,16327,16330],{"class":3865,"line":16313},65,[3863,16315,4490],{"class":3869},[3863,16317,16318],{"class":4493}," duck",[3863,16320,4167],{"class":3877},[3863,16322,7639],{"class":3869},[3863,16324,15967],{"class":3873},[3863,16326,3878],{"class":3877},[3863,16328,16329],{"class":4089},"'Дональд'",[3863,16331,5009],{"class":3877},[3863,16333,16335,16338,16340,16342,16345],{"class":3865,"line":16334},66,[3863,16336,16337],{"class":3881},"duck",[3863,16339,3783],{"class":3877},[3863,16341,16063],{"class":3873},[3863,16343,16344],{"class":3877},"();   ",[3863,16346,16347],{"class":4559},"\u002F\u002F \"Дональд літає\"\n",[3863,16349,16351,16353,16355,16357,16359],{"class":3865,"line":16350},67,[3863,16352,16337],{"class":3881},[3863,16354,3783],{"class":3877},[3863,16356,16109],{"class":3873},[3863,16358,10747],{"class":3877},[3863,16360,16361],{"class":4559},"\u002F\u002F \"Дональд плаває\"\n",[3863,16363,16365],{"class":3865,"line":16364},68,[3863,16366,4002],{"emptyLinePlaceholder":4001},[3863,16368,16370,16372,16374,16376,16378,16380,16382,16384],{"class":3865,"line":16369},69,[3863,16371,4490],{"class":3869},[3863,16373,7092],{"class":4493},[3863,16375,4167],{"class":3877},[3863,16377,7639],{"class":3869},[3863,16379,5689],{"class":3873},[3863,16381,3878],{"class":3877},[3863,16383,10779],{"class":4089},[3863,16385,5009],{"class":3877},[3863,16387,16389,16391,16393,16395,16398],{"class":3865,"line":16388},70,[3863,16390,10786],{"class":3881},[3863,16392,3783],{"class":3877},[3863,16394,16241],{"class":3873},[3863,16396,16397],{"class":3877},"();    ",[3863,16399,16400],{"class":4559},"\u002F\u002F \"Рекс біжить\"\n",[3863,16402,16404,16406,16408,16410,16412],{"class":3865,"line":16403},71,[3863,16405,10786],{"class":3881},[3863,16407,3783],{"class":3877},[3863,16409,16109],{"class":3873},[3863,16411,16344],{"class":3877},[3863,16413,16414],{"class":4559},"\u002F\u002F \"Рекс плаває\"\n",[3846,16416,16417],{},"Переваги композиції:",[3746,16419,16420,16426,16439,16448],{},[3749,16421,16422,16425],{},[3796,16423,16424],{},"Гнучкість:"," Легко комбінувати різні здібності без обмежень множинного наслідування.",[3749,16427,16428,16431,16432,3776,16435,16438],{},[3796,16429,16430],{},"Повторне використання:"," Класи ",[3753,16433,16434],{},"FlyingAbility",[3753,16436,16437],{},"SwimmingAbility"," можна використовувати у різних тваринах.",[3749,16440,16441,16444,16445,16447],{},[3796,16442,16443],{},"Слабке зв'язування:"," Зміна реалізації ",[3753,16446,16437],{}," не впливає на ієрархію класів тварин.",[3749,16449,16450,16453],{},[3796,16451,16452],{},"Тестованість:"," Можна тестувати кожну здібність окремо та легко підміняти реалізації через мок-об'єкти.",[4845,16455,16456,16459,16460,16463,16464,16467],{},[3796,16457,16458],{},"Принцип \"Favor composition over inheritance\""," (віддавай перевагу композиції перед наслідуванням) — один із ключових порад у об'єктно-орієнтованому проєктуванні. Використовуйте наслідування для моделювання ",[3796,16461,16462],{},"IS-A"," зв'язків (Собака IS-A Тварина), а композицію — для ",[3796,16465,16466],{},"HAS-A"," зв'язків (Качка HAS-A здібність літати).",[3838,16469],{},[3841,16471,16473],{"id":16472},"structural-typing-качина-типізація-у-класах","Structural typing: \"качина типізація\" у класах",[3846,16475,16476,16477,4227,16480,16483,16484,4227,16487,16490,16491,16494],{},"TypeScript використовує ",[3796,16478,16479],{},"structural typing",[4229,16481,16482],{},"структурну типізацію","), а не ",[3796,16485,16486],{},"nominal typing",[4229,16488,16489],{},"номінальну типізацію","). Це означає, що сумісність типів визначається ",[3796,16492,16493],{},"структурою об'єкта"," (які поля та методи він має), а не назвою класу або явним оголошенням реалізації інтерфейсу.",[4237,16496,16498],{"id":16497},"приклад-структурної-типізації","Приклад структурної типізації",[3854,16500,16502],{"className":3856,"code":16501,"language":3858,"meta":3859,"style":3859},"interface Point {\n  x: number;\n  y: number;\n}\n\nclass Vector {\n  constructor(public x: number, public y: number) {}\n}\n\nfunction printPoint(p: Point): void {\n  console.log(`Координати: (${p.x}, ${p.y})`);\n}\n\nconst vector = new Vector(10, 20);\nprintPoint(vector);  \u002F\u002F ✅ OK: Vector має поля x та y, тому сумісний з Point\n",[3753,16503,16504,16512,16522,16532,16536,16540,16549,16577,16581,16585,16607,16646,16650,16654,16677],{"__ignoreMap":3859},[3863,16505,16506,16508,16510],{"class":3865,"line":3866},[3863,16507,3755],{"class":3869},[3863,16509,4190],{"class":3894},[3863,16511,3928],{"class":3877},[3863,16513,16514,16516,16518,16520],{"class":3865,"line":3921},[3863,16515,5550],{"class":3881},[3863,16517,3891],{"class":3877},[3863,16519,3915],{"class":3894},[3863,16521,4108],{"class":3877},[3863,16523,16524,16526,16528,16530],{"class":3865,"line":3931},[3863,16525,5561],{"class":3881},[3863,16527,3891],{"class":3877},[3863,16529,3915],{"class":3894},[3863,16531,4108],{"class":3877},[3863,16533,16534],{"class":3865,"line":3942},[3863,16535,3995],{"class":3877},[3863,16537,16538],{"class":3865,"line":3971},[3863,16539,4002],{"emptyLinePlaceholder":4001},[3863,16541,16542,16544,16547],{"class":3865,"line":3986},[3863,16543,7514],{"class":3869},[3863,16545,16546],{"class":3894}," Vector",[3863,16548,3928],{"class":3877},[3863,16550,16551,16553,16555,16557,16560,16562,16564,16566,16568,16571,16573,16575],{"class":3865,"line":3992},[3863,16552,7827],{"class":3869},[3863,16554,3878],{"class":3877},[3863,16556,3775],{"class":3869},[3863,16558,16559],{"class":3881}," x",[3863,16561,3891],{"class":3877},[3863,16563,3915],{"class":3894},[3863,16565,3776],{"class":3877},[3863,16567,3775],{"class":3869},[3863,16569,16570],{"class":3881}," y",[3863,16572,3891],{"class":3877},[3863,16574,3915],{"class":3894},[3863,16576,8888],{"class":3877},[3863,16578,16579],{"class":3865,"line":3998},[3863,16580,3995],{"class":3877},[3863,16582,16583],{"class":3865,"line":4005},[3863,16584,4002],{"emptyLinePlaceholder":4001},[3863,16586,16587,16589,16592,16594,16596,16598,16601,16603,16605],{"class":3865,"line":4050},[3863,16588,3870],{"class":3869},[3863,16590,16591],{"class":3873}," printPoint",[3863,16593,3878],{"class":3877},[3863,16595,3846],{"class":3881},[3863,16597,3891],{"class":3877},[3863,16599,16600],{"class":3894},"Point",[3863,16602,4326],{"class":3877},[3863,16604,4898],{"class":3894},[3863,16606,3928],{"class":3877},[3863,16608,16609,16611,16613,16615,16617,16620,16622,16624,16626,16628,16630,16632,16634,16636,16638,16640,16642,16644],{"class":3865,"line":4111},[3863,16610,6273],{"class":3881},[3863,16612,3783],{"class":3877},[3863,16614,4941],{"class":3873},[3863,16616,3878],{"class":3877},[3863,16618,16619],{"class":4089},"`Координати: (",[3863,16621,4998],{"class":3869},[3863,16623,3846],{"class":3881},[3863,16625,3783],{"class":6289},[3863,16627,4196],{"class":3881},[3863,16629,5003],{"class":3869},[3863,16631,3776],{"class":4089},[3863,16633,4998],{"class":3869},[3863,16635,3846],{"class":3881},[3863,16637,3783],{"class":6289},[3863,16639,4205],{"class":3881},[3863,16641,5003],{"class":3869},[3863,16643,11775],{"class":4089},[3863,16645,5009],{"class":3877},[3863,16647,16648],{"class":3865,"line":4482},[3863,16649,3995],{"class":3877},[3863,16651,16652],{"class":3865,"line":4487},[3863,16653,4002],{"emptyLinePlaceholder":4001},[3863,16655,16656,16658,16661,16663,16665,16667,16669,16671,16673,16675],{"class":3865,"line":4505},[3863,16657,4490],{"class":3869},[3863,16659,16660],{"class":4493}," vector",[3863,16662,4167],{"class":3877},[3863,16664,7639],{"class":3869},[3863,16666,16546],{"class":3873},[3863,16668,3878],{"class":3877},[3863,16670,9101],{"class":3964},[3863,16672,3776],{"class":3877},[3863,16674,9456],{"class":3964},[3863,16676,5009],{"class":3877},[3863,16678,16679,16682,16684,16687,16689],{"class":3865,"line":4517},[3863,16680,16681],{"class":3873},"printPoint",[3863,16683,3878],{"class":3877},[3863,16685,16686],{"class":3881},"vector",[3863,16688,8730],{"class":3877},[3863,16690,16691],{"class":4559},"\u002F\u002F ✅ OK: Vector має поля x та y, тому сумісний з Point\n",[3846,16693,11550,16694,7780,16697,7780,16700,16703,16704,3756,16707,16710,16711,16713,16714,16716,16717,16719,16720,16722,16723,3783],{},[3753,16695,16696],{},"Vector",[3796,16698,16699],{},"не оголошує",[3753,16701,16702],{},"implements Point",", але він має поля ",[3753,16705,16706],{},"x: number",[3753,16708,16709],{},"y: number",", що відповідає структурі інтерфейсу ",[3753,16712,16600],{},". TypeScript вважає ",[3753,16715,16696],{}," сумісним з ",[3753,16718,16600],{}," і дозволяє передати екземпляр ",[3753,16721,16696],{}," у функцію, що очікує ",[3753,16724,16600],{},[3846,16726,16727],{},"Це працює і для класів:",[3854,16729,16731],{"className":3856,"code":16730,"language":3858,"meta":3859,"style":3859},"class Dog {\n  constructor(public name: string) {}\n  bark(): void { console.log('Гав!'); }\n}\n\nclass Cat {\n  constructor(public name: string) {}\n  bark(): void { console.log('Мяу... (помилка природи)'); }\n}\n\nfunction makeBark(animal: Dog): void {\n  console.log(`${animal.name} каже:`);\n  animal.bark();\n}\n\nconst cat = new Cat('Мурчик');\nmakeBark(cat);  \u002F\u002F ✅ OK: Cat має ту саму структуру, що й Dog (name: string, bark(): void)\n",[3753,16732,16733,16741,16757,16780,16784,16788,16796,16812,16835,16839,16843,16864,16891,16902,16906,16910,16928],{"__ignoreMap":3859},[3863,16734,16735,16737,16739],{"class":3865,"line":3866},[3863,16736,7514],{"class":3869},[3863,16738,5689],{"class":3894},[3863,16740,3928],{"class":3877},[3863,16742,16743,16745,16747,16749,16751,16753,16755],{"class":3865,"line":3921},[3863,16744,7827],{"class":3869},[3863,16746,3878],{"class":3877},[3863,16748,3775],{"class":3869},[3863,16750,8591],{"class":3881},[3863,16752,3891],{"class":3877},[3863,16754,3895],{"class":3894},[3863,16756,8888],{"class":3877},[3863,16758,16759,16761,16763,16765,16768,16770,16772,16774,16776,16778],{"class":3865,"line":3931},[3863,16760,5712],{"class":3873},[3863,16762,5715],{"class":3877},[3863,16764,4898],{"class":3894},[3863,16766,16767],{"class":3877}," { ",[3863,16769,5355],{"class":3881},[3863,16771,3783],{"class":3877},[3863,16773,4941],{"class":3873},[3863,16775,3878],{"class":3877},[3863,16777,5787],{"class":4089},[3863,16779,5790],{"class":3877},[3863,16781,16782],{"class":3865,"line":3942},[3863,16783,3995],{"class":3877},[3863,16785,16786],{"class":3865,"line":3971},[3863,16787,4002],{"emptyLinePlaceholder":4001},[3863,16789,16790,16792,16794],{"class":3865,"line":3986},[3863,16791,7514],{"class":3869},[3863,16793,7146],{"class":3894},[3863,16795,3928],{"class":3877},[3863,16797,16798,16800,16802,16804,16806,16808,16810],{"class":3865,"line":3992},[3863,16799,7827],{"class":3869},[3863,16801,3878],{"class":3877},[3863,16803,3775],{"class":3869},[3863,16805,8591],{"class":3881},[3863,16807,3891],{"class":3877},[3863,16809,3895],{"class":3894},[3863,16811,8888],{"class":3877},[3863,16813,16814,16816,16818,16820,16822,16824,16826,16828,16830,16833],{"class":3865,"line":3998},[3863,16815,5712],{"class":3873},[3863,16817,5715],{"class":3877},[3863,16819,4898],{"class":3894},[3863,16821,16767],{"class":3877},[3863,16823,5355],{"class":3881},[3863,16825,3783],{"class":3877},[3863,16827,4941],{"class":3873},[3863,16829,3878],{"class":3877},[3863,16831,16832],{"class":4089},"'Мяу... (помилка природи)'",[3863,16834,5790],{"class":3877},[3863,16836,16837],{"class":3865,"line":4005},[3863,16838,3995],{"class":3877},[3863,16840,16841],{"class":3865,"line":4050},[3863,16842,4002],{"emptyLinePlaceholder":4001},[3863,16844,16845,16847,16850,16852,16854,16856,16858,16860,16862],{"class":3865,"line":4111},[3863,16846,3870],{"class":3869},[3863,16848,16849],{"class":3873}," makeBark",[3863,16851,3878],{"class":3877},[3863,16853,12243],{"class":3881},[3863,16855,3891],{"class":3877},[3863,16857,5739],{"class":3894},[3863,16859,4326],{"class":3877},[3863,16861,4898],{"class":3894},[3863,16863,3928],{"class":3877},[3863,16865,16866,16868,16870,16872,16874,16876,16878,16880,16882,16884,16886,16889],{"class":3865,"line":4482},[3863,16867,6273],{"class":3881},[3863,16869,3783],{"class":3877},[3863,16871,4941],{"class":3873},[3863,16873,3878],{"class":3877},[3863,16875,5006],{"class":4089},[3863,16877,4998],{"class":3869},[3863,16879,12243],{"class":3881},[3863,16881,3783],{"class":6289},[3863,16883,3888],{"class":3881},[3863,16885,5003],{"class":3869},[3863,16887,16888],{"class":4089}," каже:`",[3863,16890,5009],{"class":3877},[3863,16892,16893,16896,16898,16900],{"class":3865,"line":4487},[3863,16894,16895],{"class":3881},"  animal",[3863,16897,3783],{"class":3877},[3863,16899,10791],{"class":3873},[3863,16901,9154],{"class":3877},[3863,16903,16904],{"class":3865,"line":4505},[3863,16905,3995],{"class":3877},[3863,16907,16908],{"class":3865,"line":4517},[3863,16909,4002],{"emptyLinePlaceholder":4001},[3863,16911,16912,16914,16916,16918,16920,16922,16924,16926],{"class":3865,"line":4528},[3863,16913,4490],{"class":3869},[3863,16915,11505],{"class":4493},[3863,16917,4167],{"class":3877},[3863,16919,7639],{"class":3869},[3863,16921,7146],{"class":3873},[3863,16923,3878],{"class":3877},[3863,16925,11516],{"class":4089},[3863,16927,5009],{"class":3877},[3863,16929,16930,16933,16935,16937,16939],{"class":3865,"line":4540},[3863,16931,16932],{"class":3873},"makeBark",[3863,16934,3878],{"class":3877},[3863,16936,11523],{"class":3881},[3863,16938,8730],{"class":3877},[3863,16940,16941],{"class":4559},"\u002F\u002F ✅ OK: Cat має ту саму структуру, що й Dog (name: string, bark(): void)\n",[3846,16943,16944,16945,16947,16948,16950,16951,4227,16954,16957],{},"З точки зору TypeScript, ",[3753,16946,7200],{}," структурно еквівалентний ",[3753,16949,5739],{},", тому їх можна підставляти один замість одного. Це ",[3796,16952,16953],{},"\"качина типізація\"",[4229,16955,16956],{},"duck typing","): \"якщо щось виглядає як качка, плаває як качка та крякає як качка, то це качка\".",[4145,16959,16960,16966,17066],{},[3846,16961,16962,16965],{},[3796,16963,16964],{},"Відмінність від номінальної типізації:"," У мовах з номінальною типізацією (Java, C#) два класи з ідентичною структурою все одно вважаються різними типами, якщо оголошені окремо:",[3854,16967,16971],{"className":16968,"code":16969,"language":16970,"meta":3859,"style":3859},"language-java shiki shiki-themes light-plus dark-plus dark-plus","\u002F\u002F Java\nclass Dog { String name; void bark() {} }\nclass Cat { String name; void bark() {} }\n\nvoid makeBark(Dog dog) { dog.bark(); }\nCat cat = new Cat();\n\u002F\u002F makeBark(cat);  \u002F\u002F ❌ Compile Error: Cat is not a Dog\n","java",[3753,16972,16973,16978,17000,17018,17022,17044,17058],{"__ignoreMap":3859},[3863,16974,16975],{"class":3865,"line":3866},[3863,16976,16977],{"class":4559},"\u002F\u002F Java\n",[3863,16979,16980,16982,16984,16986,16989,16992,16994,16997],{"class":3865,"line":3921},[3863,16981,7514],{"class":3869},[3863,16983,5689],{"class":3894},[3863,16985,16767],{"class":3877},[3863,16987,16988],{"class":3894},"String",[3863,16990,16991],{"class":3877}," name; ",[3863,16993,4898],{"class":3894},[3863,16995,16996],{"class":3873}," bark",[3863,16998,16999],{"class":3877},"() {} }\n",[3863,17001,17002,17004,17006,17008,17010,17012,17014,17016],{"class":3865,"line":3931},[3863,17003,7514],{"class":3869},[3863,17005,7146],{"class":3894},[3863,17007,16767],{"class":3877},[3863,17009,16988],{"class":3894},[3863,17011,16991],{"class":3877},[3863,17013,4898],{"class":3894},[3863,17015,16996],{"class":3873},[3863,17017,16999],{"class":3877},[3863,17019,17020],{"class":3865,"line":3942},[3863,17021,4002],{"emptyLinePlaceholder":4001},[3863,17023,17024,17026,17028,17030,17032,17035,17037,17039,17041],{"class":3865,"line":3971},[3863,17025,4898],{"class":3894},[3863,17027,16849],{"class":3873},[3863,17029,3878],{"class":3877},[3863,17031,5739],{"class":3894},[3863,17033,17034],{"class":3877}," dog) { ",[3863,17036,10786],{"class":3881},[3863,17038,3783],{"class":3877},[3863,17040,10791],{"class":3873},[3863,17042,17043],{"class":3877},"(); }\n",[3863,17045,17046,17048,17050,17052,17054,17056],{"class":3865,"line":3986},[3863,17047,7200],{"class":3894},[3863,17049,11505],{"class":3881},[3863,17051,4167],{"class":3877},[3863,17053,7639],{"class":3924},[3863,17055,7146],{"class":3873},[3863,17057,9154],{"class":3877},[3863,17059,17060,17063],{"class":3865,"line":3992},[3863,17061,17062],{"class":4559},"\u002F\u002F makeBark(cat);",[3863,17064,17065],{"class":4559},"  \u002F\u002F ❌ Compile Error: Cat is not a Dog\n",[3846,17067,17068],{},"TypeScript не робить таких обмежень: якщо структури сумісні, типи сумісні. Це робить код гнучкішим, але іноді може призвести до неочевидних помилок, коли два концептуально різні класи мають однакову структуру випадково.",[4237,17070,17072],{"id":17071},"nominal-typing-через-приватні-поля-brand-types","Nominal typing через приватні поля (Brand Types)",[3846,17074,17075,17076,17079],{},"Якщо потрібна номінальна типізація (розрізнення типів за назвою, а не структурою), можна використати техніку ",[3796,17077,17078],{},"brand types"," через приватні поля:",[3854,17081,17083],{"className":3856,"code":17082,"language":3858,"meta":3859,"style":3859},"class UserId {\n  private readonly __brand = 'UserId';\n  constructor(public value: string) {}\n}\n\nclass ProductId {\n  private readonly __brand = 'ProductId';\n  constructor(public value: string) {}\n}\n\nfunction getUserById(id: UserId): void {\n  console.log(`Шукаємо користувача ${id.value}`);\n}\n\nconst userId = new UserId('user-123');\nconst productId = new ProductId('prod-456');\n\ngetUserById(userId);     \u002F\u002F ✅ OK\n\u002F\u002F getUserById(productId);  \u002F\u002F ❌ Error: ProductId не сумісний з UserId через різні приватні поля\n",[3753,17084,17085,17094,17110,17126,17130,17134,17143,17158,17174,17178,17182,17204,17231,17235,17239,17258,17278,17282,17297],{"__ignoreMap":3859},[3863,17086,17087,17089,17092],{"class":3865,"line":3866},[3863,17088,7514],{"class":3869},[3863,17090,17091],{"class":3894}," UserId",[3863,17093,3928],{"class":3877},[3863,17095,17096,17098,17100,17103,17105,17108],{"class":3865,"line":3921},[3863,17097,10066],{"class":3869},[3863,17099,8776],{"class":3869},[3863,17101,17102],{"class":3881}," __brand",[3863,17104,4167],{"class":3877},[3863,17106,17107],{"class":4089},"'UserId'",[3863,17109,4108],{"class":3877},[3863,17111,17112,17114,17116,17118,17120,17122,17124],{"class":3865,"line":3931},[3863,17113,7827],{"class":3869},[3863,17115,3878],{"class":3877},[3863,17117,3775],{"class":3869},[3863,17119,8877],{"class":3881},[3863,17121,3891],{"class":3877},[3863,17123,3895],{"class":3894},[3863,17125,8888],{"class":3877},[3863,17127,17128],{"class":3865,"line":3942},[3863,17129,3995],{"class":3877},[3863,17131,17132],{"class":3865,"line":3971},[3863,17133,4002],{"emptyLinePlaceholder":4001},[3863,17135,17136,17138,17141],{"class":3865,"line":3986},[3863,17137,7514],{"class":3869},[3863,17139,17140],{"class":3894}," ProductId",[3863,17142,3928],{"class":3877},[3863,17144,17145,17147,17149,17151,17153,17156],{"class":3865,"line":3992},[3863,17146,10066],{"class":3869},[3863,17148,8776],{"class":3869},[3863,17150,17102],{"class":3881},[3863,17152,4167],{"class":3877},[3863,17154,17155],{"class":4089},"'ProductId'",[3863,17157,4108],{"class":3877},[3863,17159,17160,17162,17164,17166,17168,17170,17172],{"class":3865,"line":3998},[3863,17161,7827],{"class":3869},[3863,17163,3878],{"class":3877},[3863,17165,3775],{"class":3869},[3863,17167,8877],{"class":3881},[3863,17169,3891],{"class":3877},[3863,17171,3895],{"class":3894},[3863,17173,8888],{"class":3877},[3863,17175,17176],{"class":3865,"line":4005},[3863,17177,3995],{"class":3877},[3863,17179,17180],{"class":3865,"line":4050},[3863,17181,4002],{"emptyLinePlaceholder":4001},[3863,17183,17184,17186,17189,17191,17193,17195,17198,17200,17202],{"class":3865,"line":4111},[3863,17185,3870],{"class":3869},[3863,17187,17188],{"class":3873}," getUserById",[3863,17190,3878],{"class":3877},[3863,17192,4334],{"class":3881},[3863,17194,3891],{"class":3877},[3863,17196,17197],{"class":3894},"UserId",[3863,17199,4326],{"class":3877},[3863,17201,4898],{"class":3894},[3863,17203,3928],{"class":3877},[3863,17205,17206,17208,17210,17212,17214,17217,17219,17221,17223,17225,17227,17229],{"class":3865,"line":4482},[3863,17207,6273],{"class":3881},[3863,17209,3783],{"class":3877},[3863,17211,4941],{"class":3873},[3863,17213,3878],{"class":3877},[3863,17215,17216],{"class":4089},"`Шукаємо користувача ",[3863,17218,4998],{"class":3869},[3863,17220,4334],{"class":3881},[3863,17222,3783],{"class":6289},[3863,17224,8922],{"class":3881},[3863,17226,5003],{"class":3869},[3863,17228,5006],{"class":4089},[3863,17230,5009],{"class":3877},[3863,17232,17233],{"class":3865,"line":4487},[3863,17234,3995],{"class":3877},[3863,17236,17237],{"class":3865,"line":4505},[3863,17238,4002],{"emptyLinePlaceholder":4001},[3863,17240,17241,17243,17246,17248,17250,17252,17254,17256],{"class":3865,"line":4517},[3863,17242,4490],{"class":3869},[3863,17244,17245],{"class":4493}," userId",[3863,17247,4167],{"class":3877},[3863,17249,7639],{"class":3869},[3863,17251,17091],{"class":3873},[3863,17253,3878],{"class":3877},[3863,17255,11037],{"class":4089},[3863,17257,5009],{"class":3877},[3863,17259,17260,17262,17265,17267,17269,17271,17273,17276],{"class":3865,"line":4528},[3863,17261,4490],{"class":3869},[3863,17263,17264],{"class":4493}," productId",[3863,17266,4167],{"class":3877},[3863,17268,7639],{"class":3869},[3863,17270,17140],{"class":3873},[3863,17272,3878],{"class":3877},[3863,17274,17275],{"class":4089},"'prod-456'",[3863,17277,5009],{"class":3877},[3863,17279,17280],{"class":3865,"line":4540},[3863,17281,4002],{"emptyLinePlaceholder":4001},[3863,17283,17284,17287,17289,17292,17295],{"class":3865,"line":6647},[3863,17285,17286],{"class":3873},"getUserById",[3863,17288,3878],{"class":3877},[3863,17290,17291],{"class":3881},"userId",[3863,17293,17294],{"class":3877},");     ",[3863,17296,5397],{"class":4559},[3863,17298,17299,17302],{"class":3865,"line":6658},[3863,17300,17301],{"class":4559},"\u002F\u002F getUserById(productId);",[3863,17303,17304],{"class":4559},"  \u002F\u002F ❌ Error: ProductId не сумісний з UserId через різні приватні поля\n",[3846,17306,17307,17308,17311,17312,3756,17314,17317,17318,17321],{},"Приватне поле ",[3753,17309,17310],{},"__brand"," робить структури ",[3753,17313,17197],{},[3753,17315,17316],{},"ProductId"," різними, навіть якщо обидва мають лише ",[3753,17319,17320],{},"value: string",". TypeScript тепер розрізняє ці типи і не дозволяє підставляти один замість іншого.",[6447,17323,17324,17325,6684,17327,17330],{},"Ця техніка використовується рідко і лише тоді, коли необхідна жорстка диференціація типів (наприклад, для ідентифікаторів різних сутностей, щоб запобігти плутанині ",[3753,17326,17197],{},[3753,17328,17329],{},"OrderId"," на рівні типів).",[3838,17332],{},[3841,17334,17336],{"id":17335},"практичний-кейс-моделювання-доменної-логіки","Практичний кейс: моделювання доменної логіки",[3846,17338,17339],{},"Розглянемо практичний приклад моделювання системи управління курсами (e-learning платформа) з використанням інтерфейсів, класів, наслідування та композиції.",[4237,17341,17343],{"id":17342},"вимоги","Вимоги",[3746,17345,17346,17352,17358,17364,17370],{},[3749,17347,17348,17351],{},[3796,17349,17350],{},"Користувачі:"," можуть бути студентами або викладачами.",[3749,17353,17354,17357],{},[3796,17355,17356],{},"Курси:"," мають назву, опис, викладача та список студентів.",[3749,17359,17360,17363],{},[3796,17361,17362],{},"Студент:"," може записатися на курс, переглянути свої курси.",[3749,17365,17366,17369],{},[3796,17367,17368],{},"Викладач:"," може створити курс, додати матеріали.",[3749,17371,17372,17375],{},[3796,17373,17374],{},"Всі користувачі:"," мають email, ім'я та можуть оновлювати профіль.",[4237,17377,17379],{"id":17378},"реалізація","Реалізація",[3854,17381,17383],{"className":3856,"code":17382,"language":3858,"meta":3859,"style":3859},"\u002F\u002F Базовий інтерфейс для всіх користувачів\ninterface User {\n  readonly id: string;\n  name: string;\n  email: string;\n  updateProfile(name: string, email: string): void;\n}\n\n\u002F\u002F Абстрактний базовий клас\nabstract class BaseUser implements User {\n  constructor(\n    public readonly id: string,\n    public name: string,\n    public email: string\n  ) {}\n\n  updateProfile(name: string, email: string): void {\n    if (name.length === 0 || !email.includes('@')) {\n      throw new Error('Некоректні дані профілю');\n    }\n    this.name = name;\n    this.email = email;\n  }\n\n  abstract getUserType(): string;  \u002F\u002F кожен тип користувача має визначити свій тип\n}\n\n\u002F\u002F Клас Student\nclass Student extends BaseUser {\n  private enrolledCourses: Course[] = [];\n\n  enrollInCourse(course: Course): void {\n    if (!this.enrolledCourses.includes(course)) {\n      this.enrolledCourses.push(course);\n      course.addStudent(this);\n      console.log(`${this.name} записався на курс \"${course.title}\"`);\n    }\n  }\n\n  getCourses(): Course[] {\n    return [...this.enrolledCourses];  \u002F\u002F повертаємо копію масиву\n  }\n\n  getUserType(): string {\n    return 'Student';\n  }\n}\n\n\u002F\u002F Клас Instructor\nclass Instructor extends BaseUser {\n  private createdCourses: Course[] = [];\n\n  createCourse(title: string, description: string): Course {\n    const course = new Course(\n      `course-${Math.random().toString(36).substring(2, 9)}`,\n      title,\n      description,\n      this\n    );\n    this.createdCourses.push(course);\n    console.log(`${this.name} створив курс \"${course.title}\"`);\n    return course;\n  }\n\n  getCourses(): Course[] {\n    return [...this.createdCourses];\n  }\n\n  getUserType(): string {\n    return 'Instructor';\n  }\n}\n\n\u002F\u002F Клас Course\nclass Course {\n  private students: Student[] = [];\n\n  constructor(\n    public readonly id: string,\n    public title: string,\n    public description: string,\n    public instructor: Instructor\n  ) {}\n\n  addStudent(student: Student): void {\n    if (!this.students.includes(student)) {\n      this.students.push(student);\n    }\n  }\n\n  getStudents(): Student[] {\n    return [...this.students];\n  }\n\n  getInfo(): string {\n    return `Курс: ${this.title}\\nВикладач: ${this.instructor.name}\\nСтудентів: ${this.students.length}`;\n  }\n}\n\n\u002F\u002F Використання\nconst instructor = new Instructor('inst-001', 'Олександр Петренко', 'petro@university.edu');\nconst student1 = new Student('stud-001', 'Марія Коваленко', 'maria@student.edu');\nconst student2 = new Student('stud-002', 'Іван Шевченко', 'ivan@student.edu');\n\nconst typescriptCourse = instructor.createCourse(\n  'TypeScript Fundamentals',\n  'Вступ до TypeScript: типи, класи, інтерфейси'\n);\n\nstudent1.enrollInCourse(typescriptCourse);\nstudent2.enrollInCourse(typescriptCourse);\n\nconsole.log(typescriptCourse.getInfo());\n\u002F\u002F Курс: TypeScript Fundamentals\n\u002F\u002F Викладач: Олександр Петренко\n\u002F\u002F Студентів: 2\n\nconsole.log(`Курси студента ${student1.name}:`);\nstudent1.getCourses().forEach(course => console.log(`- ${course.title}`));\n\u002F\u002F Курси студента Марія Коваленко:\n\u002F\u002F - TypeScript Fundamentals\n",[3753,17384,17385,17390,17398,17410,17420,17430,17457,17461,17465,17470,17485,17491,17505,17517,17527,17531,17535,17561,17594,17609,17613,17627,17641,17645,17649,17665,17669,17673,17678,17691,17706,17710,17730,17753,17772,17788,17829,17833,17837,17841,17853,17872,17876,17880,17891,17900,17904,17908,17912,17917,17930,17943,17947,17975,17991,18032,18039,18046,18051,18056,18075,18114,18122,18126,18130,18140,18154,18158,18162,18172,18181,18185,18190,18195,18201,18210,18225,18230,18237,18252,18265,18279,18292,18297,18302,18323,18347,18366,18371,18376,18381,18393,18408,18413,18418,18429,18492,18497,18502,18507,18513,18543,18574,18605,18610,18629,18637,18643,18648,18653,18671,18687,18692,18711,18717,18723,18729,18734,18763,18809,18815],{"__ignoreMap":3859},[3863,17386,17387],{"class":3865,"line":3866},[3863,17388,17389],{"class":4559},"\u002F\u002F Базовий інтерфейс для всіх користувачів\n",[3863,17391,17392,17394,17396],{"class":3865,"line":3921},[3863,17393,3755],{"class":3869},[3863,17395,4258],{"class":3894},[3863,17397,3928],{"class":3877},[3863,17399,17400,17402,17404,17406,17408],{"class":3865,"line":3931},[3863,17401,4690],{"class":3869},[3863,17403,4693],{"class":3881},[3863,17405,3891],{"class":3877},[3863,17407,3895],{"class":3894},[3863,17409,4108],{"class":3877},[3863,17411,17412,17414,17416,17418],{"class":3865,"line":3942},[3863,17413,4265],{"class":3881},[3863,17415,3891],{"class":3877},[3863,17417,3895],{"class":3894},[3863,17419,4108],{"class":3877},[3863,17421,17422,17424,17426,17428],{"class":3865,"line":3971},[3863,17423,4276],{"class":3881},[3863,17425,3891],{"class":3877},[3863,17427,3895],{"class":3894},[3863,17429,4108],{"class":3877},[3863,17431,17432,17435,17437,17439,17441,17443,17445,17447,17449,17451,17453,17455],{"class":3865,"line":3986},[3863,17433,17434],{"class":3873},"  updateProfile",[3863,17436,3878],{"class":3877},[3863,17438,3888],{"class":3881},[3863,17440,3891],{"class":3877},[3863,17442,3895],{"class":3894},[3863,17444,3776],{"class":3877},[3863,17446,3901],{"class":3881},[3863,17448,3891],{"class":3877},[3863,17450,3895],{"class":3894},[3863,17452,4326],{"class":3877},[3863,17454,4898],{"class":3894},[3863,17456,4108],{"class":3877},[3863,17458,17459],{"class":3865,"line":3992},[3863,17460,3995],{"class":3877},[3863,17462,17463],{"class":3865,"line":3998},[3863,17464,4002],{"emptyLinePlaceholder":4001},[3863,17466,17467],{"class":3865,"line":4005},[3863,17468,17469],{"class":4559},"\u002F\u002F Абстрактний базовий клас\n",[3863,17471,17472,17474,17476,17479,17481,17483],{"class":3865,"line":4050},[3863,17473,13664],{"class":3869},[3863,17475,13676],{"class":3869},[3863,17477,17478],{"class":3894}," BaseUser",[3863,17480,12636],{"class":3869},[3863,17482,4258],{"class":3894},[3863,17484,3928],{"class":3877},[3863,17486,17487,17489],{"class":3865,"line":4111},[3863,17488,7827],{"class":3869},[3863,17490,8583],{"class":3877},[3863,17492,17493,17495,17497,17499,17501,17503],{"class":3865,"line":4482},[3863,17494,8588],{"class":3869},[3863,17496,8776],{"class":3869},[3863,17498,4693],{"class":3881},[3863,17500,3891],{"class":3877},[3863,17502,3895],{"class":3894},[3863,17504,3939],{"class":3877},[3863,17506,17507,17509,17511,17513,17515],{"class":3865,"line":4487},[3863,17508,8588],{"class":3869},[3863,17510,8591],{"class":3881},[3863,17512,3891],{"class":3877},[3863,17514,3895],{"class":3894},[3863,17516,3939],{"class":3877},[3863,17518,17519,17521,17523,17525],{"class":3865,"line":4505},[3863,17520,8588],{"class":3869},[3863,17522,8604],{"class":3881},[3863,17524,3891],{"class":3877},[3863,17526,8828],{"class":3894},[3863,17528,17529],{"class":3865,"line":4517},[3863,17530,8833],{"class":3877},[3863,17532,17533],{"class":3865,"line":4528},[3863,17534,4002],{"emptyLinePlaceholder":4001},[3863,17536,17537,17539,17541,17543,17545,17547,17549,17551,17553,17555,17557,17559],{"class":3865,"line":4540},[3863,17538,17434],{"class":3873},[3863,17540,3878],{"class":3877},[3863,17542,3888],{"class":3881},[3863,17544,3891],{"class":3877},[3863,17546,3895],{"class":3894},[3863,17548,3776],{"class":3877},[3863,17550,3901],{"class":3881},[3863,17552,3891],{"class":3877},[3863,17554,3895],{"class":3894},[3863,17556,4326],{"class":3877},[3863,17558,4898],{"class":3894},[3863,17560,3928],{"class":3877},[3863,17562,17563,17565,17567,17569,17571,17573,17576,17578,17581,17583,17585,17587,17589,17591],{"class":3865,"line":6647},[3863,17564,10146],{"class":3924},[3863,17566,4227],{"class":3877},[3863,17568,3888],{"class":3881},[3863,17570,3783],{"class":3877},[3863,17572,4064],{"class":3881},[3863,17574,17575],{"class":3877}," === ",[3863,17577,4070],{"class":3964},[3863,17579,17580],{"class":3877}," || !",[3863,17582,3901],{"class":3881},[3863,17584,3783],{"class":3877},[3863,17586,4084],{"class":3873},[3863,17588,3878],{"class":3877},[3863,17590,4090],{"class":4089},[3863,17592,17593],{"class":3877},")) {\n",[3863,17595,17596,17598,17600,17602,17604,17607],{"class":3865,"line":6658},[3863,17597,14989],{"class":3924},[3863,17599,3977],{"class":3869},[3863,17601,14994],{"class":3873},[3863,17603,3878],{"class":3877},[3863,17605,17606],{"class":4089},"'Некоректні дані профілю'",[3863,17608,5009],{"class":3877},[3863,17610,17611],{"class":3865,"line":6667},[3863,17612,8118],{"class":3877},[3863,17614,17615,17617,17619,17621,17623,17625],{"class":3865,"line":6918},[3863,17616,7842],{"class":3869},[3863,17618,3783],{"class":3877},[3863,17620,3888],{"class":3881},[3863,17622,4167],{"class":3877},[3863,17624,3888],{"class":3881},[3863,17626,4108],{"class":3877},[3863,17628,17629,17631,17633,17635,17637,17639],{"class":3865,"line":6957},[3863,17630,7842],{"class":3869},[3863,17632,3783],{"class":3877},[3863,17634,3901],{"class":3881},[3863,17636,4167],{"class":3877},[3863,17638,3901],{"class":3881},[3863,17640,4108],{"class":3877},[3863,17642,17643],{"class":3865,"line":6962},[3863,17644,5098],{"class":3877},[3863,17646,17647],{"class":3865,"line":7489},[3863,17648,4002],{"emptyLinePlaceholder":4001},[3863,17650,17651,17653,17656,17658,17660,17662],{"class":3865,"line":7495},[3863,17652,13707],{"class":3869},[3863,17654,17655],{"class":3873}," getUserType",[3863,17657,5715],{"class":3877},[3863,17659,3895],{"class":3894},[3863,17661,5394],{"class":3877},[3863,17663,17664],{"class":4559},"\u002F\u002F кожен тип користувача має визначити свій тип\n",[3863,17666,17667],{"class":3865,"line":7501},[3863,17668,3995],{"class":3877},[3863,17670,17671],{"class":3865,"line":10312},[3863,17672,4002],{"emptyLinePlaceholder":4001},[3863,17674,17675],{"class":3865,"line":10333},[3863,17676,17677],{"class":4559},"\u002F\u002F Клас Student\n",[3863,17679,17680,17682,17685,17687,17689],{"class":3865,"line":10350},[3863,17681,7514],{"class":3869},[3863,17683,17684],{"class":3894}," Student",[3863,17686,5692],{"class":3869},[3863,17688,17478],{"class":3894},[3863,17690,3928],{"class":3877},[3863,17692,17693,17695,17698,17700,17703],{"class":3865,"line":10373},[3863,17694,10066],{"class":3869},[3863,17696,17697],{"class":3881}," enrolledCourses",[3863,17699,3891],{"class":3877},[3863,17701,17702],{"class":3894},"Course",[3863,17704,17705],{"class":3877},"[] = [];\n",[3863,17707,17708],{"class":3865,"line":10378},[3863,17709,4002],{"emptyLinePlaceholder":4001},[3863,17711,17712,17715,17717,17720,17722,17724,17726,17728],{"class":3865,"line":14182},[3863,17713,17714],{"class":3873},"  enrollInCourse",[3863,17716,3878],{"class":3877},[3863,17718,17719],{"class":3881},"course",[3863,17721,3891],{"class":3877},[3863,17723,17702],{"class":3894},[3863,17725,4326],{"class":3877},[3863,17727,4898],{"class":3894},[3863,17729,3928],{"class":3877},[3863,17731,17732,17734,17736,17738,17740,17743,17745,17747,17749,17751],{"class":3865,"line":14211},[3863,17733,10146],{"class":3924},[3863,17735,15391],{"class":3877},[3863,17737,6885],{"class":3869},[3863,17739,3783],{"class":3877},[3863,17741,17742],{"class":3881},"enrolledCourses",[3863,17744,3783],{"class":3877},[3863,17746,4084],{"class":3873},[3863,17748,3878],{"class":3877},[3863,17750,17719],{"class":3881},[3863,17752,17593],{"class":3877},[3863,17754,17755,17757,17759,17761,17763,17766,17768,17770],{"class":3865,"line":15962},[3863,17756,10161],{"class":3869},[3863,17758,3783],{"class":3877},[3863,17760,17742],{"class":3881},[3863,17762,3783],{"class":3877},[3863,17764,17765],{"class":3873},"push",[3863,17767,3878],{"class":3877},[3863,17769,17719],{"class":3881},[3863,17771,5009],{"class":3877},[3863,17773,17774,17777,17779,17782,17784,17786],{"class":3865,"line":15981},[3863,17775,17776],{"class":3881},"      course",[3863,17778,3783],{"class":3877},[3863,17780,17781],{"class":3873},"addStudent",[3863,17783,3878],{"class":3877},[3863,17785,6885],{"class":3869},[3863,17787,5009],{"class":3877},[3863,17789,17790,17792,17794,17796,17798,17800,17802,17804,17806,17808,17810,17813,17815,17817,17819,17822,17824,17827],{"class":3865,"line":15997},[3863,17791,15423],{"class":3881},[3863,17793,3783],{"class":3877},[3863,17795,4941],{"class":3873},[3863,17797,3878],{"class":3877},[3863,17799,5006],{"class":4089},[3863,17801,4998],{"class":3869},[3863,17803,6885],{"class":3869},[3863,17805,3783],{"class":6289},[3863,17807,3888],{"class":3881},[3863,17809,5003],{"class":3869},[3863,17811,17812],{"class":4089}," записався на курс \"",[3863,17814,4998],{"class":3869},[3863,17816,17719],{"class":3881},[3863,17818,3783],{"class":6289},[3863,17820,17821],{"class":3881},"title",[3863,17823,5003],{"class":3869},[3863,17825,17826],{"class":4089},"\"`",[3863,17828,5009],{"class":3877},[3863,17830,17831],{"class":3865,"line":16013},[3863,17832,8118],{"class":3877},[3863,17834,17835],{"class":3865,"line":16018},[3863,17836,5098],{"class":3877},[3863,17838,17839],{"class":3865,"line":16035},[3863,17840,4002],{"emptyLinePlaceholder":4001},[3863,17842,17843,17846,17848,17850],{"class":3865,"line":16040},[3863,17844,17845],{"class":3873},"  getCourses",[3863,17847,5715],{"class":3877},[3863,17849,17702],{"class":3894},[3863,17851,17852],{"class":3877},"[] {\n",[3863,17854,17855,17857,17860,17862,17864,17866,17869],{"class":3865,"line":16051},[3863,17856,6921],{"class":3924},[3863,17858,17859],{"class":3877}," [...",[3863,17861,6885],{"class":3869},[3863,17863,3783],{"class":3877},[3863,17865,17742],{"class":3881},[3863,17867,17868],{"class":3877},"];  ",[3863,17870,17871],{"class":4559},"\u002F\u002F повертаємо копію масиву\n",[3863,17873,17874],{"class":3865,"line":16076},[3863,17875,5098],{"class":3877},[3863,17877,17878],{"class":3865,"line":16081},[3863,17879,4002],{"emptyLinePlaceholder":4001},[3863,17881,17882,17885,17887,17889],{"class":3865,"line":16086},[3863,17883,17884],{"class":3873},"  getUserType",[3863,17886,5715],{"class":3877},[3863,17888,3895],{"class":3894},[3863,17890,3928],{"class":3877},[3863,17892,17893,17895,17898],{"class":3865,"line":16097},[3863,17894,6921],{"class":3924},[3863,17896,17897],{"class":4089}," 'Student'",[3863,17899,4108],{"class":3877},[3863,17901,17902],{"class":3865,"line":16122},[3863,17903,5098],{"class":3877},[3863,17905,17906],{"class":3865,"line":16127},[3863,17907,3995],{"class":3877},[3863,17909,17910],{"class":3865,"line":16132},[3863,17911,4002],{"emptyLinePlaceholder":4001},[3863,17913,17914],{"class":3865,"line":16137},[3863,17915,17916],{"class":4559},"\u002F\u002F Клас Instructor\n",[3863,17918,17919,17921,17924,17926,17928],{"class":3865,"line":16143},[3863,17920,7514],{"class":3869},[3863,17922,17923],{"class":3894}," Instructor",[3863,17925,5692],{"class":3869},[3863,17927,17478],{"class":3894},[3863,17929,3928],{"class":3877},[3863,17931,17932,17934,17937,17939,17941],{"class":3865,"line":16160},[3863,17933,10066],{"class":3869},[3863,17935,17936],{"class":3881}," createdCourses",[3863,17938,3891],{"class":3877},[3863,17940,17702],{"class":3894},[3863,17942,17705],{"class":3877},[3863,17944,17945],{"class":3865,"line":16176},[3863,17946,4002],{"emptyLinePlaceholder":4001},[3863,17948,17949,17952,17954,17956,17958,17960,17962,17965,17967,17969,17971,17973],{"class":3865,"line":16191},[3863,17950,17951],{"class":3873},"  createCourse",[3863,17953,3878],{"class":3877},[3863,17955,17821],{"class":3881},[3863,17957,3891],{"class":3877},[3863,17959,3895],{"class":3894},[3863,17961,3776],{"class":3877},[3863,17963,17964],{"class":3881},"description",[3863,17966,3891],{"class":3877},[3863,17968,3895],{"class":3894},[3863,17970,4326],{"class":3877},[3863,17972,17702],{"class":3894},[3863,17974,3928],{"class":3877},[3863,17976,17977,17979,17982,17984,17986,17989],{"class":3865,"line":16196},[3863,17978,9576],{"class":3869},[3863,17980,17981],{"class":4493}," course",[3863,17983,4167],{"class":3877},[3863,17985,7639],{"class":3869},[3863,17987,17988],{"class":3873}," Course",[3863,17990,8583],{"class":3877},[3863,17992,17993,17996,17998,18000,18002,18004,18006,18008,18010,18012,18014,18016,18018,18020,18022,18024,18026,18028,18030],{"class":3865,"line":16213},[3863,17994,17995],{"class":4089},"      `course-",[3863,17997,4998],{"class":3869},[3863,17999,13947],{"class":3881},[3863,18001,3783],{"class":6289},[3863,18003,3953],{"class":3873},[3863,18005,3956],{"class":6289},[3863,18007,3959],{"class":3873},[3863,18009,3878],{"class":6289},[3863,18011,3965],{"class":3964},[3863,18013,9128],{"class":6289},[3863,18015,9673],{"class":3873},[3863,18017,3878],{"class":6289},[3863,18019,9136],{"class":3964},[3863,18021,3776],{"class":6289},[3863,18023,15055],{"class":3964},[3863,18025,14774],{"class":6289},[3863,18027,5003],{"class":3869},[3863,18029,5006],{"class":4089},[3863,18031,3939],{"class":3877},[3863,18033,18034,18037],{"class":3865,"line":16218},[3863,18035,18036],{"class":3881},"      title",[3863,18038,3939],{"class":3877},[3863,18040,18041,18044],{"class":3865,"line":16229},[3863,18042,18043],{"class":3881},"      description",[3863,18045,3939],{"class":3877},[3863,18047,18048],{"class":3865,"line":16254},[3863,18049,18050],{"class":3869},"      this\n",[3863,18052,18053],{"class":3865,"line":16259},[3863,18054,18055],{"class":3877},"    );\n",[3863,18057,18058,18060,18062,18065,18067,18069,18071,18073],{"class":3865,"line":16264},[3863,18059,7842],{"class":3869},[3863,18061,3783],{"class":3877},[3863,18063,18064],{"class":3881},"createdCourses",[3863,18066,3783],{"class":3877},[3863,18068,17765],{"class":3873},[3863,18070,3878],{"class":3877},[3863,18072,17719],{"class":3881},[3863,18074,5009],{"class":3877},[3863,18076,18077,18079,18081,18083,18085,18087,18089,18091,18093,18095,18097,18100,18102,18104,18106,18108,18110,18112],{"class":3865,"line":16275},[3863,18078,4986],{"class":3881},[3863,18080,3783],{"class":3877},[3863,18082,4941],{"class":3873},[3863,18084,3878],{"class":3877},[3863,18086,5006],{"class":4089},[3863,18088,4998],{"class":3869},[3863,18090,6885],{"class":3869},[3863,18092,3783],{"class":6289},[3863,18094,3888],{"class":3881},[3863,18096,5003],{"class":3869},[3863,18098,18099],{"class":4089}," створив курс \"",[3863,18101,4998],{"class":3869},[3863,18103,17719],{"class":3881},[3863,18105,3783],{"class":6289},[3863,18107,17821],{"class":3881},[3863,18109,5003],{"class":3869},[3863,18111,17826],{"class":4089},[3863,18113,5009],{"class":3877},[3863,18115,18116,18118,18120],{"class":3865,"line":16298},[3863,18117,6921],{"class":3924},[3863,18119,17981],{"class":3881},[3863,18121,4108],{"class":3877},[3863,18123,18124],{"class":3865,"line":16303},[3863,18125,5098],{"class":3877},[3863,18127,18128],{"class":3865,"line":16308},[3863,18129,4002],{"emptyLinePlaceholder":4001},[3863,18131,18132,18134,18136,18138],{"class":3865,"line":16313},[3863,18133,17845],{"class":3873},[3863,18135,5715],{"class":3877},[3863,18137,17702],{"class":3894},[3863,18139,17852],{"class":3877},[3863,18141,18142,18144,18146,18148,18150,18152],{"class":3865,"line":16334},[3863,18143,6921],{"class":3924},[3863,18145,17859],{"class":3877},[3863,18147,6885],{"class":3869},[3863,18149,3783],{"class":3877},[3863,18151,18064],{"class":3881},[3863,18153,12224],{"class":3877},[3863,18155,18156],{"class":3865,"line":16350},[3863,18157,5098],{"class":3877},[3863,18159,18160],{"class":3865,"line":16364},[3863,18161,4002],{"emptyLinePlaceholder":4001},[3863,18163,18164,18166,18168,18170],{"class":3865,"line":16369},[3863,18165,17884],{"class":3873},[3863,18167,5715],{"class":3877},[3863,18169,3895],{"class":3894},[3863,18171,3928],{"class":3877},[3863,18173,18174,18176,18179],{"class":3865,"line":16388},[3863,18175,6921],{"class":3924},[3863,18177,18178],{"class":4089}," 'Instructor'",[3863,18180,4108],{"class":3877},[3863,18182,18183],{"class":3865,"line":16403},[3863,18184,5098],{"class":3877},[3863,18186,18188],{"class":3865,"line":18187},72,[3863,18189,3995],{"class":3877},[3863,18191,18193],{"class":3865,"line":18192},73,[3863,18194,4002],{"emptyLinePlaceholder":4001},[3863,18196,18198],{"class":3865,"line":18197},74,[3863,18199,18200],{"class":4559},"\u002F\u002F Клас Course\n",[3863,18202,18204,18206,18208],{"class":3865,"line":18203},75,[3863,18205,7514],{"class":3869},[3863,18207,17988],{"class":3894},[3863,18209,3928],{"class":3877},[3863,18211,18213,18215,18218,18220,18223],{"class":3865,"line":18212},76,[3863,18214,10066],{"class":3869},[3863,18216,18217],{"class":3881}," students",[3863,18219,3891],{"class":3877},[3863,18221,18222],{"class":3894},"Student",[3863,18224,17705],{"class":3877},[3863,18226,18228],{"class":3865,"line":18227},77,[3863,18229,4002],{"emptyLinePlaceholder":4001},[3863,18231,18233,18235],{"class":3865,"line":18232},78,[3863,18234,7827],{"class":3869},[3863,18236,8583],{"class":3877},[3863,18238,18240,18242,18244,18246,18248,18250],{"class":3865,"line":18239},79,[3863,18241,8588],{"class":3869},[3863,18243,8776],{"class":3869},[3863,18245,4693],{"class":3881},[3863,18247,3891],{"class":3877},[3863,18249,3895],{"class":3894},[3863,18251,3939],{"class":3877},[3863,18253,18255,18257,18259,18261,18263],{"class":3865,"line":18254},80,[3863,18256,8588],{"class":3869},[3863,18258,13134],{"class":3881},[3863,18260,3891],{"class":3877},[3863,18262,3895],{"class":3894},[3863,18264,3939],{"class":3877},[3863,18266,18268,18270,18273,18275,18277],{"class":3865,"line":18267},81,[3863,18269,8588],{"class":3869},[3863,18271,18272],{"class":3881}," description",[3863,18274,3891],{"class":3877},[3863,18276,3895],{"class":3894},[3863,18278,3939],{"class":3877},[3863,18280,18282,18284,18287,18289],{"class":3865,"line":18281},82,[3863,18283,8588],{"class":3869},[3863,18285,18286],{"class":3881}," instructor",[3863,18288,3891],{"class":3877},[3863,18290,18291],{"class":3894},"Instructor\n",[3863,18293,18295],{"class":3865,"line":18294},83,[3863,18296,8833],{"class":3877},[3863,18298,18300],{"class":3865,"line":18299},84,[3863,18301,4002],{"emptyLinePlaceholder":4001},[3863,18303,18305,18308,18310,18313,18315,18317,18319,18321],{"class":3865,"line":18304},85,[3863,18306,18307],{"class":3873},"  addStudent",[3863,18309,3878],{"class":3877},[3863,18311,18312],{"class":3881},"student",[3863,18314,3891],{"class":3877},[3863,18316,18222],{"class":3894},[3863,18318,4326],{"class":3877},[3863,18320,4898],{"class":3894},[3863,18322,3928],{"class":3877},[3863,18324,18326,18328,18330,18332,18334,18337,18339,18341,18343,18345],{"class":3865,"line":18325},86,[3863,18327,10146],{"class":3924},[3863,18329,15391],{"class":3877},[3863,18331,6885],{"class":3869},[3863,18333,3783],{"class":3877},[3863,18335,18336],{"class":3881},"students",[3863,18338,3783],{"class":3877},[3863,18340,4084],{"class":3873},[3863,18342,3878],{"class":3877},[3863,18344,18312],{"class":3881},[3863,18346,17593],{"class":3877},[3863,18348,18350,18352,18354,18356,18358,18360,18362,18364],{"class":3865,"line":18349},87,[3863,18351,10161],{"class":3869},[3863,18353,3783],{"class":3877},[3863,18355,18336],{"class":3881},[3863,18357,3783],{"class":3877},[3863,18359,17765],{"class":3873},[3863,18361,3878],{"class":3877},[3863,18363,18312],{"class":3881},[3863,18365,5009],{"class":3877},[3863,18367,18369],{"class":3865,"line":18368},88,[3863,18370,8118],{"class":3877},[3863,18372,18374],{"class":3865,"line":18373},89,[3863,18375,5098],{"class":3877},[3863,18377,18379],{"class":3865,"line":18378},90,[3863,18380,4002],{"emptyLinePlaceholder":4001},[3863,18382,18384,18387,18389,18391],{"class":3865,"line":18383},91,[3863,18385,18386],{"class":3873},"  getStudents",[3863,18388,5715],{"class":3877},[3863,18390,18222],{"class":3894},[3863,18392,17852],{"class":3877},[3863,18394,18396,18398,18400,18402,18404,18406],{"class":3865,"line":18395},92,[3863,18397,6921],{"class":3924},[3863,18399,17859],{"class":3877},[3863,18401,6885],{"class":3869},[3863,18403,3783],{"class":3877},[3863,18405,18336],{"class":3881},[3863,18407,12224],{"class":3877},[3863,18409,18411],{"class":3865,"line":18410},93,[3863,18412,5098],{"class":3877},[3863,18414,18416],{"class":3865,"line":18415},94,[3863,18417,4002],{"emptyLinePlaceholder":4001},[3863,18419,18421,18423,18425,18427],{"class":3865,"line":18420},95,[3863,18422,11726],{"class":3873},[3863,18424,5715],{"class":3877},[3863,18426,3895],{"class":3894},[3863,18428,3928],{"class":3877},[3863,18430,18432,18434,18437,18439,18441,18443,18445,18447,18451,18454,18456,18458,18460,18463,18465,18467,18469,18471,18474,18476,18478,18480,18482,18484,18486,18488,18490],{"class":3865,"line":18431},96,[3863,18433,6921],{"class":3924},[3863,18435,18436],{"class":4089}," `Курс: ",[3863,18438,4998],{"class":3869},[3863,18440,6885],{"class":3869},[3863,18442,3783],{"class":6289},[3863,18444,17821],{"class":3881},[3863,18446,5003],{"class":3869},[3863,18448,18450],{"class":18449},"sjcCO","\\n",[3863,18452,18453],{"class":4089},"Викладач: ",[3863,18455,4998],{"class":3869},[3863,18457,6885],{"class":3869},[3863,18459,3783],{"class":6289},[3863,18461,18462],{"class":3881},"instructor",[3863,18464,3783],{"class":6289},[3863,18466,3888],{"class":3881},[3863,18468,5003],{"class":3869},[3863,18470,18450],{"class":18449},[3863,18472,18473],{"class":4089},"Студентів: ",[3863,18475,4998],{"class":3869},[3863,18477,6885],{"class":3869},[3863,18479,3783],{"class":6289},[3863,18481,18336],{"class":3881},[3863,18483,3783],{"class":6289},[3863,18485,4064],{"class":3881},[3863,18487,5003],{"class":3869},[3863,18489,5006],{"class":4089},[3863,18491,4108],{"class":3877},[3863,18493,18495],{"class":3865,"line":18494},97,[3863,18496,5098],{"class":3877},[3863,18498,18500],{"class":3865,"line":18499},98,[3863,18501,3995],{"class":3877},[3863,18503,18505],{"class":3865,"line":18504},99,[3863,18506,4002],{"emptyLinePlaceholder":4001},[3863,18508,18510],{"class":3865,"line":18509},100,[3863,18511,18512],{"class":4559},"\u002F\u002F Використання\n",[3863,18514,18516,18518,18520,18522,18524,18526,18528,18531,18533,18536,18538,18541],{"class":3865,"line":18515},101,[3863,18517,4490],{"class":3869},[3863,18519,18286],{"class":4493},[3863,18521,4167],{"class":3877},[3863,18523,7639],{"class":3869},[3863,18525,17923],{"class":3873},[3863,18527,3878],{"class":3877},[3863,18529,18530],{"class":4089},"'inst-001'",[3863,18532,3776],{"class":3877},[3863,18534,18535],{"class":4089},"'Олександр Петренко'",[3863,18537,3776],{"class":3877},[3863,18539,18540],{"class":4089},"'petro@university.edu'",[3863,18542,5009],{"class":3877},[3863,18544,18546,18548,18551,18553,18555,18557,18559,18562,18564,18567,18569,18572],{"class":3865,"line":18545},102,[3863,18547,4490],{"class":3869},[3863,18549,18550],{"class":4493}," student1",[3863,18552,4167],{"class":3877},[3863,18554,7639],{"class":3869},[3863,18556,17684],{"class":3873},[3863,18558,3878],{"class":3877},[3863,18560,18561],{"class":4089},"'stud-001'",[3863,18563,3776],{"class":3877},[3863,18565,18566],{"class":4089},"'Марія Коваленко'",[3863,18568,3776],{"class":3877},[3863,18570,18571],{"class":4089},"'maria@student.edu'",[3863,18573,5009],{"class":3877},[3863,18575,18577,18579,18582,18584,18586,18588,18590,18593,18595,18598,18600,18603],{"class":3865,"line":18576},103,[3863,18578,4490],{"class":3869},[3863,18580,18581],{"class":4493}," student2",[3863,18583,4167],{"class":3877},[3863,18585,7639],{"class":3869},[3863,18587,17684],{"class":3873},[3863,18589,3878],{"class":3877},[3863,18591,18592],{"class":4089},"'stud-002'",[3863,18594,3776],{"class":3877},[3863,18596,18597],{"class":4089},"'Іван Шевченко'",[3863,18599,3776],{"class":3877},[3863,18601,18602],{"class":4089},"'ivan@student.edu'",[3863,18604,5009],{"class":3877},[3863,18606,18608],{"class":3865,"line":18607},104,[3863,18609,4002],{"emptyLinePlaceholder":4001},[3863,18611,18613,18615,18618,18620,18622,18624,18627],{"class":3865,"line":18612},105,[3863,18614,4490],{"class":3869},[3863,18616,18617],{"class":4493}," typescriptCourse",[3863,18619,4167],{"class":3877},[3863,18621,18462],{"class":3881},[3863,18623,3783],{"class":3877},[3863,18625,18626],{"class":3873},"createCourse",[3863,18628,8583],{"class":3877},[3863,18630,18632,18635],{"class":3865,"line":18631},106,[3863,18633,18634],{"class":4089},"  'TypeScript Fundamentals'",[3863,18636,3939],{"class":3877},[3863,18638,18640],{"class":3865,"line":18639},107,[3863,18641,18642],{"class":4089},"  'Вступ до TypeScript: типи, класи, інтерфейси'\n",[3863,18644,18646],{"class":3865,"line":18645},108,[3863,18647,5009],{"class":3877},[3863,18649,18651],{"class":3865,"line":18650},109,[3863,18652,4002],{"emptyLinePlaceholder":4001},[3863,18654,18656,18659,18661,18664,18666,18669],{"class":3865,"line":18655},110,[3863,18657,18658],{"class":3881},"student1",[3863,18660,3783],{"class":3877},[3863,18662,18663],{"class":3873},"enrollInCourse",[3863,18665,3878],{"class":3877},[3863,18667,18668],{"class":3881},"typescriptCourse",[3863,18670,5009],{"class":3877},[3863,18672,18674,18677,18679,18681,18683,18685],{"class":3865,"line":18673},111,[3863,18675,18676],{"class":3881},"student2",[3863,18678,3783],{"class":3877},[3863,18680,18663],{"class":3873},[3863,18682,3878],{"class":3877},[3863,18684,18668],{"class":3881},[3863,18686,5009],{"class":3877},[3863,18688,18690],{"class":3865,"line":18689},112,[3863,18691,4002],{"emptyLinePlaceholder":4001},[3863,18693,18695,18697,18699,18701,18703,18705,18707,18709],{"class":3865,"line":18694},113,[3863,18696,5355],{"class":3881},[3863,18698,3783],{"class":3877},[3863,18700,4941],{"class":3873},[3863,18702,3878],{"class":3877},[3863,18704,18668],{"class":3881},[3863,18706,3783],{"class":3877},[3863,18708,11837],{"class":3873},[3863,18710,7956],{"class":3877},[3863,18712,18714],{"class":3865,"line":18713},114,[3863,18715,18716],{"class":4559},"\u002F\u002F Курс: TypeScript Fundamentals\n",[3863,18718,18720],{"class":3865,"line":18719},115,[3863,18721,18722],{"class":4559},"\u002F\u002F Викладач: Олександр Петренко\n",[3863,18724,18726],{"class":3865,"line":18725},116,[3863,18727,18728],{"class":4559},"\u002F\u002F Студентів: 2\n",[3863,18730,18732],{"class":3865,"line":18731},117,[3863,18733,4002],{"emptyLinePlaceholder":4001},[3863,18735,18737,18739,18741,18743,18745,18748,18750,18752,18754,18756,18758,18761],{"class":3865,"line":18736},118,[3863,18738,5355],{"class":3881},[3863,18740,3783],{"class":3877},[3863,18742,4941],{"class":3873},[3863,18744,3878],{"class":3877},[3863,18746,18747],{"class":4089},"`Курси студента ",[3863,18749,4998],{"class":3869},[3863,18751,18658],{"class":3881},[3863,18753,3783],{"class":6289},[3863,18755,3888],{"class":3881},[3863,18757,5003],{"class":3869},[3863,18759,18760],{"class":4089},":`",[3863,18762,5009],{"class":3877},[3863,18764,18766,18768,18770,18773,18775,18777,18779,18781,18783,18786,18788,18790,18792,18795,18797,18799,18801,18803,18805,18807],{"class":3865,"line":18765},119,[3863,18767,18658],{"class":3881},[3863,18769,3783],{"class":3877},[3863,18771,18772],{"class":3873},"getCourses",[3863,18774,3956],{"class":3877},[3863,18776,12238],{"class":3873},[3863,18778,3878],{"class":3877},[3863,18780,17719],{"class":3881},[3863,18782,12246],{"class":3869},[3863,18784,18785],{"class":3881}," console",[3863,18787,3783],{"class":3877},[3863,18789,4941],{"class":3873},[3863,18791,3878],{"class":3877},[3863,18793,18794],{"class":4089},"`- ",[3863,18796,4998],{"class":3869},[3863,18798,17719],{"class":3881},[3863,18800,3783],{"class":6289},[3863,18802,17821],{"class":3881},[3863,18804,5003],{"class":3869},[3863,18806,5006],{"class":4089},[3863,18808,14566],{"class":3877},[3863,18810,18812],{"class":3865,"line":18811},120,[3863,18813,18814],{"class":4559},"\u002F\u002F Курси студента Марія Коваленко:\n",[3863,18816,18818],{"class":3865,"line":18817},121,[3863,18819,18820],{"class":4559},"\u002F\u002F - TypeScript Fundamentals\n",[4237,18822,18824],{"id":18823},"аналіз-рішення","Аналіз рішення",[3746,18826,18827,18834,18851,18865,18872,18890],{},[3749,18828,18829,18833],{},[3796,18830,6672,18831,4671],{},[3753,18832,4303],{}," Визначає контракт для всіх користувачів, забезпечуючи узгодженість API.",[3749,18835,18836,18842,18843,18846,18847,18850],{},[3796,18837,18838,18839,4671],{},"Абстрактний клас ",[3753,18840,18841],{},"BaseUser"," Містить спільну реалізацію (",[3753,18844,18845],{},"updateProfile",") та абстрактний метод ",[3753,18848,18849],{},"getUserType()",", який нащадки мають реалізувати.",[3749,18852,18853,18861,18862,18864],{},[3796,18854,18855,18856,3756,18858,4671],{},"Класи ",[3753,18857,18222],{},[3753,18859,18860],{},"Instructor"," Успадковують ",[3753,18863,18841],{},", додають специфічну поведінку (запис на курси для студентів, створення курсів для викладачів).",[3749,18866,18867,18871],{},[3796,18868,11550,18869,4671],{},[3753,18870,17702],{}," Інкапсулює логіку курсу, зберігає список студентів, зв'язаний з викладачем.",[3749,18873,18874,18877,18878,3756,18880,18882,18883,3756,18886,18889],{},[3796,18875,18876],{},"Інкапсуляція:"," Приватні масиви ",[3753,18879,17742],{},[3753,18881,18336],{}," захищені від прямого доступу; методи ",[3753,18884,18885],{},"getCourses()",[3753,18887,18888],{},"getStudents()"," повертають копії масивів, щоб зовнішній код не міг змінити внутрішній стан напряму.",[3749,18891,18892,18895,18896,18898],{},[3796,18893,18894],{},"Двостороння зв'язаність:"," Метод ",[3753,18897,18663],{}," додає студента до курсу і оновлює список курсів студента, підтримуючи узгодженість даних.",[4845,18900,18901,18902,4227,18905,18908],{},"Цей приклад демонструє ",[3796,18903,18904],{},"доменно-орієнтоване проєктування",[4229,18906,18907],{},"Domain-Driven Design, DDD","): класи моделюють реальні сутності предметної області (студенти, викладачі, курси), інкапсулюють бізнес-правила (валідацію, обмеження) та надають чіткі інтерфейси для взаємодії. TypeScript забезпечує безпеку типів, що знижує ризик помилок у runtime.",[3838,18910],{},[3841,18912,18914],{"id":18913},"підсумок-інтерфейси-та-класи-як-основа-типобезпечної-архітектури","Підсумок: інтерфейси та класи як основа типобезпечної архітектури",[3846,18916,18917,18918,3756,18920,18923],{},"У цьому розділі ми опанували два фундаментальні інструменти TypeScript для структурування коду: ",[3796,18919,15673],{},[3796,18921,18922],{},"класи",". Хоча обидва механізми часто використовуються разом, вони мають різні ролі:",[3746,18925,18926,18946],{},[3749,18927,18928,18931,18932,18935,18936,4227,18939,18942,18943,18945],{},[3796,18929,18930],{},"Інтерфейси"," визначають ",[3796,18933,18934],{},"контракти"," — що має робити об'єкт або клас, але не як це робиться. Вони є основою ",[3796,18937,18938],{},"слабкого зв'язування",[4229,18940,18941],{},"loose coupling",") та ",[3796,18944,13354],{},": код залежить від абстракцій (інтерфейсів), а не від конкретних реалізацій (класів). Це робить систему гнучкою, тестованою та легко розширюваною.",[3749,18947,18948,18951,18952,18954],{},[3796,18949,18950],{},"Класи"," надають ",[3796,18953,5152],{}," — конкретний код, що виконує функціональність. Класи TypeScript базуються на прототипній моделі JavaScript, але додають типізацію, модифікатори доступу, абстрактні методи та інші інструменти, що роблять ОО-код безпечним та виразним.",[4237,18956,18958],{"id":18957},"ключові-тези","Ключові тези",[3746,18960,18961,18967,18973,18986,18994,19002,19008,19014,19020],{},[3749,18962,18963,18966],{},[3796,18964,18965],{},"Інтерфейси описують структуру:"," використовуйте їх для моделювання форм даних, контрактів поведінки та публічних API.",[3749,18968,18969,18972],{},[3796,18970,18971],{},"Type aliases універсальніші:"," застосовуйте для union types, intersection types, кортежів, але для об'єктів часто інтерфейси виразніші.",[3749,18974,18975,18978,18979,3776,18981,3776,18983,18985],{},[3796,18976,18977],{},"Класи інкапсулюють стан та логіку:"," використовуйте модифікатори доступу (",[3753,18980,3779],{},[3753,18982,3782],{},[3753,18984,3775],{},") для контролю видимості та захисту внутрішньої реалізації.",[3749,18987,18988,18993],{},[3796,18989,18990,18991,4671],{},"Наслідування через ",[3753,18992,5640],{}," створюйте ієрархії класів для повторного використання коду, але не зловживайте глибокими ієрархіями.",[3749,18995,18996,19001],{},[3796,18997,18998,18999,4671],{},"Реалізація інтерфейсів через ",[3753,19000,12561],{}," забезпечує узгодженість API та дозволяє використовувати поліморфізм.",[3749,19003,19004,19007],{},[3796,19005,19006],{},"Абстрактні класи як шаблони:"," використовуйте для базових класів з частковою реалізацією та абстрактними методами, що нащадки мають реалізувати.",[3749,19009,19010,19013],{},[3796,19011,19012],{},"Композиція перед наслідуванням:"," для гнучких та слабко зв'язаних архітектур віддавайте перевагу композиції поведінки через поля-об'єкти замість глибоких ієрархій наслідування.",[3749,19015,19016,19019],{},[3796,19017,19018],{},"Getters та setters:"," додають контрольований доступ до полів з валідацією, обчисленнями та lazy initialization.",[3749,19021,19022,19025],{},[3796,19023,19024],{},"Structural typing:"," TypeScript перевіряє сумісність типів за структурою, а не за іменем класу, що робить систему типів гнучкішою.",[4237,19027,6342],{"id":19028},"практичні-рекомендації-1",[4845,19030,19031,19036,19052,19057,19077,19082],{},[3846,19032,19033],{},[3796,19034,19035],{},"Для публічних API бібліотек:",[3746,19037,19038,19043,19049],{},[3749,19039,4847,19040,19042],{},[3796,19041,15673],{}," для визначення контрактів, що користувачі мають реалізувати або яким мають відповідати об'єкти.",[3749,19044,19045,19046,19048],{},"Дозволяйте ",[3796,19047,5895],{}," для розширення ваших типів користувачами.",[3749,19050,19051],{},"Документуйте інтерфейси через JSDoc коментарі.",[3846,19053,19054],{},[3796,19055,19056],{},"Для внутрішньої доменної логіки:",[3746,19058,19059,19065,19072],{},[3749,19060,19061,19062,19064],{},"Моделюйте сутності через ",[3796,19063,18922],{}," з приватними полями та публічними методами.",[3749,19066,19067,19068,19071],{},"Застосовуйте ",[3796,19069,19070],{},"абстрактні класи"," для базових сутностей з частковою реалізацією.",[3749,19073,4847,19074,19076],{},[3796,19075,4670],{}," для незмінних ідентифікаторів та метаданих.",[3846,19078,19079],{},[3796,19080,19081],{},"Для архітектурних патернів:",[3746,19083,19084,19090,19096],{},[3749,19085,19086,19089],{},[3796,19087,19088],{},"Dependency Injection:"," приймайте залежності як інтерфейси у конструкторі класу.",[3749,19091,19092,19095],{},[3796,19093,19094],{},"Strategy Pattern:"," визначайте стратегії як інтерфейси, реалізуйте через класи, передавайте через композицію.",[3749,19097,19098,19101],{},[3796,19099,19100],{},"Factory Pattern:"," використовуйте статичні методи класів для створення екземплярів з різними конфігураціями.",[3846,19103,19104,19105,19108,19109,3756,19112,19115],{},"У наступних розділах ми розглянемо ",[3796,19106,19107],{},"generics"," — механізм параметризації типів, що дозволяє писати універсальний та повторно використовуваний код без втрати типобезпеки, а також ",[3796,19110,19111],{},"enums",[3796,19113,19114],{},"decorators"," для метапрограмування та декларативного розширення функціональності класів.",[3838,19117],{},[19119,19120,19121,19200,19228,19272,19396,19574],"accordion",{},[19122,19123,19126,19131,19197],"accordion-item",{"icon":19124,"label":19125},"i-lucide-help-circle","❓ Чи можна використовувати interface для опису union типу?",[3846,19127,19128,19129,4671],{},"Ні, інтерфейси призначені для опису структур об'єктів. Для union типів використовуйте ",[3753,19130,3759],{},[3854,19132,19134],{"className":3856,"code":19133,"language":3858,"meta":3859,"style":3859},"\u002F\u002F ❌ Неможливо\ninterface Status = 'idle' | 'loading' | 'success';\n\n\u002F\u002F ✅ Правильно\ntype Status = 'idle' | 'loading' | 'success';\n",[3753,19135,19136,19141,19168,19172,19177],{"__ignoreMap":3859},[3863,19137,19138],{"class":3865,"line":3866},[3863,19139,19140],{"class":4559},"\u002F\u002F ❌ Неможливо\n",[3863,19142,19143,19145,19148,19151,19154,19157,19160,19162,19165],{"class":3865,"line":3921},[3863,19144,3755],{"class":3869},[3863,19146,19147],{"class":3894}," Status",[3863,19149,19150],{"class":3877}," = '",[3863,19152,19153],{"class":3894},"idle",[3863,19155,19156],{"class":3877},"' | '",[3863,19158,19159],{"class":3894},"loading",[3863,19161,19156],{"class":3877},[3863,19163,19164],{"class":3894},"success",[3863,19166,19167],{"class":3877},"';\n",[3863,19169,19170],{"class":3865,"line":3931},[3863,19171,4002],{"emptyLinePlaceholder":4001},[3863,19173,19174],{"class":3865,"line":3942},[3863,19175,19176],{"class":4559},"\u002F\u002F ✅ Правильно\n",[3863,19178,19179,19181,19183,19185,19187,19189,19191,19193,19195],{"class":3865,"line":3971},[3863,19180,3759],{"class":3894},[3863,19182,19147],{"class":3894},[3863,19184,19150],{"class":3877},[3863,19186,19153],{"class":3894},[3863,19188,19156],{"class":3877},[3863,19190,19159],{"class":3894},[3863,19192,19156],{"class":3877},[3863,19194,19164],{"class":3894},[3863,19196,19167],{"class":3877},[3846,19198,19199],{},"Інтерфейси можуть розширюватися, об'єднуватися (declaration merging), але не можуть бути union типами або примітивами.",[19122,19201,19203,19220],{"icon":19124,"label":19202},"❓ Чому TypeScript private відрізняється від JavaScript # приватних полів?",[3846,19204,19205,19210,19211,19216,19217,19219],{},[3796,19206,19207,19208],{},"TypeScript ",[3753,19209,3779],{}," — це лише анотація типу, що працює на етапі компіляції. У скомпільованому JavaScript коді поле залишається звичайним і доступним. ",[3796,19212,19213,19214],{},"JavaScript ",[3753,19215,10421],{}," — це справжня приватність на рівні мови: поля з ",[3753,19218,10421],{}," недоступні ззовні навіть у runtime.",[3846,19221,4847,19222,19224,19225,19227],{},[3753,19223,3779],{}," для типізації та документування інтенцій, ",[3753,19226,10421],{}," — коли потрібна реальна приватність у runtime (наприклад, для безпеки або уникнення конфліктів імен).",[19122,19229,19231,19253,19269],{"icon":19124,"label":19230},"❓ Коли використовувати абстрактний клас, а коли інтерфейс?",[3846,19232,19233,19236,19237,19239,19240,19243,19244,19247,19248,3776,19251,3783],{},[3796,19234,19235],{},"Абстрактний клас:"," коли потрібна ",[3796,19238,14805],{}," частини функціональності для всіх нащадків, або коли базовий клас має містити стан (поля) та приватні\u002Fprotected методи. Приклад: ",[3753,19241,19242],{},"abstract class Shape"," з методом ",[3753,19245,19246],{},"describe()"," та абстрактними методами ",[3753,19249,19250],{},"getArea()",[3753,19252,14380],{},[3846,19254,19255,19258,19259,19262,19263,3776,19266,3783],{},[3796,19256,19257],{},"Інтерфейс:"," коли потрібен ",[3796,19260,19261],{},"чистий контракт"," без реалізації, або коли клас має реалізовувати кілька контрактів одночасно (множинна реалізація). Приклад: ",[3753,19264,19265],{},"interface Loggable",[3753,19267,19268],{},"interface Serializable",[3846,19270,19271],{},"Якщо сумніваєтеся, почніть з інтерфейсу — він гнучкіший. Перейдіть на абстрактний клас, коли виявиться, що кілька класів дублюють одну й ту саму реалізацію.",[19122,19273,19275,19286,19393],{"icon":19124,"label":19274},"❓ Чи можна змінити модифікатор доступу (public\u002Fprivate\u002Fprotected) при перевизначенні методу у нащадку?",[3846,19276,19277,19278,19281,19282,19285],{},"TypeScript дозволяє ",[3796,19279,19280],{},"розширити доступність"," (зробити метод більш доступним), але ",[3796,19283,19284],{},"заборонить звуження"," (зробити його менш доступним):",[3854,19287,19289],{"className":3856,"code":19288,"language":3858,"meta":3859,"style":3859},"class Base {\n  protected method(): void {}\n}\n\nclass Derived extends Base {\n  public method(): void {}  \u002F\u002F ✅ OK: розширення з protected до public\n}\n\nclass Another extends Base {\n  \u002F\u002F ❌ Error: Cannot reduce visibility\n  private method(): void {}\n}\n",[3753,19290,19291,19300,19314,19318,19322,19335,19351,19355,19359,19372,19377,19389],{"__ignoreMap":3859},[3863,19292,19293,19295,19298],{"class":3865,"line":3866},[3863,19294,7514],{"class":3869},[3863,19296,19297],{"class":3894}," Base",[3863,19299,3928],{"class":3877},[3863,19301,19302,19304,19307,19309,19311],{"class":3865,"line":3921},[3863,19303,10598],{"class":3869},[3863,19305,19306],{"class":3873}," method",[3863,19308,5715],{"class":3877},[3863,19310,4898],{"class":3894},[3863,19312,19313],{"class":3877}," {}\n",[3863,19315,19316],{"class":3865,"line":3931},[3863,19317,3995],{"class":3877},[3863,19319,19320],{"class":3865,"line":3942},[3863,19321,4002],{"emptyLinePlaceholder":4001},[3863,19323,19324,19326,19329,19331,19333],{"class":3865,"line":3971},[3863,19325,7514],{"class":3869},[3863,19327,19328],{"class":3894}," Derived",[3863,19330,5692],{"class":3869},[3863,19332,19297],{"class":3894},[3863,19334,3928],{"class":3877},[3863,19336,19337,19339,19341,19343,19345,19348],{"class":3865,"line":3986},[3863,19338,9902],{"class":3869},[3863,19340,19306],{"class":3873},[3863,19342,5715],{"class":3877},[3863,19344,4898],{"class":3894},[3863,19346,19347],{"class":3877}," {}  ",[3863,19349,19350],{"class":4559},"\u002F\u002F ✅ OK: розширення з protected до public\n",[3863,19352,19353],{"class":3865,"line":3992},[3863,19354,3995],{"class":3877},[3863,19356,19357],{"class":3865,"line":3998},[3863,19358,4002],{"emptyLinePlaceholder":4001},[3863,19360,19361,19363,19366,19368,19370],{"class":3865,"line":4005},[3863,19362,7514],{"class":3869},[3863,19364,19365],{"class":3894}," Another",[3863,19367,5692],{"class":3869},[3863,19369,19297],{"class":3894},[3863,19371,3928],{"class":3877},[3863,19373,19374],{"class":3865,"line":4050},[3863,19375,19376],{"class":4559},"  \u002F\u002F ❌ Error: Cannot reduce visibility\n",[3863,19378,19379,19381,19383,19385,19387],{"class":3865,"line":4111},[3863,19380,10066],{"class":3869},[3863,19382,19306],{"class":3873},[3863,19384,5715],{"class":3877},[3863,19386,4898],{"class":3894},[3863,19388,19313],{"class":3877},[3863,19390,19391],{"class":3865,"line":4482},[3863,19392,3995],{"class":3877},[3846,19394,19395],{},"Це забезпечує принцип підстановки Лісков: якщо метод був доступний у базовому класі, він має залишатися доступним у нащадку.",[19122,19397,19399,19405,19569],{"icon":19124,"label":19398},"❓ Як перевірити у runtime, чи є об'єкт екземпляром певного класу?",[3846,19400,19401,19402,4671],{},"Використовуйте оператор ",[3753,19403,19404],{},"instanceof",[3854,19406,19408],{"className":3856,"code":19407,"language":3858,"meta":3859,"style":3859},"class Dog {\n  bark(): void { console.log('Гав!'); }\n}\n\nclass Cat {\n  meow(): void { console.log('Мяу!'); }\n}\n\nconst animal: Dog | Cat = new Dog();\n\nif (animal instanceof Dog) {\n  animal.bark();  \u002F\u002F TypeScript знає, що animal тут має тип Dog\n} else {\n  animal.meow();  \u002F\u002F TypeScript знає, що animal тут має тип Cat\n}\n",[3753,19409,19410,19418,19440,19444,19448,19456,19479,19483,19487,19509,19513,19529,19542,19552,19565],{"__ignoreMap":3859},[3863,19411,19412,19414,19416],{"class":3865,"line":3866},[3863,19413,7514],{"class":3869},[3863,19415,5689],{"class":3894},[3863,19417,3928],{"class":3877},[3863,19419,19420,19422,19424,19426,19428,19430,19432,19434,19436,19438],{"class":3865,"line":3921},[3863,19421,5712],{"class":3873},[3863,19423,5715],{"class":3877},[3863,19425,4898],{"class":3894},[3863,19427,16767],{"class":3877},[3863,19429,5355],{"class":3881},[3863,19431,3783],{"class":3877},[3863,19433,4941],{"class":3873},[3863,19435,3878],{"class":3877},[3863,19437,5787],{"class":4089},[3863,19439,5790],{"class":3877},[3863,19441,19442],{"class":3865,"line":3931},[3863,19443,3995],{"class":3877},[3863,19445,19446],{"class":3865,"line":3942},[3863,19447,4002],{"emptyLinePlaceholder":4001},[3863,19449,19450,19452,19454],{"class":3865,"line":3971},[3863,19451,7514],{"class":3869},[3863,19453,7146],{"class":3894},[3863,19455,3928],{"class":3877},[3863,19457,19458,19460,19462,19464,19466,19468,19470,19472,19474,19477],{"class":3865,"line":3986},[3863,19459,11453],{"class":3873},[3863,19461,5715],{"class":3877},[3863,19463,4898],{"class":3894},[3863,19465,16767],{"class":3877},[3863,19467,5355],{"class":3881},[3863,19469,3783],{"class":3877},[3863,19471,4941],{"class":3873},[3863,19473,3878],{"class":3877},[3863,19475,19476],{"class":4089},"'Мяу!'",[3863,19478,5790],{"class":3877},[3863,19480,19481],{"class":3865,"line":3992},[3863,19482,3995],{"class":3877},[3863,19484,19485],{"class":3865,"line":3998},[3863,19486,4002],{"emptyLinePlaceholder":4001},[3863,19488,19489,19491,19493,19495,19497,19499,19501,19503,19505,19507],{"class":3865,"line":4005},[3863,19490,4490],{"class":3869},[3863,19492,12249],{"class":4493},[3863,19494,3891],{"class":3877},[3863,19496,5739],{"class":3894},[3863,19498,4173],{"class":3877},[3863,19500,7200],{"class":3894},[3863,19502,4167],{"class":3877},[3863,19504,7639],{"class":3869},[3863,19506,5689],{"class":3873},[3863,19508,9154],{"class":3877},[3863,19510,19511],{"class":3865,"line":4050},[3863,19512,4002],{"emptyLinePlaceholder":4001},[3863,19514,19515,19518,19520,19522,19525,19527],{"class":3865,"line":4111},[3863,19516,19517],{"class":3924},"if",[3863,19519,4227],{"class":3877},[3863,19521,12243],{"class":3881},[3863,19523,19524],{"class":3869}," instanceof",[3863,19526,5689],{"class":3894},[3863,19528,5195],{"class":3877},[3863,19530,19531,19533,19535,19537,19539],{"class":3865,"line":4482},[3863,19532,16895],{"class":3881},[3863,19534,3783],{"class":3877},[3863,19536,10791],{"class":3873},[3863,19538,10747],{"class":3877},[3863,19540,19541],{"class":4559},"\u002F\u002F TypeScript знає, що animal тут має тип Dog\n",[3863,19543,19544,19547,19550],{"class":3865,"line":4487},[3863,19545,19546],{"class":3877},"} ",[3863,19548,19549],{"class":3924},"else",[3863,19551,3928],{"class":3877},[3863,19553,19554,19556,19558,19560,19562],{"class":3865,"line":4505},[3863,19555,16895],{"class":3881},[3863,19557,3783],{"class":3877},[3863,19559,11541],{"class":3873},[3863,19561,10747],{"class":3877},[3863,19563,19564],{"class":4559},"\u002F\u002F TypeScript знає, що animal тут має тип Cat\n",[3863,19566,19567],{"class":3865,"line":4517},[3863,19568,3995],{"class":3877},[3846,19570,19571,19573],{},[3753,19572,19404],{}," перевіряє ланцюг прототипів об'єкта у runtime і є type guard для TypeScript — після перевірки компілятор автоматично звужує тип.",[19122,19575,19577,19580,19668],{"icon":19124,"label":19576},"❓ Чи впливає порядок оголошення інтерфейсів при declaration merging?",[3846,19578,19579],{},"Ні, порядок не впливає — TypeScript об'єднує всі оголошення інтерфейсів з однаковим іменем у одне незалежно від порядку:",[3854,19581,19583],{"className":3856,"code":19582,"language":3858,"meta":3859,"style":3859},"interface User {\n  name: string;\n}\n\ninterface User {\n  age: number;\n}\n\ninterface User {\n  email: string;\n}\n\n\u002F\u002F Результат: User має name, age, email незалежно від порядку оголошень\n",[3753,19584,19585,19593,19603,19607,19611,19619,19629,19633,19637,19645,19655,19659,19663],{"__ignoreMap":3859},[3863,19586,19587,19589,19591],{"class":3865,"line":3866},[3863,19588,3755],{"class":3869},[3863,19590,4258],{"class":3894},[3863,19592,3928],{"class":3877},[3863,19594,19595,19597,19599,19601],{"class":3865,"line":3921},[3863,19596,4265],{"class":3881},[3863,19598,3891],{"class":3877},[3863,19600,3895],{"class":3894},[3863,19602,4108],{"class":3877},[3863,19604,19605],{"class":3865,"line":3931},[3863,19606,3995],{"class":3877},[3863,19608,19609],{"class":3865,"line":3942},[3863,19610,4002],{"emptyLinePlaceholder":4001},[3863,19612,19613,19615,19617],{"class":3865,"line":3971},[3863,19614,3755],{"class":3869},[3863,19616,4258],{"class":3894},[3863,19618,3928],{"class":3877},[3863,19620,19621,19623,19625,19627],{"class":3865,"line":3986},[3863,19622,4287],{"class":3881},[3863,19624,3891],{"class":3877},[3863,19626,3915],{"class":3894},[3863,19628,4108],{"class":3877},[3863,19630,19631],{"class":3865,"line":3992},[3863,19632,3995],{"class":3877},[3863,19634,19635],{"class":3865,"line":3998},[3863,19636,4002],{"emptyLinePlaceholder":4001},[3863,19638,19639,19641,19643],{"class":3865,"line":4005},[3863,19640,3755],{"class":3869},[3863,19642,4258],{"class":3894},[3863,19644,3928],{"class":3877},[3863,19646,19647,19649,19651,19653],{"class":3865,"line":4050},[3863,19648,4276],{"class":3881},[3863,19650,3891],{"class":3877},[3863,19652,3895],{"class":3894},[3863,19654,4108],{"class":3877},[3863,19656,19657],{"class":3865,"line":4111},[3863,19658,3995],{"class":3877},[3863,19660,19661],{"class":3865,"line":4482},[3863,19662,4002],{"emptyLinePlaceholder":4001},[3863,19664,19665],{"class":3865,"line":4487},[3863,19666,19667],{"class":4559},"\u002F\u002F Результат: User має name, age, email незалежно від порядку оголошень\n",[3846,19669,19670],{},"Якщо є конфлікт (одне й те саме поле оголошено з різними типами), TypeScript видасть помилку.",[19672,19673,19674],"style",{},"html pre.shiki code .su1O8, html code.shiki .su1O8{--shiki-light:#0000FF;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .s8Opu, html code.shiki .s8Opu{--shiki-light:#795E26;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .sHH4Y, html code.shiki .sHH4Y{--shiki-light:#000000;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .siwwj, html code.shiki .siwwj{--shiki-light:#001080;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .sN1BT, html code.shiki .sN1BT{--shiki-light:#267F99;--shiki-default:#4EC9B0;--shiki-dark:#4EC9B0}html pre.shiki code .s8xlr, html code.shiki .s8xlr{--shiki-light:#AF00DB;--shiki-default:#C586C0;--shiki-dark:#C586C0}html pre.shiki code .sJj4R, html code.shiki .sJj4R{--shiki-light:#098658;--shiki-default:#B5CEA8;--shiki-dark:#B5CEA8}html pre.shiki code .sbdoH, html code.shiki .sbdoH{--shiki-light:#A31515;--shiki-default:#CE9178;--shiki-dark:#CE9178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-QsJ, html code.shiki .s-QsJ{--shiki-light:#0070C1;--shiki-default:#4FC1FF;--shiki-dark:#4FC1FF}html pre.shiki code .spJ8K, html code.shiki .spJ8K{--shiki-light:#008000;--shiki-default:#6A9955;--shiki-dark:#6A9955}html pre.shiki code .sD7JJ, html code.shiki .sD7JJ{--shiki-light:#000000FF;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .se1LK, html code.shiki .se1LK{--shiki-light:#CD3131;--shiki-default:#F44747;--shiki-dark:#F44747}html pre.shiki code .sjcCO, html code.shiki .sjcCO{--shiki-light:#EE0000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}",{"title":3859,"searchDepth":3921,"depth":3921,"links":19676},[19677,19678,19684,19688,19693,19698,19704,19710,19716,19719,19724,19728,19729,19733,19738],{"id":3843,"depth":3921,"text":3844},{"id":4220,"depth":3921,"text":4221,"children":19679},[19680,19681,19682,19683],{"id":4239,"depth":3931,"text":4240},{"id":4653,"depth":3931,"text":4654},{"id":4857,"depth":3931,"text":4858},{"id":5251,"depth":3931,"text":5252},{"id":5516,"depth":3921,"text":5517,"children":19685},[19686,19687],{"id":5624,"depth":3931,"text":5625},{"id":6341,"depth":3931,"text":6342},{"id":6459,"depth":3921,"text":6460,"children":19689},[19690,19691,19692],{"id":6483,"depth":3931,"text":6484},{"id":6694,"depth":3931,"text":6695},{"id":6981,"depth":3931,"text":6982},{"id":7228,"depth":3921,"text":7229,"children":19694},[19695,19696,19697],{"id":7253,"depth":3931,"text":7254},{"id":7507,"depth":3931,"text":7508},{"id":7802,"depth":3931,"text":7803},{"id":8178,"depth":3921,"text":8179,"children":19699},[19700,19701,19702,19703],{"id":8185,"depth":3931,"text":8186},{"id":8547,"depth":3931,"text":8548},{"id":8846,"depth":3931,"text":8847},{"id":9215,"depth":3931,"text":9216},{"id":9845,"depth":3921,"text":9846,"children":19705},[19706,19707,19708,19709],{"id":9874,"depth":3931,"text":9875},{"id":10037,"depth":3931,"text":10038},{"id":10570,"depth":3931,"text":10571},{"id":10826,"depth":3931,"text":10827},{"id":11346,"depth":3921,"text":11347,"children":19711},[19712,19713,19714,19715],{"id":11365,"depth":3931,"text":11366},{"id":11566,"depth":3931,"text":11567},{"id":11962,"depth":3931,"text":11963},{"id":12298,"depth":3931,"text":12299},{"id":12547,"depth":3921,"text":12548,"children":19717},[19718],{"id":12959,"depth":3931,"text":12960},{"id":13636,"depth":3921,"text":13637,"children":19720},[19721,19722,19723],{"id":13657,"depth":3931,"text":13658},{"id":14235,"depth":3931,"text":14236},{"id":14682,"depth":3931,"text":14683},{"id":14853,"depth":3921,"text":14854,"children":19725},[19726,19727],{"id":14870,"depth":3931,"text":14871},{"id":15295,"depth":3931,"text":15296},{"id":15488,"depth":3921,"text":15489},{"id":16472,"depth":3921,"text":16473,"children":19730},[19731,19732],{"id":16497,"depth":3931,"text":16498},{"id":17071,"depth":3931,"text":17072},{"id":17335,"depth":3921,"text":17336,"children":19734},[19735,19736,19737],{"id":17342,"depth":3931,"text":17343},{"id":17378,"depth":3931,"text":17379},{"id":18823,"depth":3931,"text":18824},{"id":18913,"depth":3921,"text":18914,"children":19739},[19740,19741],{"id":18957,"depth":3931,"text":18958},{"id":19028,"depth":3931,"text":6342},"Інтерфейси, класи та об","md",null,{},{"title":3648,"description":19742},"H4XwOpCKRHZ38EIimMPLcm-jHOXRSbN_QOt0wI-5uB8",[19749,19751],{"title":3639,"path":3640,"stem":3641,"description":19750,"children":-1},"Глибокий розбір типізації функцій у TypeScript: параметри, повернення значень, опціональні параметри, rest parameters, перевантаження функцій та callback типізація",{"title":3652,"path":3653,"stem":3654,"description":19752,"children":-1},"Введення у Generic типи: параметризація типів, constraints та практичне використання",1788081815151]