[{"data":1,"prerenderedAt":18218},["ShallowReactive",2],{"navigation_docs":3,"-web-development-typescript-type-system-type-narrowing":3728,"-web-development-typescript-type-system-type-narrowing-surround":18213},[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":3635,"body":3730,"description":18207,"extension":18208,"links":18209,"meta":18210,"navigation":4152,"path":3636,"seo":18211,"stem":3637,"__hash__":18212},"docs\u002F18.web-development\u002F03.typescript-type-system\u002F05.type-narrowing.md",{"type":3731,"value":3732,"toc":18141},"minimark",[3733,3737,3829,3832,3837,3842,3846,3962,3991,3995,4008,4187,4213,4444,4448,4455,4482,4497,4499,4503,4507,4513,4730,4738,4770,4774,4780,5007,5012,5128,5132,5140,5292,5301,5439,5463,5467,5476,5499,5502,5504,5508,5512,5535,5540,5583,5589,5633,5777,5781,5789,5965,5970,5979,6140,6148,6258,6351,6355,6365,6559,6561,6565,6569,6580,6742,6747,6894,6898,6907,7052,7057,7131,7135,7141,7379,7397,7399,7403,7407,7412,7516,7520,7526,7754,7759,8012,8016,8028,8145,8152,8237,8239,8243,8247,8252,8513,8517,8523,8743,8748,8890,8894,8900,9120,9128,9134,9282,9309,9311,9315,9319,9325,9511,9514,9528,9532,9556,9728,9748,10060,10262,10266,10302,10306,10309,10736,10740,10743,10766,10769,10779,10781,10785,10789,10799,10964,10979,10983,11000,11158,11163,11213,11240,11244,11548,11552,11888,11892,12133,12269,12273,12276,12740,12742,12746,12750,12760,12953,12959,12963,12970,13179,13186,13190,13193,13316,13325,13470,13478,13507,13601,13605,13614,13793,13798,13864,13869,13925,14096,14098,14102,14106,14123,14311,14315,14373,14384,14388,14395,14571,14575,14903,14907,14913,15000,15008,15100,15115,15117,15121,15125,15920,15924,16502,16506,16845,16847,16851,16854,16859,16870,16875,16926,16931,16948,16953,16971,16975,16992,16997,17011,18137],[3734,3735,3635],"h1",{"id":3736},"type-narrowing-звуження-типів",[3738,3739,3740,3784],"card-group",{},[3741,3742,3745],"card",{"icon":3743,"title":3744},"i-lucide-target","🎯 Мета розділу",[3746,3747,3748,3757,3772,3775,3778,3781],"ul",{},[3749,3750,3751,3752,3756],"li",{},"Зрозуміти концепцію звуження типів (",[3753,3754,3755],"em",{},"type narrowing",") та її важливість.",[3749,3758,3759,3760,3764,3765,3764,3768,3771],{},"Освоїти різні техніки type guards: ",[3761,3762,3763],"code",{},"typeof",", ",[3761,3766,3767],{},"instanceof",[3761,3769,3770],{},"in",", equality checks.",[3749,3773,3774],{},"Навчитися використовувати truthiness та discriminated unions для безпечної роботи з типами.",[3749,3776,3777],{},"Опанувати control flow analysis TypeScript для автоматичного виведення типів.",[3749,3779,3780],{},"Усвідомити, як TypeScript відстежує потік виконання коду та звужує типи в різних гілках.",[3749,3782,3783],{},"Навчитися писати власні type guard функції для складних перевірок.",[3741,3785,3788],{"icon":3786,"title":3787},"i-lucide-key","🔑 Ключові терміни",[3746,3789,3790,3797,3803,3809,3815],{},[3749,3791,3792,3796],{},[3793,3794,3795],"strong",{},"Type Narrowing:"," процес уточнення типу з ширшого до вужчого всередині певного контексту.",[3749,3798,3799,3802],{},[3793,3800,3801],{},"Type Guard:"," вираз або функція, що дозволяє TypeScript звузити тип у певній гілці коду.",[3749,3804,3805,3808],{},[3793,3806,3807],{},"Control Flow Analysis:"," аналіз потоку виконання коду для автоматичного виведення типів.",[3749,3810,3811,3814],{},[3793,3812,3813],{},"Discriminated Union:"," union type з спільною властивістю-дискримінатором для розрізнення варіантів.",[3749,3816,3817,3820,3821,3824,3825,3828],{},[3793,3818,3819],{},"Truthiness:"," концепція JavaScript, де значення приводяться до ",[3761,3822,3823],{},"true"," або ",[3761,3826,3827],{},"false"," у логічному контексті.",[3830,3831],"hr",{},[3833,3834,3836],"h2",{"id":3835},"що-таке-type-narrowing","Що таке Type Narrowing",[3838,3839,3841],"h3",{"id":3840},"проблема-широких-типів","Проблема широких типів",[3843,3844,3845],"p",{},"У попередніх розділах ви вивчили union types, які дозволяють змінній мати один з кількох типів:",[3847,3848,3853],"pre",{"className":3849,"code":3850,"language":3851,"meta":3852,"style":3852},"language-typescript shiki shiki-themes light-plus dark-plus dark-plus","function processValue(value: string | number): void {\n  \u002F\u002F Тут TypeScript знає лише, що value — це string АБО number\n  \u002F\u002F Але не знає, який саме тип у конкретному виклику\n  \n  console.log(value.toUpperCase());  \u002F\u002F Error!\n  \u002F\u002F Property 'toUpperCase' does not exist on type 'string | number'.\n  \u002F\u002F Property 'toUpperCase' does not exist on type 'number'.\n}\n","typescript","",[3761,3854,3855,3898,3905,3911,3917,3944,3950,3956],{"__ignoreMap":3852},[3856,3857,3860,3864,3868,3872,3876,3879,3883,3886,3889,3892,3895],"span",{"class":3858,"line":3859},"line",1,[3856,3861,3863],{"class":3862},"su1O8","function",[3856,3865,3867],{"class":3866},"s8Opu"," processValue",[3856,3869,3871],{"class":3870},"sHH4Y","(",[3856,3873,3875],{"class":3874},"siwwj","value",[3856,3877,3878],{"class":3870},": ",[3856,3880,3882],{"class":3881},"sN1BT","string",[3856,3884,3885],{"class":3870}," | ",[3856,3887,3888],{"class":3881},"number",[3856,3890,3891],{"class":3870},"): ",[3856,3893,3894],{"class":3881},"void",[3856,3896,3897],{"class":3870}," {\n",[3856,3899,3901],{"class":3858,"line":3900},2,[3856,3902,3904],{"class":3903},"spJ8K","  \u002F\u002F Тут TypeScript знає лише, що value — це string АБО number\n",[3856,3906,3908],{"class":3858,"line":3907},3,[3856,3909,3910],{"class":3903},"  \u002F\u002F Але не знає, який саме тип у конкретному виклику\n",[3856,3912,3914],{"class":3858,"line":3913},4,[3856,3915,3916],{"class":3870},"  \n",[3856,3918,3920,3923,3926,3929,3931,3933,3935,3938,3941],{"class":3858,"line":3919},5,[3856,3921,3922],{"class":3874},"  console",[3856,3924,3925],{"class":3870},".",[3856,3927,3928],{"class":3866},"log",[3856,3930,3871],{"class":3870},[3856,3932,3875],{"class":3874},[3856,3934,3925],{"class":3870},[3856,3936,3937],{"class":3866},"toUpperCase",[3856,3939,3940],{"class":3870},"());  ",[3856,3942,3943],{"class":3903},"\u002F\u002F Error!\n",[3856,3945,3947],{"class":3858,"line":3946},6,[3856,3948,3949],{"class":3903},"  \u002F\u002F Property 'toUpperCase' does not exist on type 'string | number'.\n",[3856,3951,3953],{"class":3858,"line":3952},7,[3856,3954,3955],{"class":3903},"  \u002F\u002F Property 'toUpperCase' does not exist on type 'number'.\n",[3856,3957,3959],{"class":3858,"line":3958},8,[3856,3960,3961],{"class":3870},"}\n",[3843,3963,3964,3965,3968,3969,3971,3972,3974,3975,3977,3978,3981,3982,3985,3986,3988,3989,3925],{},"Проблема: метод ",[3761,3966,3967],{},"toUpperCase()"," існує лише для ",[3761,3970,3882],{},", але TypeScript не може його викликати, бо ",[3761,3973,3875],{}," може бути ",[3761,3976,3888],{},". Нам потрібен спосіб ",[3793,3979,3980],{},"звузити тип"," (",[3753,3983,3984],{},"narrow the type",") — переконати TypeScript, що в певній частині коду ",[3761,3987,3875],{}," точно є ",[3761,3990,3882],{},[3838,3992,3994],{"id":3993},"концепція-type-narrowing","Концепція Type Narrowing",[3843,3996,3997,3981,4000,4003,4004,4007],{},[3793,3998,3999],{},"Type Narrowing",[3753,4001,4002],{},"звуження типів",") — це процес, коли TypeScript ",[3793,4005,4006],{},"уточнює тип"," змінної з більш загального (wide type) до більш специфічного (narrow type) на основі перевірок у коді. Після звуження TypeScript дозволяє використовувати властивості та методи, специфічні для звуженого типу.",[3847,4009,4011],{"className":3849,"code":4010,"language":3851,"meta":3852,"style":3852},"function processValue(value: string | number): void {\n  \u002F\u002F Перевірка типу через typeof\n  if (typeof value === \"string\") {\n    \u002F\u002F У цій гілці TypeScript ЗНАЄ, що value — це string\n    console.log(value.toUpperCase());  \u002F\u002F OK! TypeScript звузив тип до string\n  } else {\n    \u002F\u002F У цій гілці TypeScript ЗНАЄ, що value — це number\n    console.log(value.toFixed(2));     \u002F\u002F OK! TypeScript звузив тип до number\n  }\n}\n\nprocessValue(\"hello\");  \u002F\u002F виведе \"HELLO\"\nprocessValue(42);       \u002F\u002F виведе \"42.00\"\n",[3761,4012,4013,4037,4042,4065,4070,4092,4102,4107,4136,4142,4147,4154,4171],{"__ignoreMap":3852},[3856,4014,4015,4017,4019,4021,4023,4025,4027,4029,4031,4033,4035],{"class":3858,"line":3859},[3856,4016,3863],{"class":3862},[3856,4018,3867],{"class":3866},[3856,4020,3871],{"class":3870},[3856,4022,3875],{"class":3874},[3856,4024,3878],{"class":3870},[3856,4026,3882],{"class":3881},[3856,4028,3885],{"class":3870},[3856,4030,3888],{"class":3881},[3856,4032,3891],{"class":3870},[3856,4034,3894],{"class":3881},[3856,4036,3897],{"class":3870},[3856,4038,4039],{"class":3858,"line":3900},[3856,4040,4041],{"class":3903},"  \u002F\u002F Перевірка типу через typeof\n",[3856,4043,4044,4048,4050,4052,4055,4058,4062],{"class":3858,"line":3907},[3856,4045,4047],{"class":4046},"s8xlr","  if",[3856,4049,3981],{"class":3870},[3856,4051,3763],{"class":3862},[3856,4053,4054],{"class":3874}," value",[3856,4056,4057],{"class":3870}," === ",[3856,4059,4061],{"class":4060},"sbdoH","\"string\"",[3856,4063,4064],{"class":3870},") {\n",[3856,4066,4067],{"class":3858,"line":3913},[3856,4068,4069],{"class":3903},"    \u002F\u002F У цій гілці TypeScript ЗНАЄ, що value — це string\n",[3856,4071,4072,4075,4077,4079,4081,4083,4085,4087,4089],{"class":3858,"line":3919},[3856,4073,4074],{"class":3874},"    console",[3856,4076,3925],{"class":3870},[3856,4078,3928],{"class":3866},[3856,4080,3871],{"class":3870},[3856,4082,3875],{"class":3874},[3856,4084,3925],{"class":3870},[3856,4086,3937],{"class":3866},[3856,4088,3940],{"class":3870},[3856,4090,4091],{"class":3903},"\u002F\u002F OK! TypeScript звузив тип до string\n",[3856,4093,4094,4097,4100],{"class":3858,"line":3946},[3856,4095,4096],{"class":3870},"  } ",[3856,4098,4099],{"class":4046},"else",[3856,4101,3897],{"class":3870},[3856,4103,4104],{"class":3858,"line":3952},[3856,4105,4106],{"class":3903},"    \u002F\u002F У цій гілці TypeScript ЗНАЄ, що value — це number\n",[3856,4108,4109,4111,4113,4115,4117,4119,4121,4124,4126,4130,4133],{"class":3858,"line":3958},[3856,4110,4074],{"class":3874},[3856,4112,3925],{"class":3870},[3856,4114,3928],{"class":3866},[3856,4116,3871],{"class":3870},[3856,4118,3875],{"class":3874},[3856,4120,3925],{"class":3870},[3856,4122,4123],{"class":3866},"toFixed",[3856,4125,3871],{"class":3870},[3856,4127,4129],{"class":4128},"sJj4R","2",[3856,4131,4132],{"class":3870},"));     ",[3856,4134,4135],{"class":3903},"\u002F\u002F OK! TypeScript звузив тип до number\n",[3856,4137,4139],{"class":3858,"line":4138},9,[3856,4140,4141],{"class":3870},"  }\n",[3856,4143,4145],{"class":3858,"line":4144},10,[3856,4146,3961],{"class":3870},[3856,4148,4150],{"class":3858,"line":4149},11,[3856,4151,4153],{"emptyLinePlaceholder":4152},true,"\n",[3856,4155,4157,4160,4162,4165,4168],{"class":3858,"line":4156},12,[3856,4158,4159],{"class":3866},"processValue",[3856,4161,3871],{"class":3870},[3856,4163,4164],{"class":4060},"\"hello\"",[3856,4166,4167],{"class":3870},");  ",[3856,4169,4170],{"class":3903},"\u002F\u002F виведе \"HELLO\"\n",[3856,4172,4174,4176,4178,4181,4184],{"class":3858,"line":4173},13,[3856,4175,4159],{"class":3866},[3856,4177,3871],{"class":3870},[3856,4179,4180],{"class":4128},"42",[3856,4182,4183],{"class":3870},");       ",[3856,4185,4186],{"class":3903},"\u002F\u002F виведе \"42.00\"\n",[3843,4188,4189,4190,4193,4194,4197,4198,4201,4202,4204,4205,4207,4208,4210,4211,3925],{},"Після перевірки ",[3761,4191,4192],{},"typeof value === \"string\""," TypeScript ",[3793,4195,4196],{},"гарантує",", що всередині блоку ",[3761,4199,4200],{},"if"," змінна ",[3761,4203,3875],{}," має тип ",[3761,4206,3882],{},", а в блоці ",[3761,4209,4099],{}," — тип ",[3761,4212,3888],{},[4214,4215,4217],"plant-uml",{"alt":4216},"Концепція звуження типу від широкого до вузького",[3847,4218,4222],{"className":4219,"code":4220,"language":4221,"meta":3852,"style":3852},"language-plantuml shiki shiki-themes light-plus dark-plus dark-plus","@startuml\nskinparam style plain\nskinparam backgroundColor #FFFFFF\n\nrectangle \"Початковий тип:\\nstring | number\" as Wide #FCA5A5 {\n    note bottom\n    TypeScript знає лише,\n    що value може бути\n    string або number\n    end note\n}\n\nrectangle \"Перевірка:\\ntypeof value === 'string'\" as Check #FBBF24\n\nrectangle \"Звужений тип у блоці if:\\nstring\" as NarrowString #86EFAC {\n    note bottom\n    TypeScript тепер знає,\n    що value точно string.\n    Доступні методи: toUpperCase(),\n    slice(), charAt() тощо\n    end note\n}\n\nrectangle \"Звужений тип у блоці else:\\nnumber\" as NarrowNumber #93C5FD {\n    note bottom\n    TypeScript знає,\n    що value точно number.\n    Доступні методи: toFixed(),\n    toPrecision() тощо\n    end note\n}\n\nWide -down-> Check\nCheck -down-> NarrowString : if (true)\nCheck -down-> NarrowNumber : else (false)\n\nnote right of Check\n  Type guard відділяє\n  один тип від іншого\nend note\n@enduml\n","plantuml",[3761,4223,4224,4229,4234,4239,4243,4248,4253,4258,4263,4268,4273,4277,4281,4286,4291,4297,4302,4308,4314,4320,4326,4331,4336,4341,4347,4352,4358,4364,4370,4376,4381,4386,4391,4397,4403,4409,4414,4420,4426,4432,4438],{"__ignoreMap":3852},[3856,4225,4226],{"class":3858,"line":3859},[3856,4227,4228],{},"@startuml\n",[3856,4230,4231],{"class":3858,"line":3900},[3856,4232,4233],{},"skinparam style plain\n",[3856,4235,4236],{"class":3858,"line":3907},[3856,4237,4238],{},"skinparam backgroundColor #FFFFFF\n",[3856,4240,4241],{"class":3858,"line":3913},[3856,4242,4153],{"emptyLinePlaceholder":4152},[3856,4244,4245],{"class":3858,"line":3919},[3856,4246,4247],{},"rectangle \"Початковий тип:\\nstring | number\" as Wide #FCA5A5 {\n",[3856,4249,4250],{"class":3858,"line":3946},[3856,4251,4252],{},"    note bottom\n",[3856,4254,4255],{"class":3858,"line":3952},[3856,4256,4257],{},"    TypeScript знає лише,\n",[3856,4259,4260],{"class":3858,"line":3958},[3856,4261,4262],{},"    що value може бути\n",[3856,4264,4265],{"class":3858,"line":4138},[3856,4266,4267],{},"    string або number\n",[3856,4269,4270],{"class":3858,"line":4144},[3856,4271,4272],{},"    end note\n",[3856,4274,4275],{"class":3858,"line":4149},[3856,4276,3961],{},[3856,4278,4279],{"class":3858,"line":4156},[3856,4280,4153],{"emptyLinePlaceholder":4152},[3856,4282,4283],{"class":3858,"line":4173},[3856,4284,4285],{},"rectangle \"Перевірка:\\ntypeof value === 'string'\" as Check #FBBF24\n",[3856,4287,4289],{"class":3858,"line":4288},14,[3856,4290,4153],{"emptyLinePlaceholder":4152},[3856,4292,4294],{"class":3858,"line":4293},15,[3856,4295,4296],{},"rectangle \"Звужений тип у блоці if:\\nstring\" as NarrowString #86EFAC {\n",[3856,4298,4300],{"class":3858,"line":4299},16,[3856,4301,4252],{},[3856,4303,4305],{"class":3858,"line":4304},17,[3856,4306,4307],{},"    TypeScript тепер знає,\n",[3856,4309,4311],{"class":3858,"line":4310},18,[3856,4312,4313],{},"    що value точно string.\n",[3856,4315,4317],{"class":3858,"line":4316},19,[3856,4318,4319],{},"    Доступні методи: toUpperCase(),\n",[3856,4321,4323],{"class":3858,"line":4322},20,[3856,4324,4325],{},"    slice(), charAt() тощо\n",[3856,4327,4329],{"class":3858,"line":4328},21,[3856,4330,4272],{},[3856,4332,4334],{"class":3858,"line":4333},22,[3856,4335,3961],{},[3856,4337,4339],{"class":3858,"line":4338},23,[3856,4340,4153],{"emptyLinePlaceholder":4152},[3856,4342,4344],{"class":3858,"line":4343},24,[3856,4345,4346],{},"rectangle \"Звужений тип у блоці else:\\nnumber\" as NarrowNumber #93C5FD {\n",[3856,4348,4350],{"class":3858,"line":4349},25,[3856,4351,4252],{},[3856,4353,4355],{"class":3858,"line":4354},26,[3856,4356,4357],{},"    TypeScript знає,\n",[3856,4359,4361],{"class":3858,"line":4360},27,[3856,4362,4363],{},"    що value точно number.\n",[3856,4365,4367],{"class":3858,"line":4366},28,[3856,4368,4369],{},"    Доступні методи: toFixed(),\n",[3856,4371,4373],{"class":3858,"line":4372},29,[3856,4374,4375],{},"    toPrecision() тощо\n",[3856,4377,4379],{"class":3858,"line":4378},30,[3856,4380,4272],{},[3856,4382,4384],{"class":3858,"line":4383},31,[3856,4385,3961],{},[3856,4387,4389],{"class":3858,"line":4388},32,[3856,4390,4153],{"emptyLinePlaceholder":4152},[3856,4392,4394],{"class":3858,"line":4393},33,[3856,4395,4396],{},"Wide -down-> Check\n",[3856,4398,4400],{"class":3858,"line":4399},34,[3856,4401,4402],{},"Check -down-> NarrowString : if (true)\n",[3856,4404,4406],{"class":3858,"line":4405},35,[3856,4407,4408],{},"Check -down-> NarrowNumber : else (false)\n",[3856,4410,4412],{"class":3858,"line":4411},36,[3856,4413,4153],{"emptyLinePlaceholder":4152},[3856,4415,4417],{"class":3858,"line":4416},37,[3856,4418,4419],{},"note right of Check\n",[3856,4421,4423],{"class":3858,"line":4422},38,[3856,4424,4425],{},"  Type guard відділяє\n",[3856,4427,4429],{"class":3858,"line":4428},39,[3856,4430,4431],{},"  один тип від іншого\n",[3856,4433,4435],{"class":3858,"line":4434},40,[3856,4436,4437],{},"end note\n",[3856,4439,4441],{"class":3858,"line":4440},41,[3856,4442,4443],{},"@enduml\n",[3838,4445,4447],{"id":4446},"чому-type-narrowing-критично-важливий","Чому Type Narrowing критично важливий",[3843,4449,4450,4451,4454],{},"Type narrowing — це не просто синтаксична особливість TypeScript. Це ",[3793,4452,4453],{},"фундаментальний механізм",", що дозволяє:",[4456,4457,4458,4464,4470,4476],"ol",{},[3749,4459,4460,4463],{},[3793,4461,4462],{},"Безпечно працювати з union types:"," без звуження union types майже марні — ви не можете викликати жодних специфічних методів.",[3749,4465,4466,4469],{},[3793,4467,4468],{},"Уникати runtime помилок:"," перевірки типів змушують вас обробляти всі можливі варіанти, а TypeScript гарантує, що ви нічого не пропустили.",[3749,4471,4472,4475],{},[3793,4473,4474],{},"Писати виразний код:"," перевірки типів документують ваші наміри та роблять код більш читабельним.",[3749,4477,4478,4481],{},[3793,4479,4480],{},"Отримувати автодоповнення в IDE:"," після звуження типу IDE показує лише релевантні властивості та методи.",[4483,4484,4485,4486,4489,4490,4493,4494,4496],"note",{},"У JavaScript ви теж пишете перевірки типів (наприклад, ",[3761,4487,4488],{},"if (typeof x === \"string\")","), але JavaScript не дає жодних гарантій щодо коректності вашого коду. TypeScript ",[3793,4491,4492],{},"відстежує"," ці перевірки та ",[3793,4495,4196],{}," типобезпеку на етапі компіляції.",[3830,4498],{},[3833,4500,4502],{"id":4501},"typeof-type-guards","Typeof Type Guards",[3838,4504,4506],{"id":4505},"оператор-typeof-у-javascript","Оператор typeof у JavaScript",[3843,4508,4509,4510,4512],{},"У JavaScript оператор ",[3761,4511,3763],{}," повертає рядок, що описує тип значення:",[3847,4514,4518],{"className":4515,"code":4516,"language":4517,"meta":3852,"style":3852},"language-javascript shiki shiki-themes light-plus dark-plus dark-plus","console.log(typeof \"hello\");       \u002F\u002F \"string\"\nconsole.log(typeof 42);            \u002F\u002F \"number\"\nconsole.log(typeof true);          \u002F\u002F \"boolean\"\nconsole.log(typeof undefined);     \u002F\u002F \"undefined\"\nconsole.log(typeof Symbol(\"id\"));  \u002F\u002F \"symbol\"\nconsole.log(typeof 123n);          \u002F\u002F \"bigint\"\nconsole.log(typeof {});            \u002F\u002F \"object\"\nconsole.log(typeof []);            \u002F\u002F \"object\" (масиви теж є об'єктами!)\nconsole.log(typeof null);          \u002F\u002F \"object\" (історична помилка JS!)\nconsole.log(typeof function(){}); \u002F\u002F \"function\"\n","javascript",[3761,4519,4520,4541,4562,4583,4604,4630,4653,4671,4689,4709],{"__ignoreMap":3852},[3856,4521,4522,4525,4527,4529,4531,4533,4536,4538],{"class":3858,"line":3859},[3856,4523,4524],{"class":3874},"console",[3856,4526,3925],{"class":3870},[3856,4528,3928],{"class":3866},[3856,4530,3871],{"class":3870},[3856,4532,3763],{"class":3862},[3856,4534,4535],{"class":4060}," \"hello\"",[3856,4537,4183],{"class":3870},[3856,4539,4540],{"class":3903},"\u002F\u002F \"string\"\n",[3856,4542,4543,4545,4547,4549,4551,4553,4556,4559],{"class":3858,"line":3900},[3856,4544,4524],{"class":3874},[3856,4546,3925],{"class":3870},[3856,4548,3928],{"class":3866},[3856,4550,3871],{"class":3870},[3856,4552,3763],{"class":3862},[3856,4554,4555],{"class":4128}," 42",[3856,4557,4558],{"class":3870},");            ",[3856,4560,4561],{"class":3903},"\u002F\u002F \"number\"\n",[3856,4563,4564,4566,4568,4570,4572,4574,4577,4580],{"class":3858,"line":3907},[3856,4565,4524],{"class":3874},[3856,4567,3925],{"class":3870},[3856,4569,3928],{"class":3866},[3856,4571,3871],{"class":3870},[3856,4573,3763],{"class":3862},[3856,4575,4576],{"class":3862}," true",[3856,4578,4579],{"class":3870},");          ",[3856,4581,4582],{"class":3903},"\u002F\u002F \"boolean\"\n",[3856,4584,4585,4587,4589,4591,4593,4595,4598,4601],{"class":3858,"line":3913},[3856,4586,4524],{"class":3874},[3856,4588,3925],{"class":3870},[3856,4590,3928],{"class":3866},[3856,4592,3871],{"class":3870},[3856,4594,3763],{"class":3862},[3856,4596,4597],{"class":3862}," undefined",[3856,4599,4600],{"class":3870},");     ",[3856,4602,4603],{"class":3903},"\u002F\u002F \"undefined\"\n",[3856,4605,4606,4608,4610,4612,4614,4616,4619,4621,4624,4627],{"class":3858,"line":3919},[3856,4607,4524],{"class":3874},[3856,4609,3925],{"class":3870},[3856,4611,3928],{"class":3866},[3856,4613,3871],{"class":3870},[3856,4615,3763],{"class":3862},[3856,4617,4618],{"class":3866}," Symbol",[3856,4620,3871],{"class":3870},[3856,4622,4623],{"class":4060},"\"id\"",[3856,4625,4626],{"class":3870},"));  ",[3856,4628,4629],{"class":3903},"\u002F\u002F \"symbol\"\n",[3856,4631,4632,4634,4636,4638,4640,4642,4645,4648,4650],{"class":3858,"line":3946},[3856,4633,4524],{"class":3874},[3856,4635,3925],{"class":3870},[3856,4637,3928],{"class":3866},[3856,4639,3871],{"class":3870},[3856,4641,3763],{"class":3862},[3856,4643,4644],{"class":4128}," 123",[3856,4646,4647],{"class":3862},"n",[3856,4649,4579],{"class":3870},[3856,4651,4652],{"class":3903},"\u002F\u002F \"bigint\"\n",[3856,4654,4655,4657,4659,4661,4663,4665,4668],{"class":3858,"line":3952},[3856,4656,4524],{"class":3874},[3856,4658,3925],{"class":3870},[3856,4660,3928],{"class":3866},[3856,4662,3871],{"class":3870},[3856,4664,3763],{"class":3862},[3856,4666,4667],{"class":3870}," {});            ",[3856,4669,4670],{"class":3903},"\u002F\u002F \"object\"\n",[3856,4672,4673,4675,4677,4679,4681,4683,4686],{"class":3858,"line":3958},[3856,4674,4524],{"class":3874},[3856,4676,3925],{"class":3870},[3856,4678,3928],{"class":3866},[3856,4680,3871],{"class":3870},[3856,4682,3763],{"class":3862},[3856,4684,4685],{"class":3870}," []);            ",[3856,4687,4688],{"class":3903},"\u002F\u002F \"object\" (масиви теж є об'єктами!)\n",[3856,4690,4691,4693,4695,4697,4699,4701,4704,4706],{"class":3858,"line":4138},[3856,4692,4524],{"class":3874},[3856,4694,3925],{"class":3870},[3856,4696,3928],{"class":3866},[3856,4698,3871],{"class":3870},[3856,4700,3763],{"class":3862},[3856,4702,4703],{"class":3862}," null",[3856,4705,4579],{"class":3870},[3856,4707,4708],{"class":3903},"\u002F\u002F \"object\" (історична помилка JS!)\n",[3856,4710,4711,4713,4715,4717,4719,4721,4724,4727],{"class":3858,"line":4144},[3856,4712,4524],{"class":3874},[3856,4714,3925],{"class":3870},[3856,4716,3928],{"class":3866},[3856,4718,3871],{"class":3870},[3856,4720,3763],{"class":3862},[3856,4722,4723],{"class":3862}," function",[3856,4725,4726],{"class":3870},"(){}); ",[3856,4728,4729],{"class":3903},"\u002F\u002F \"function\"\n",[3843,4731,4732],{},[3793,4733,4734,4735,4737],{},"Важливі особливості ",[3761,4736,3763],{},":",[3746,4739,4740,4754,4763],{},[3749,4741,4742,4745,4746,4749,4750,4753],{},[3761,4743,4744],{},"typeof null"," повертає ",[3761,4747,4748],{},"\"object\""," — це ",[3793,4751,4752],{},"історична помилка"," JavaScript, що залишилася для зворотної сумісності.",[3749,4755,4756,4757,4759,4760,4762],{},"Масиви та об'єкти повертають ",[3761,4758,4748],{}," — ",[3761,4761,3763],{}," не розрізняє їх.",[3749,4764,4765,4766,4769],{},"Функції повертають ",[3761,4767,4768],{},"\"function\"",", хоча технічно вони теж є об'єктами.",[3838,4771,4773],{"id":4772},"typeof-як-type-guard-у-typescript","Typeof як Type Guard у TypeScript",[3843,4775,4776,4777,4779],{},"TypeScript розуміє ",[3761,4778,3763],{}," та використовує його для звуження типів:",[3847,4781,4783],{"className":3849,"code":4782,"language":3851,"meta":3852,"style":3852},"function format(value: string | number | boolean): string {\n  if (typeof value === \"string\") {\n    \u002F\u002F Тип звужено до string\n    return value.toUpperCase();\n  }\n  \n  if (typeof value === \"number\") {\n    \u002F\u002F Тип звужено до number\n    return value.toFixed(2);\n  }\n  \n  \u002F\u002F Тут TypeScript знає, що value — це boolean\n  return value ? \"Yes\" : \"No\";\n}\n\nconsole.log(format(\"hello\"));   \u002F\u002F \"HELLO\"\nconsole.log(format(3.14159));   \u002F\u002F \"3.14\"\nconsole.log(format(true));      \u002F\u002F \"Yes\"\n",[3761,4784,4785,4815,4831,4836,4850,4854,4858,4875,4880,4897,4901,4905,4910,4932,4936,4940,4963,4985],{"__ignoreMap":3852},[3856,4786,4787,4789,4792,4794,4796,4798,4800,4802,4804,4806,4809,4811,4813],{"class":3858,"line":3859},[3856,4788,3863],{"class":3862},[3856,4790,4791],{"class":3866}," format",[3856,4793,3871],{"class":3870},[3856,4795,3875],{"class":3874},[3856,4797,3878],{"class":3870},[3856,4799,3882],{"class":3881},[3856,4801,3885],{"class":3870},[3856,4803,3888],{"class":3881},[3856,4805,3885],{"class":3870},[3856,4807,4808],{"class":3881},"boolean",[3856,4810,3891],{"class":3870},[3856,4812,3882],{"class":3881},[3856,4814,3897],{"class":3870},[3856,4816,4817,4819,4821,4823,4825,4827,4829],{"class":3858,"line":3900},[3856,4818,4047],{"class":4046},[3856,4820,3981],{"class":3870},[3856,4822,3763],{"class":3862},[3856,4824,4054],{"class":3874},[3856,4826,4057],{"class":3870},[3856,4828,4061],{"class":4060},[3856,4830,4064],{"class":3870},[3856,4832,4833],{"class":3858,"line":3907},[3856,4834,4835],{"class":3903},"    \u002F\u002F Тип звужено до string\n",[3856,4837,4838,4841,4843,4845,4847],{"class":3858,"line":3913},[3856,4839,4840],{"class":4046},"    return",[3856,4842,4054],{"class":3874},[3856,4844,3925],{"class":3870},[3856,4846,3937],{"class":3866},[3856,4848,4849],{"class":3870},"();\n",[3856,4851,4852],{"class":3858,"line":3919},[3856,4853,4141],{"class":3870},[3856,4855,4856],{"class":3858,"line":3946},[3856,4857,3916],{"class":3870},[3856,4859,4860,4862,4864,4866,4868,4870,4873],{"class":3858,"line":3952},[3856,4861,4047],{"class":4046},[3856,4863,3981],{"class":3870},[3856,4865,3763],{"class":3862},[3856,4867,4054],{"class":3874},[3856,4869,4057],{"class":3870},[3856,4871,4872],{"class":4060},"\"number\"",[3856,4874,4064],{"class":3870},[3856,4876,4877],{"class":3858,"line":3958},[3856,4878,4879],{"class":3903},"    \u002F\u002F Тип звужено до number\n",[3856,4881,4882,4884,4886,4888,4890,4892,4894],{"class":3858,"line":4138},[3856,4883,4840],{"class":4046},[3856,4885,4054],{"class":3874},[3856,4887,3925],{"class":3870},[3856,4889,4123],{"class":3866},[3856,4891,3871],{"class":3870},[3856,4893,4129],{"class":4128},[3856,4895,4896],{"class":3870},");\n",[3856,4898,4899],{"class":3858,"line":4144},[3856,4900,4141],{"class":3870},[3856,4902,4903],{"class":3858,"line":4149},[3856,4904,3916],{"class":3870},[3856,4906,4907],{"class":3858,"line":4156},[3856,4908,4909],{"class":3903},"  \u002F\u002F Тут TypeScript знає, що value — це boolean\n",[3856,4911,4912,4915,4917,4920,4923,4926,4929],{"class":3858,"line":4173},[3856,4913,4914],{"class":4046},"  return",[3856,4916,4054],{"class":3874},[3856,4918,4919],{"class":3870}," ? ",[3856,4921,4922],{"class":4060},"\"Yes\"",[3856,4924,4925],{"class":3870}," : ",[3856,4927,4928],{"class":4060},"\"No\"",[3856,4930,4931],{"class":3870},";\n",[3856,4933,4934],{"class":3858,"line":4288},[3856,4935,3961],{"class":3870},[3856,4937,4938],{"class":3858,"line":4293},[3856,4939,4153],{"emptyLinePlaceholder":4152},[3856,4941,4942,4944,4946,4948,4950,4953,4955,4957,4960],{"class":3858,"line":4299},[3856,4943,4524],{"class":3874},[3856,4945,3925],{"class":3870},[3856,4947,3928],{"class":3866},[3856,4949,3871],{"class":3870},[3856,4951,4952],{"class":3866},"format",[3856,4954,3871],{"class":3870},[3856,4956,4164],{"class":4060},[3856,4958,4959],{"class":3870},"));   ",[3856,4961,4962],{"class":3903},"\u002F\u002F \"HELLO\"\n",[3856,4964,4965,4967,4969,4971,4973,4975,4977,4980,4982],{"class":3858,"line":4304},[3856,4966,4524],{"class":3874},[3856,4968,3925],{"class":3870},[3856,4970,3928],{"class":3866},[3856,4972,3871],{"class":3870},[3856,4974,4952],{"class":3866},[3856,4976,3871],{"class":3870},[3856,4978,4979],{"class":4128},"3.14159",[3856,4981,4959],{"class":3870},[3856,4983,4984],{"class":3903},"\u002F\u002F \"3.14\"\n",[3856,4986,4987,4989,4991,4993,4995,4997,4999,5001,5004],{"class":3858,"line":4310},[3856,4988,4524],{"class":3874},[3856,4990,3925],{"class":3870},[3856,4992,3928],{"class":3866},[3856,4994,3871],{"class":3870},[3856,4996,4952],{"class":3866},[3856,4998,3871],{"class":3870},[3856,5000,3823],{"class":3862},[3856,5002,5003],{"class":3870},"));      ",[3856,5005,5006],{"class":3903},"\u002F\u002F \"Yes\"\n",[3843,5008,5009],{},[3793,5010,5011],{},"TypeScript відстежує гілки коду:",[3847,5013,5015],{"className":3849,"code":5014,"language":3851,"meta":3852,"style":3852},"function example(x: string | number): void {\n  if (typeof x === \"string\") {\n    \u002F\u002F У цій гілці x: string\n    console.log(x.toUpperCase());\n  } else {\n    \u002F\u002F У цій гілці x: number (бо якщо не string, то number)\n    console.log(x.toFixed(2));\n  }\n}\n",[3761,5016,5017,5043,5060,5065,5084,5092,5097,5120,5124],{"__ignoreMap":3852},[3856,5018,5019,5021,5024,5026,5029,5031,5033,5035,5037,5039,5041],{"class":3858,"line":3859},[3856,5020,3863],{"class":3862},[3856,5022,5023],{"class":3866}," example",[3856,5025,3871],{"class":3870},[3856,5027,5028],{"class":3874},"x",[3856,5030,3878],{"class":3870},[3856,5032,3882],{"class":3881},[3856,5034,3885],{"class":3870},[3856,5036,3888],{"class":3881},[3856,5038,3891],{"class":3870},[3856,5040,3894],{"class":3881},[3856,5042,3897],{"class":3870},[3856,5044,5045,5047,5049,5051,5054,5056,5058],{"class":3858,"line":3900},[3856,5046,4047],{"class":4046},[3856,5048,3981],{"class":3870},[3856,5050,3763],{"class":3862},[3856,5052,5053],{"class":3874}," x",[3856,5055,4057],{"class":3870},[3856,5057,4061],{"class":4060},[3856,5059,4064],{"class":3870},[3856,5061,5062],{"class":3858,"line":3907},[3856,5063,5064],{"class":3903},"    \u002F\u002F У цій гілці x: string\n",[3856,5066,5067,5069,5071,5073,5075,5077,5079,5081],{"class":3858,"line":3913},[3856,5068,4074],{"class":3874},[3856,5070,3925],{"class":3870},[3856,5072,3928],{"class":3866},[3856,5074,3871],{"class":3870},[3856,5076,5028],{"class":3874},[3856,5078,3925],{"class":3870},[3856,5080,3937],{"class":3866},[3856,5082,5083],{"class":3870},"());\n",[3856,5085,5086,5088,5090],{"class":3858,"line":3919},[3856,5087,4096],{"class":3870},[3856,5089,4099],{"class":4046},[3856,5091,3897],{"class":3870},[3856,5093,5094],{"class":3858,"line":3946},[3856,5095,5096],{"class":3903},"    \u002F\u002F У цій гілці x: number (бо якщо не string, то number)\n",[3856,5098,5099,5101,5103,5105,5107,5109,5111,5113,5115,5117],{"class":3858,"line":3952},[3856,5100,4074],{"class":3874},[3856,5102,3925],{"class":3870},[3856,5104,3928],{"class":3866},[3856,5106,3871],{"class":3870},[3856,5108,5028],{"class":3874},[3856,5110,3925],{"class":3870},[3856,5112,4123],{"class":3866},[3856,5114,3871],{"class":3870},[3856,5116,4129],{"class":4128},[3856,5118,5119],{"class":3870},"));\n",[3856,5121,5122],{"class":3858,"line":3958},[3856,5123,4141],{"class":3870},[3856,5125,5126],{"class":3858,"line":4138},[3856,5127,3961],{"class":3870},[3838,5129,5131],{"id":5130},"перевірка-на-undefined-та-null","Перевірка на undefined та null",[3843,5133,5134,5136,5137,4737],{},[3761,5135,3763],{}," корисний для перевірки на ",[3761,5138,5139],{},"undefined",[3847,5141,5143],{"className":3849,"code":5142,"language":3851,"meta":3852,"style":3852},"function printLength(text: string | undefined): void {\n  if (typeof text === \"undefined\") {\n    console.log(\"No text provided\");\n    return;\n  }\n  \n  \u002F\u002F Тут text: string (undefined виключено)\n  console.log(`Length: ${text.length}`);\n}\n\nprintLength(\"hello\");      \u002F\u002F \"Length: 5\"\nprintLength(undefined);    \u002F\u002F \"No text provided\"\n",[3761,5144,5145,5171,5189,5204,5210,5214,5218,5223,5255,5259,5263,5278],{"__ignoreMap":3852},[3856,5146,5147,5149,5152,5154,5157,5159,5161,5163,5165,5167,5169],{"class":3858,"line":3859},[3856,5148,3863],{"class":3862},[3856,5150,5151],{"class":3866}," printLength",[3856,5153,3871],{"class":3870},[3856,5155,5156],{"class":3874},"text",[3856,5158,3878],{"class":3870},[3856,5160,3882],{"class":3881},[3856,5162,3885],{"class":3870},[3856,5164,5139],{"class":3881},[3856,5166,3891],{"class":3870},[3856,5168,3894],{"class":3881},[3856,5170,3897],{"class":3870},[3856,5172,5173,5175,5177,5179,5182,5184,5187],{"class":3858,"line":3900},[3856,5174,4047],{"class":4046},[3856,5176,3981],{"class":3870},[3856,5178,3763],{"class":3862},[3856,5180,5181],{"class":3874}," text",[3856,5183,4057],{"class":3870},[3856,5185,5186],{"class":4060},"\"undefined\"",[3856,5188,4064],{"class":3870},[3856,5190,5191,5193,5195,5197,5199,5202],{"class":3858,"line":3907},[3856,5192,4074],{"class":3874},[3856,5194,3925],{"class":3870},[3856,5196,3928],{"class":3866},[3856,5198,3871],{"class":3870},[3856,5200,5201],{"class":4060},"\"No text provided\"",[3856,5203,4896],{"class":3870},[3856,5205,5206,5208],{"class":3858,"line":3913},[3856,5207,4840],{"class":4046},[3856,5209,4931],{"class":3870},[3856,5211,5212],{"class":3858,"line":3919},[3856,5213,4141],{"class":3870},[3856,5215,5216],{"class":3858,"line":3946},[3856,5217,3916],{"class":3870},[3856,5219,5220],{"class":3858,"line":3952},[3856,5221,5222],{"class":3903},"  \u002F\u002F Тут text: string (undefined виключено)\n",[3856,5224,5225,5227,5229,5231,5233,5236,5239,5241,5244,5247,5250,5253],{"class":3858,"line":3958},[3856,5226,3922],{"class":3874},[3856,5228,3925],{"class":3870},[3856,5230,3928],{"class":3866},[3856,5232,3871],{"class":3870},[3856,5234,5235],{"class":4060},"`Length: ",[3856,5237,5238],{"class":3862},"${",[3856,5240,5156],{"class":3874},[3856,5242,3925],{"class":5243},"sD7JJ",[3856,5245,5246],{"class":3874},"length",[3856,5248,5249],{"class":3862},"}",[3856,5251,5252],{"class":4060},"`",[3856,5254,4896],{"class":3870},[3856,5256,5257],{"class":3858,"line":4138},[3856,5258,3961],{"class":3870},[3856,5260,5261],{"class":3858,"line":4144},[3856,5262,4153],{"emptyLinePlaceholder":4152},[3856,5264,5265,5268,5270,5272,5275],{"class":3858,"line":4149},[3856,5266,5267],{"class":3866},"printLength",[3856,5269,3871],{"class":3870},[3856,5271,4164],{"class":4060},[3856,5273,5274],{"class":3870},");      ",[3856,5276,5277],{"class":3903},"\u002F\u002F \"Length: 5\"\n",[3856,5279,5280,5282,5284,5286,5289],{"class":3858,"line":4156},[3856,5281,5267],{"class":3866},[3856,5283,3871],{"class":3870},[3856,5285,5139],{"class":3862},[3856,5287,5288],{"class":3870},");    ",[3856,5290,5291],{"class":3903},"\u002F\u002F \"No text provided\"\n",[3843,5293,5294],{},[3793,5295,5296,5297,5300],{},"Але для ",[3761,5298,5299],{},"null"," typeof не спрацює коректно:",[3847,5302,5304],{"className":3849,"code":5303,"language":3851,"meta":3852,"style":3852},"function example(value: string | null): void {\n  if (typeof value === \"null\") {  \u002F\u002F ❌ Неправильно!\n    \u002F\u002F typeof null === \"object\", а не \"null\"!\n  }\n  \n  \u002F\u002F ✅ Правильно: перевірка через ===\n  if (value === null) {\n    console.log(\"Value is null\");\n    return;\n  }\n  \n  \u002F\u002F Тут value: string\n  console.log(value.toUpperCase());\n}\n",[3761,5305,5306,5330,5351,5356,5360,5364,5369,5383,5398,5404,5408,5412,5417,5435],{"__ignoreMap":3852},[3856,5307,5308,5310,5312,5314,5316,5318,5320,5322,5324,5326,5328],{"class":3858,"line":3859},[3856,5309,3863],{"class":3862},[3856,5311,5023],{"class":3866},[3856,5313,3871],{"class":3870},[3856,5315,3875],{"class":3874},[3856,5317,3878],{"class":3870},[3856,5319,3882],{"class":3881},[3856,5321,3885],{"class":3870},[3856,5323,5299],{"class":3881},[3856,5325,3891],{"class":3870},[3856,5327,3894],{"class":3881},[3856,5329,3897],{"class":3870},[3856,5331,5332,5334,5336,5338,5340,5342,5345,5348],{"class":3858,"line":3900},[3856,5333,4047],{"class":4046},[3856,5335,3981],{"class":3870},[3856,5337,3763],{"class":3862},[3856,5339,4054],{"class":3874},[3856,5341,4057],{"class":3870},[3856,5343,5344],{"class":4060},"\"null\"",[3856,5346,5347],{"class":3870},") {  ",[3856,5349,5350],{"class":3903},"\u002F\u002F ❌ Неправильно!\n",[3856,5352,5353],{"class":3858,"line":3907},[3856,5354,5355],{"class":3903},"    \u002F\u002F typeof null === \"object\", а не \"null\"!\n",[3856,5357,5358],{"class":3858,"line":3913},[3856,5359,4141],{"class":3870},[3856,5361,5362],{"class":3858,"line":3919},[3856,5363,3916],{"class":3870},[3856,5365,5366],{"class":3858,"line":3946},[3856,5367,5368],{"class":3903},"  \u002F\u002F ✅ Правильно: перевірка через ===\n",[3856,5370,5371,5373,5375,5377,5379,5381],{"class":3858,"line":3952},[3856,5372,4047],{"class":4046},[3856,5374,3981],{"class":3870},[3856,5376,3875],{"class":3874},[3856,5378,4057],{"class":3870},[3856,5380,5299],{"class":3862},[3856,5382,4064],{"class":3870},[3856,5384,5385,5387,5389,5391,5393,5396],{"class":3858,"line":3958},[3856,5386,4074],{"class":3874},[3856,5388,3925],{"class":3870},[3856,5390,3928],{"class":3866},[3856,5392,3871],{"class":3870},[3856,5394,5395],{"class":4060},"\"Value is null\"",[3856,5397,4896],{"class":3870},[3856,5399,5400,5402],{"class":3858,"line":4138},[3856,5401,4840],{"class":4046},[3856,5403,4931],{"class":3870},[3856,5405,5406],{"class":3858,"line":4144},[3856,5407,4141],{"class":3870},[3856,5409,5410],{"class":3858,"line":4149},[3856,5411,3916],{"class":3870},[3856,5413,5414],{"class":3858,"line":4156},[3856,5415,5416],{"class":3903},"  \u002F\u002F Тут value: string\n",[3856,5418,5419,5421,5423,5425,5427,5429,5431,5433],{"class":3858,"line":4173},[3856,5420,3922],{"class":3874},[3856,5422,3925],{"class":3870},[3856,5424,3928],{"class":3866},[3856,5426,3871],{"class":3870},[3856,5428,3875],{"class":3874},[3856,5430,3925],{"class":3870},[3856,5432,3937],{"class":3866},[3856,5434,5083],{"class":3870},[3856,5436,5437],{"class":3858,"line":4288},[3856,5438,3961],{"class":3870},[5440,5441,5442,5445,5446,4745,5448,5450,5451,5453,5454,3981,5457,5460,5461,3925],"warning",{},[3793,5443,5444],{},"Пастка з typeof null:"," ",[3761,5447,4744],{},[3761,5449,4748],{},", тому для перевірки на ",[3761,5452,5299],{}," використовуйте ",[3793,5455,5456],{},"strict equality",[3761,5458,5459],{},"=== null","), а не ",[3761,5462,3763],{},[3838,5464,5466],{"id":5465},"обмеження-typeof","Обмеження typeof",[3843,5468,5469,5471,5472,5475],{},[3761,5470,3763],{}," працює лише з ",[3793,5473,5474],{},"примітивними типами"," та функціями. Він не допомагає розрізняти:",[3746,5477,5478,5484,5489],{},[3749,5479,5480,5481,5483],{},"Масиви від об'єктів (обидва повертають ",[3761,5482,4748],{},")",[3749,5485,5486,5487,5483],{},"Різні класи об'єктів (всі повертають ",[3761,5488,4748],{},[3749,5490,5491,5493,5494,5496,5497,5483],{},[3761,5492,5299],{}," (повертає ",[3761,5495,4748],{}," замість ",[3761,5498,5344],{},[3843,5500,5501],{},"Для складніших типів потрібні інші техніки звуження.",[3830,5503],{},[3833,5505,5507],{"id":5506},"truthiness-narrowing","Truthiness Narrowing",[3838,5509,5511],{"id":5510},"truthy-та-falsy-значення-у-javascript","Truthy та Falsy значення у JavaScript",[3843,5513,5514,5515,3764,5517,3764,5520,5523,5524,3824,5526,5528,5529,5531,5532,4737],{},"У JavaScript будь-яке значення у логічному контексті (",[3761,5516,4200],{},[3761,5518,5519],{},"while",[3761,5521,5522],{},"? :",") приводиться до ",[3761,5525,3823],{},[3761,5527,3827],{},". Значення, що перетворюються на ",[3761,5530,3827],{},", називаються ",[3793,5533,5534],{},"falsy",[3843,5536,5537],{},[3793,5538,5539],{},"Falsy значення (їх всього 8):",[4456,5541,5542,5546,5552,5558,5564,5570,5574,5578],{},[3749,5543,5544],{},[3761,5545,3827],{},[3749,5547,5548,5551],{},[3761,5549,5550],{},"0"," (число нуль)",[3749,5553,5554,5557],{},[3761,5555,5556],{},"-0"," (від'ємний нуль)",[3749,5559,5560,5563],{},[3761,5561,5562],{},"0n"," (BigInt нуль)",[3749,5565,5566,5569],{},[3761,5567,5568],{},"\"\""," (порожній рядок)",[3749,5571,5572],{},[3761,5573,5299],{},[3749,5575,5576],{},[3761,5577,5139],{},[3749,5579,5580],{},[3761,5581,5582],{},"NaN",[3843,5584,5585,5588],{},[3793,5586,5587],{},"Усі інші значення є truthy",", включаючи:",[3746,5590,5591,5602,5617,5629],{},[3749,5592,5593,5594,3764,5596,3764,5599],{},"Непорожні рядки: ",[3761,5595,4164],{},[3761,5597,5598],{},"\"0\"",[3761,5600,5601],{},"\"false\"",[3749,5603,5604,5605,3764,5608,3764,5611,3764,5614],{},"Будь-які ненульові числа: ",[3761,5606,5607],{},"1",[3761,5609,5610],{},"-1",[3761,5612,5613],{},"3.14",[3761,5615,5616],{},"Infinity",[3749,5618,5619,5620,3764,5623,3764,5626],{},"Об'єкти: ",[3761,5621,5622],{},"{}",[3761,5624,5625],{},"[]",[3761,5627,5628],{},"function(){}",[3749,5630,5631],{},[3761,5632,3823],{},[3847,5634,5636],{"className":4515,"code":5635,"language":4517,"meta":3852,"style":3852},"\u002F\u002F Приклади truthiness\nif (\"hello\") {\n  console.log(\"Truthy\");  \u002F\u002F виконається\n}\n\nif (0) {\n  console.log(\"Truthy\");  \u002F\u002F НЕ виконається (0 — falsy)\n}\n\nif ([]) {\n  console.log(\"Truthy\");  \u002F\u002F виконається (порожній масив — truthy!)\n}\n\nif (null) {\n  console.log(\"Truthy\");  \u002F\u002F НЕ виконається (null — falsy)\n}\n",[3761,5637,5638,5643,5653,5671,5675,5679,5689,5706,5710,5714,5721,5738,5742,5746,5756,5773],{"__ignoreMap":3852},[3856,5639,5640],{"class":3858,"line":3859},[3856,5641,5642],{"class":3903},"\u002F\u002F Приклади truthiness\n",[3856,5644,5645,5647,5649,5651],{"class":3858,"line":3900},[3856,5646,4200],{"class":4046},[3856,5648,3981],{"class":3870},[3856,5650,4164],{"class":4060},[3856,5652,4064],{"class":3870},[3856,5654,5655,5657,5659,5661,5663,5666,5668],{"class":3858,"line":3907},[3856,5656,3922],{"class":3874},[3856,5658,3925],{"class":3870},[3856,5660,3928],{"class":3866},[3856,5662,3871],{"class":3870},[3856,5664,5665],{"class":4060},"\"Truthy\"",[3856,5667,4167],{"class":3870},[3856,5669,5670],{"class":3903},"\u002F\u002F виконається\n",[3856,5672,5673],{"class":3858,"line":3913},[3856,5674,3961],{"class":3870},[3856,5676,5677],{"class":3858,"line":3919},[3856,5678,4153],{"emptyLinePlaceholder":4152},[3856,5680,5681,5683,5685,5687],{"class":3858,"line":3946},[3856,5682,4200],{"class":4046},[3856,5684,3981],{"class":3870},[3856,5686,5550],{"class":4128},[3856,5688,4064],{"class":3870},[3856,5690,5691,5693,5695,5697,5699,5701,5703],{"class":3858,"line":3952},[3856,5692,3922],{"class":3874},[3856,5694,3925],{"class":3870},[3856,5696,3928],{"class":3866},[3856,5698,3871],{"class":3870},[3856,5700,5665],{"class":4060},[3856,5702,4167],{"class":3870},[3856,5704,5705],{"class":3903},"\u002F\u002F НЕ виконається (0 — falsy)\n",[3856,5707,5708],{"class":3858,"line":3958},[3856,5709,3961],{"class":3870},[3856,5711,5712],{"class":3858,"line":4138},[3856,5713,4153],{"emptyLinePlaceholder":4152},[3856,5715,5716,5718],{"class":3858,"line":4144},[3856,5717,4200],{"class":4046},[3856,5719,5720],{"class":3870}," ([]) {\n",[3856,5722,5723,5725,5727,5729,5731,5733,5735],{"class":3858,"line":4149},[3856,5724,3922],{"class":3874},[3856,5726,3925],{"class":3870},[3856,5728,3928],{"class":3866},[3856,5730,3871],{"class":3870},[3856,5732,5665],{"class":4060},[3856,5734,4167],{"class":3870},[3856,5736,5737],{"class":3903},"\u002F\u002F виконається (порожній масив — truthy!)\n",[3856,5739,5740],{"class":3858,"line":4156},[3856,5741,3961],{"class":3870},[3856,5743,5744],{"class":3858,"line":4173},[3856,5745,4153],{"emptyLinePlaceholder":4152},[3856,5747,5748,5750,5752,5754],{"class":3858,"line":4288},[3856,5749,4200],{"class":4046},[3856,5751,3981],{"class":3870},[3856,5753,5299],{"class":3862},[3856,5755,4064],{"class":3870},[3856,5757,5758,5760,5762,5764,5766,5768,5770],{"class":3858,"line":4293},[3856,5759,3922],{"class":3874},[3856,5761,3925],{"class":3870},[3856,5763,3928],{"class":3866},[3856,5765,3871],{"class":3870},[3856,5767,5665],{"class":4060},[3856,5769,4167],{"class":3870},[3856,5771,5772],{"class":3903},"\u002F\u002F НЕ виконається (null — falsy)\n",[3856,5774,5775],{"class":3858,"line":4299},[3856,5776,3961],{"class":3870},[3838,5778,5780],{"id":5779},"truthiness-для-звуження-типів","Truthiness для звуження типів",[3843,5782,5783,5784,5786,5787,4737],{},"TypeScript використовує truthiness для звуження типів, особливо для виключення ",[3761,5785,5299],{}," та ",[3761,5788,5139],{},[3847,5790,5792],{"className":3849,"code":5791,"language":3851,"meta":3852,"style":3852},"function printName(name: string | null | undefined): void {\n  \u002F\u002F Перевірка на truthiness\n  if (name) {\n    \u002F\u002F Тут name: string (null та undefined — falsy, вони виключені)\n    console.log(`Hello, ${name.toUpperCase()}!`);\n  } else {\n    console.log(\"Name not provided\");\n  }\n}\n\nprintName(\"Alice\");     \u002F\u002F \"Hello, ALICE!\"\nprintName(null);        \u002F\u002F \"Name not provided\"\nprintName(undefined);   \u002F\u002F \"Name not provided\"\nprintName(\"\");          \u002F\u002F \"Name not provided\" (порожній рядок теж falsy!)\n",[3761,5793,5794,5824,5829,5839,5844,5875,5883,5898,5902,5906,5910,5925,5939,5952],{"__ignoreMap":3852},[3856,5795,5796,5798,5801,5803,5806,5808,5810,5812,5814,5816,5818,5820,5822],{"class":3858,"line":3859},[3856,5797,3863],{"class":3862},[3856,5799,5800],{"class":3866}," printName",[3856,5802,3871],{"class":3870},[3856,5804,5805],{"class":3874},"name",[3856,5807,3878],{"class":3870},[3856,5809,3882],{"class":3881},[3856,5811,3885],{"class":3870},[3856,5813,5299],{"class":3881},[3856,5815,3885],{"class":3870},[3856,5817,5139],{"class":3881},[3856,5819,3891],{"class":3870},[3856,5821,3894],{"class":3881},[3856,5823,3897],{"class":3870},[3856,5825,5826],{"class":3858,"line":3900},[3856,5827,5828],{"class":3903},"  \u002F\u002F Перевірка на truthiness\n",[3856,5830,5831,5833,5835,5837],{"class":3858,"line":3907},[3856,5832,4047],{"class":4046},[3856,5834,3981],{"class":3870},[3856,5836,5805],{"class":3874},[3856,5838,4064],{"class":3870},[3856,5840,5841],{"class":3858,"line":3913},[3856,5842,5843],{"class":3903},"    \u002F\u002F Тут name: string (null та undefined — falsy, вони виключені)\n",[3856,5845,5846,5848,5850,5852,5854,5857,5859,5861,5863,5865,5868,5870,5873],{"class":3858,"line":3919},[3856,5847,4074],{"class":3874},[3856,5849,3925],{"class":3870},[3856,5851,3928],{"class":3866},[3856,5853,3871],{"class":3870},[3856,5855,5856],{"class":4060},"`Hello, ",[3856,5858,5238],{"class":3862},[3856,5860,5805],{"class":3874},[3856,5862,3925],{"class":5243},[3856,5864,3937],{"class":3866},[3856,5866,5867],{"class":5243},"()",[3856,5869,5249],{"class":3862},[3856,5871,5872],{"class":4060},"!`",[3856,5874,4896],{"class":3870},[3856,5876,5877,5879,5881],{"class":3858,"line":3946},[3856,5878,4096],{"class":3870},[3856,5880,4099],{"class":4046},[3856,5882,3897],{"class":3870},[3856,5884,5885,5887,5889,5891,5893,5896],{"class":3858,"line":3952},[3856,5886,4074],{"class":3874},[3856,5888,3925],{"class":3870},[3856,5890,3928],{"class":3866},[3856,5892,3871],{"class":3870},[3856,5894,5895],{"class":4060},"\"Name not provided\"",[3856,5897,4896],{"class":3870},[3856,5899,5900],{"class":3858,"line":3958},[3856,5901,4141],{"class":3870},[3856,5903,5904],{"class":3858,"line":4138},[3856,5905,3961],{"class":3870},[3856,5907,5908],{"class":3858,"line":4144},[3856,5909,4153],{"emptyLinePlaceholder":4152},[3856,5911,5912,5915,5917,5920,5922],{"class":3858,"line":4149},[3856,5913,5914],{"class":3866},"printName",[3856,5916,3871],{"class":3870},[3856,5918,5919],{"class":4060},"\"Alice\"",[3856,5921,4600],{"class":3870},[3856,5923,5924],{"class":3903},"\u002F\u002F \"Hello, ALICE!\"\n",[3856,5926,5927,5929,5931,5933,5936],{"class":3858,"line":4156},[3856,5928,5914],{"class":3866},[3856,5930,3871],{"class":3870},[3856,5932,5299],{"class":3862},[3856,5934,5935],{"class":3870},");        ",[3856,5937,5938],{"class":3903},"\u002F\u002F \"Name not provided\"\n",[3856,5940,5941,5943,5945,5947,5950],{"class":3858,"line":4173},[3856,5942,5914],{"class":3866},[3856,5944,3871],{"class":3870},[3856,5946,5139],{"class":3862},[3856,5948,5949],{"class":3870},");   ",[3856,5951,5938],{"class":3903},[3856,5953,5954,5956,5958,5960,5962],{"class":3858,"line":4288},[3856,5955,5914],{"class":3866},[3856,5957,3871],{"class":3870},[3856,5959,5568],{"class":4060},[3856,5961,4579],{"class":3870},[3856,5963,5964],{"class":3903},"\u002F\u002F \"Name not provided\" (порожній рядок теж falsy!)\n",[3843,5966,5967],{},[3793,5968,5969],{},"Увага: порожній рядок теж falsy!",[3843,5971,5972,5973,5975,5976,5978],{},"Якщо ви хочете дозволити порожній рядок, але виключити ",[3761,5974,5299],{},"\u002F",[3761,5977,5139],{},", використовуйте явну перевірку:",[3847,5980,5982],{"className":3849,"code":5981,"language":3851,"meta":3852,"style":3852},"function printName(name: string | null | undefined): void {\n  \u002F\u002F Перевірка лише на null\u002Fundefined\n  if (name !== null && name !== undefined) {\n    \u002F\u002F Тут name: string (включаючи порожній рядок \"\")\n    console.log(`Name: ${name}`);\n  } else {\n    console.log(\"Name not provided\");\n  }\n}\n\nprintName(\"\");          \u002F\u002F \"Name: \" (тепер порожній рядок дозволений)\nprintName(null);        \u002F\u002F \"Name not provided\"\nprintName(undefined);   \u002F\u002F \"Name not provided\"\n",[3761,5983,5984,6012,6017,6041,6046,6069,6077,6091,6095,6099,6103,6116,6128],{"__ignoreMap":3852},[3856,5985,5986,5988,5990,5992,5994,5996,5998,6000,6002,6004,6006,6008,6010],{"class":3858,"line":3859},[3856,5987,3863],{"class":3862},[3856,5989,5800],{"class":3866},[3856,5991,3871],{"class":3870},[3856,5993,5805],{"class":3874},[3856,5995,3878],{"class":3870},[3856,5997,3882],{"class":3881},[3856,5999,3885],{"class":3870},[3856,6001,5299],{"class":3881},[3856,6003,3885],{"class":3870},[3856,6005,5139],{"class":3881},[3856,6007,3891],{"class":3870},[3856,6009,3894],{"class":3881},[3856,6011,3897],{"class":3870},[3856,6013,6014],{"class":3858,"line":3900},[3856,6015,6016],{"class":3903},"  \u002F\u002F Перевірка лише на null\u002Fundefined\n",[3856,6018,6019,6021,6023,6025,6028,6030,6033,6035,6037,6039],{"class":3858,"line":3907},[3856,6020,4047],{"class":4046},[3856,6022,3981],{"class":3870},[3856,6024,5805],{"class":3874},[3856,6026,6027],{"class":3870}," !== ",[3856,6029,5299],{"class":3862},[3856,6031,6032],{"class":3870}," && ",[3856,6034,5805],{"class":3874},[3856,6036,6027],{"class":3870},[3856,6038,5139],{"class":3862},[3856,6040,4064],{"class":3870},[3856,6042,6043],{"class":3858,"line":3913},[3856,6044,6045],{"class":3903},"    \u002F\u002F Тут name: string (включаючи порожній рядок \"\")\n",[3856,6047,6048,6050,6052,6054,6056,6059,6061,6063,6065,6067],{"class":3858,"line":3919},[3856,6049,4074],{"class":3874},[3856,6051,3925],{"class":3870},[3856,6053,3928],{"class":3866},[3856,6055,3871],{"class":3870},[3856,6057,6058],{"class":4060},"`Name: ",[3856,6060,5238],{"class":3862},[3856,6062,5805],{"class":3874},[3856,6064,5249],{"class":3862},[3856,6066,5252],{"class":4060},[3856,6068,4896],{"class":3870},[3856,6070,6071,6073,6075],{"class":3858,"line":3946},[3856,6072,4096],{"class":3870},[3856,6074,4099],{"class":4046},[3856,6076,3897],{"class":3870},[3856,6078,6079,6081,6083,6085,6087,6089],{"class":3858,"line":3952},[3856,6080,4074],{"class":3874},[3856,6082,3925],{"class":3870},[3856,6084,3928],{"class":3866},[3856,6086,3871],{"class":3870},[3856,6088,5895],{"class":4060},[3856,6090,4896],{"class":3870},[3856,6092,6093],{"class":3858,"line":3958},[3856,6094,4141],{"class":3870},[3856,6096,6097],{"class":3858,"line":4138},[3856,6098,3961],{"class":3870},[3856,6100,6101],{"class":3858,"line":4144},[3856,6102,4153],{"emptyLinePlaceholder":4152},[3856,6104,6105,6107,6109,6111,6113],{"class":3858,"line":4149},[3856,6106,5914],{"class":3866},[3856,6108,3871],{"class":3870},[3856,6110,5568],{"class":4060},[3856,6112,4579],{"class":3870},[3856,6114,6115],{"class":3903},"\u002F\u002F \"Name: \" (тепер порожній рядок дозволений)\n",[3856,6117,6118,6120,6122,6124,6126],{"class":3858,"line":4156},[3856,6119,5914],{"class":3866},[3856,6121,3871],{"class":3870},[3856,6123,5299],{"class":3862},[3856,6125,5935],{"class":3870},[3856,6127,5938],{"class":3903},[3856,6129,6130,6132,6134,6136,6138],{"class":3858,"line":4173},[3856,6131,5914],{"class":3866},[3856,6133,3871],{"class":3870},[3856,6135,5139],{"class":3862},[3856,6137,5949],{"class":3870},[3856,6139,5938],{"class":3903},[3843,6141,6142],{},[3793,6143,6144,6145,4737],{},"Або через оператор ",[3761,6146,6147],{},"!= null",[3847,6149,6151],{"className":3849,"code":6150,"language":3851,"meta":3852,"style":3852},"function printName(name: string | null | undefined): void {\n  \u002F\u002F != null виключає як null, так і undefined\n  if (name != null) {\n    \u002F\u002F Тут name: string\n    console.log(`Name: ${name}`);\n  } else {\n    console.log(\"Name not provided\");\n  }\n}\n",[3761,6152,6153,6181,6186,6201,6206,6228,6236,6250,6254],{"__ignoreMap":3852},[3856,6154,6155,6157,6159,6161,6163,6165,6167,6169,6171,6173,6175,6177,6179],{"class":3858,"line":3859},[3856,6156,3863],{"class":3862},[3856,6158,5800],{"class":3866},[3856,6160,3871],{"class":3870},[3856,6162,5805],{"class":3874},[3856,6164,3878],{"class":3870},[3856,6166,3882],{"class":3881},[3856,6168,3885],{"class":3870},[3856,6170,5299],{"class":3881},[3856,6172,3885],{"class":3870},[3856,6174,5139],{"class":3881},[3856,6176,3891],{"class":3870},[3856,6178,3894],{"class":3881},[3856,6180,3897],{"class":3870},[3856,6182,6183],{"class":3858,"line":3900},[3856,6184,6185],{"class":3903},"  \u002F\u002F != null виключає як null, так і undefined\n",[3856,6187,6188,6190,6192,6194,6197,6199],{"class":3858,"line":3907},[3856,6189,4047],{"class":4046},[3856,6191,3981],{"class":3870},[3856,6193,5805],{"class":3874},[3856,6195,6196],{"class":3870}," != ",[3856,6198,5299],{"class":3862},[3856,6200,4064],{"class":3870},[3856,6202,6203],{"class":3858,"line":3913},[3856,6204,6205],{"class":3903},"    \u002F\u002F Тут name: string\n",[3856,6207,6208,6210,6212,6214,6216,6218,6220,6222,6224,6226],{"class":3858,"line":3919},[3856,6209,4074],{"class":3874},[3856,6211,3925],{"class":3870},[3856,6213,3928],{"class":3866},[3856,6215,3871],{"class":3870},[3856,6217,6058],{"class":4060},[3856,6219,5238],{"class":3862},[3856,6221,5805],{"class":3874},[3856,6223,5249],{"class":3862},[3856,6225,5252],{"class":4060},[3856,6227,4896],{"class":3870},[3856,6229,6230,6232,6234],{"class":3858,"line":3946},[3856,6231,4096],{"class":3870},[3856,6233,4099],{"class":4046},[3856,6235,3897],{"class":3870},[3856,6237,6238,6240,6242,6244,6246,6248],{"class":3858,"line":3952},[3856,6239,4074],{"class":3874},[3856,6241,3925],{"class":3870},[3856,6243,3928],{"class":3866},[3856,6245,3871],{"class":3870},[3856,6247,5895],{"class":4060},[3856,6249,4896],{"class":3870},[3856,6251,6252],{"class":3858,"line":3958},[3856,6253,4141],{"class":3870},[3856,6255,6256],{"class":3858,"line":4138},[3856,6257,3961],{"class":3870},[6259,6260,6261,6276,6336],"tip",{},[3843,6262,6263,6264,6266,6267,6275],{},"Оператор ",[3761,6265,6147],{}," (не strict equality) ",[3793,6268,6269,6270,6272,6273],{},"виключає як ",[3761,6271,5299],{},", так і ",[3761,6274,5139],{}," завдяки type coercion у JavaScript:",[3847,6277,6279],{"className":4515,"code":6278,"language":4517,"meta":3852,"style":3852},"null == undefined   \u002F\u002F true\nnull == null        \u002F\u002F true\nundefined == null   \u002F\u002F true\n\"\" == null          \u002F\u002F false\n0 == null           \u002F\u002F false\n",[3761,6280,6281,6293,6304,6314,6325],{"__ignoreMap":3852},[3856,6282,6283,6285,6288,6290],{"class":3858,"line":3859},[3856,6284,5299],{"class":3862},[3856,6286,6287],{"class":3870}," == ",[3856,6289,5139],{"class":3862},[3856,6291,6292],{"class":3903},"   \u002F\u002F true\n",[3856,6294,6295,6297,6299,6301],{"class":3858,"line":3900},[3856,6296,5299],{"class":3862},[3856,6298,6287],{"class":3870},[3856,6300,5299],{"class":3862},[3856,6302,6303],{"class":3903},"        \u002F\u002F true\n",[3856,6305,6306,6308,6310,6312],{"class":3858,"line":3907},[3856,6307,5139],{"class":3862},[3856,6309,6287],{"class":3870},[3856,6311,5299],{"class":3862},[3856,6313,6292],{"class":3903},[3856,6315,6316,6318,6320,6322],{"class":3858,"line":3913},[3856,6317,5568],{"class":4060},[3856,6319,6287],{"class":3870},[3856,6321,5299],{"class":3862},[3856,6323,6324],{"class":3903},"          \u002F\u002F false\n",[3856,6326,6327,6329,6331,6333],{"class":3858,"line":3919},[3856,6328,5550],{"class":4128},[3856,6330,6287],{"class":3870},[3856,6332,5299],{"class":3862},[3856,6334,6335],{"class":3903},"           \u002F\u002F false\n",[3843,6337,6338,6339,6342,6343,6346,6347,6350],{},"Це один з ",[3793,6340,6341],{},"рідкісних випадків",", коли ",[3761,6344,6345],{},"=="," корисніший за ",[3761,6348,6349],{},"==="," для звуження типів.",[3838,6352,6354],{"id":6353},"boolean-для-явного-перетворення","Boolean() для явного перетворення",[3843,6356,6357,6358,6361,6362,4737],{},"Іноді truthy-перевірка недостатньо очевидна. Для явного перетворення до boolean використовуйте ",[3761,6359,6360],{},"Boolean()"," або подвійне заперечення ",[3761,6363,6364],{},"!!",[3847,6366,6368],{"className":3849,"code":6367,"language":3851,"meta":3852,"style":3852},"function hasValue(value: string | null | undefined): value is string {\n  return Boolean(value);  \u002F\u002F явне перетворення до boolean\n}\n\n\u002F\u002F Або через !!\nfunction hasValue2(value: string | null | undefined): value is string {\n  return !!value;  \u002F\u002F !! перетворює до boolean\n}\n\nlet text: string | null = \"hello\";\n\nif (hasValue(text)) {\n  \u002F\u002F Тут text: string\n  console.log(text.toUpperCase());\n}\n",[3761,6369,6370,6405,6421,6425,6429,6434,6467,6482,6486,6490,6512,6516,6532,6537,6555],{"__ignoreMap":3852},[3856,6371,6372,6374,6377,6379,6381,6383,6385,6387,6389,6391,6393,6395,6397,6400,6403],{"class":3858,"line":3859},[3856,6373,3863],{"class":3862},[3856,6375,6376],{"class":3866}," hasValue",[3856,6378,3871],{"class":3870},[3856,6380,3875],{"class":3874},[3856,6382,3878],{"class":3870},[3856,6384,3882],{"class":3881},[3856,6386,3885],{"class":3870},[3856,6388,5299],{"class":3881},[3856,6390,3885],{"class":3870},[3856,6392,5139],{"class":3881},[3856,6394,3891],{"class":3870},[3856,6396,3875],{"class":3874},[3856,6398,6399],{"class":3862}," is",[3856,6401,6402],{"class":3881}," string",[3856,6404,3897],{"class":3870},[3856,6406,6407,6409,6412,6414,6416,6418],{"class":3858,"line":3900},[3856,6408,4914],{"class":4046},[3856,6410,6411],{"class":3866}," Boolean",[3856,6413,3871],{"class":3870},[3856,6415,3875],{"class":3874},[3856,6417,4167],{"class":3870},[3856,6419,6420],{"class":3903},"\u002F\u002F явне перетворення до boolean\n",[3856,6422,6423],{"class":3858,"line":3907},[3856,6424,3961],{"class":3870},[3856,6426,6427],{"class":3858,"line":3913},[3856,6428,4153],{"emptyLinePlaceholder":4152},[3856,6430,6431],{"class":3858,"line":3919},[3856,6432,6433],{"class":3903},"\u002F\u002F Або через !!\n",[3856,6435,6436,6438,6441,6443,6445,6447,6449,6451,6453,6455,6457,6459,6461,6463,6465],{"class":3858,"line":3946},[3856,6437,3863],{"class":3862},[3856,6439,6440],{"class":3866}," hasValue2",[3856,6442,3871],{"class":3870},[3856,6444,3875],{"class":3874},[3856,6446,3878],{"class":3870},[3856,6448,3882],{"class":3881},[3856,6450,3885],{"class":3870},[3856,6452,5299],{"class":3881},[3856,6454,3885],{"class":3870},[3856,6456,5139],{"class":3881},[3856,6458,3891],{"class":3870},[3856,6460,3875],{"class":3874},[3856,6462,6399],{"class":3862},[3856,6464,6402],{"class":3881},[3856,6466,3897],{"class":3870},[3856,6468,6469,6471,6474,6476,6479],{"class":3858,"line":3952},[3856,6470,4914],{"class":4046},[3856,6472,6473],{"class":3870}," !!",[3856,6475,3875],{"class":3874},[3856,6477,6478],{"class":3870},";  ",[3856,6480,6481],{"class":3903},"\u002F\u002F !! перетворює до boolean\n",[3856,6483,6484],{"class":3858,"line":3958},[3856,6485,3961],{"class":3870},[3856,6487,6488],{"class":3858,"line":4138},[3856,6489,4153],{"emptyLinePlaceholder":4152},[3856,6491,6492,6495,6497,6499,6501,6503,6505,6508,6510],{"class":3858,"line":4144},[3856,6493,6494],{"class":3862},"let",[3856,6496,5181],{"class":3874},[3856,6498,3878],{"class":3870},[3856,6500,3882],{"class":3881},[3856,6502,3885],{"class":3870},[3856,6504,5299],{"class":3881},[3856,6506,6507],{"class":3870}," = ",[3856,6509,4164],{"class":4060},[3856,6511,4931],{"class":3870},[3856,6513,6514],{"class":3858,"line":4149},[3856,6515,4153],{"emptyLinePlaceholder":4152},[3856,6517,6518,6520,6522,6525,6527,6529],{"class":3858,"line":4156},[3856,6519,4200],{"class":4046},[3856,6521,3981],{"class":3870},[3856,6523,6524],{"class":3866},"hasValue",[3856,6526,3871],{"class":3870},[3856,6528,5156],{"class":3874},[3856,6530,6531],{"class":3870},")) {\n",[3856,6533,6534],{"class":3858,"line":4173},[3856,6535,6536],{"class":3903},"  \u002F\u002F Тут text: string\n",[3856,6538,6539,6541,6543,6545,6547,6549,6551,6553],{"class":3858,"line":4288},[3856,6540,3922],{"class":3874},[3856,6542,3925],{"class":3870},[3856,6544,3928],{"class":3866},[3856,6546,3871],{"class":3870},[3856,6548,5156],{"class":3874},[3856,6550,3925],{"class":3870},[3856,6552,3937],{"class":3866},[3856,6554,5083],{"class":3870},[3856,6556,6557],{"class":3858,"line":4293},[3856,6558,3961],{"class":3870},[3830,6560],{},[3833,6562,6564],{"id":6563},"equality-narrowing","Equality Narrowing",[3838,6566,6568],{"id":6567},"перевірка-через-та","Перевірка через === та !==",[3843,6570,6571,3981,6574,5786,6576,6579],{},[3793,6572,6573],{},"Strict equality",[3761,6575,6349],{},[3761,6577,6578],{},"!==",") дозволяє TypeScript звужувати типи на основі порівняння значень:",[3847,6581,6583],{"className":3849,"code":6582,"language":3851,"meta":3852,"style":3852},"function example(x: string | number, y: string | boolean): void {\n  if (x === y) {\n    \u002F\u002F Якщо x === y, то вони ОБИДВА мають однаковий тип\n    \u002F\u002F TypeScript виводить: x та y — це string (єдиний спільний тип)\n    console.log(x.toUpperCase());  \u002F\u002F OK\n    console.log(y.toUpperCase());  \u002F\u002F OK\n  } else {\n    \u002F\u002F У цій гілці x та y можуть мати різні типи\n    console.log(x);  \u002F\u002F string | number\n    console.log(y);  \u002F\u002F string | boolean\n  }\n}\n",[3761,6584,6585,6622,6636,6641,6646,6667,6687,6695,6700,6717,6734,6738],{"__ignoreMap":3852},[3856,6586,6587,6589,6591,6593,6595,6597,6599,6601,6603,6605,6608,6610,6612,6614,6616,6618,6620],{"class":3858,"line":3859},[3856,6588,3863],{"class":3862},[3856,6590,5023],{"class":3866},[3856,6592,3871],{"class":3870},[3856,6594,5028],{"class":3874},[3856,6596,3878],{"class":3870},[3856,6598,3882],{"class":3881},[3856,6600,3885],{"class":3870},[3856,6602,3888],{"class":3881},[3856,6604,3764],{"class":3870},[3856,6606,6607],{"class":3874},"y",[3856,6609,3878],{"class":3870},[3856,6611,3882],{"class":3881},[3856,6613,3885],{"class":3870},[3856,6615,4808],{"class":3881},[3856,6617,3891],{"class":3870},[3856,6619,3894],{"class":3881},[3856,6621,3897],{"class":3870},[3856,6623,6624,6626,6628,6630,6632,6634],{"class":3858,"line":3900},[3856,6625,4047],{"class":4046},[3856,6627,3981],{"class":3870},[3856,6629,5028],{"class":3874},[3856,6631,4057],{"class":3870},[3856,6633,6607],{"class":3874},[3856,6635,4064],{"class":3870},[3856,6637,6638],{"class":3858,"line":3907},[3856,6639,6640],{"class":3903},"    \u002F\u002F Якщо x === y, то вони ОБИДВА мають однаковий тип\n",[3856,6642,6643],{"class":3858,"line":3913},[3856,6644,6645],{"class":3903},"    \u002F\u002F TypeScript виводить: x та y — це string (єдиний спільний тип)\n",[3856,6647,6648,6650,6652,6654,6656,6658,6660,6662,6664],{"class":3858,"line":3919},[3856,6649,4074],{"class":3874},[3856,6651,3925],{"class":3870},[3856,6653,3928],{"class":3866},[3856,6655,3871],{"class":3870},[3856,6657,5028],{"class":3874},[3856,6659,3925],{"class":3870},[3856,6661,3937],{"class":3866},[3856,6663,3940],{"class":3870},[3856,6665,6666],{"class":3903},"\u002F\u002F OK\n",[3856,6668,6669,6671,6673,6675,6677,6679,6681,6683,6685],{"class":3858,"line":3946},[3856,6670,4074],{"class":3874},[3856,6672,3925],{"class":3870},[3856,6674,3928],{"class":3866},[3856,6676,3871],{"class":3870},[3856,6678,6607],{"class":3874},[3856,6680,3925],{"class":3870},[3856,6682,3937],{"class":3866},[3856,6684,3940],{"class":3870},[3856,6686,6666],{"class":3903},[3856,6688,6689,6691,6693],{"class":3858,"line":3952},[3856,6690,4096],{"class":3870},[3856,6692,4099],{"class":4046},[3856,6694,3897],{"class":3870},[3856,6696,6697],{"class":3858,"line":3958},[3856,6698,6699],{"class":3903},"    \u002F\u002F У цій гілці x та y можуть мати різні типи\n",[3856,6701,6702,6704,6706,6708,6710,6712,6714],{"class":3858,"line":4138},[3856,6703,4074],{"class":3874},[3856,6705,3925],{"class":3870},[3856,6707,3928],{"class":3866},[3856,6709,3871],{"class":3870},[3856,6711,5028],{"class":3874},[3856,6713,4167],{"class":3870},[3856,6715,6716],{"class":3903},"\u002F\u002F string | number\n",[3856,6718,6719,6721,6723,6725,6727,6729,6731],{"class":3858,"line":4144},[3856,6720,4074],{"class":3874},[3856,6722,3925],{"class":3870},[3856,6724,3928],{"class":3866},[3856,6726,3871],{"class":3870},[3856,6728,6607],{"class":3874},[3856,6730,4167],{"class":3870},[3856,6732,6733],{"class":3903},"\u002F\u002F string | boolean\n",[3856,6735,6736],{"class":3858,"line":4149},[3856,6737,4141],{"class":3870},[3856,6739,6740],{"class":3858,"line":4156},[3856,6741,3961],{"class":3870},[3843,6743,6744],{},[3793,6745,6746],{},"Перевірка на конкретне значення:",[3847,6748,6750],{"className":3849,"code":6749,"language":3851,"meta":3852,"style":3852},"function printStatus(status: \"success\" | \"error\" | \"pending\"): void {\n  if (status === \"success\") {\n    \u002F\u002F Тут status: \"success\" (literal type)\n    console.log(\"✓ Operation completed\");\n  } else if (status === \"error\") {\n    \u002F\u002F Тут status: \"error\"\n    console.log(\"✗ Operation failed\");\n  } else {\n    \u002F\u002F Тут status: \"pending\" (єдиний варіант, що залишився)\n    console.log(\"⏳ Operation in progress\");\n  }\n}\n",[3761,6751,6752,6785,6799,6804,6819,6838,6843,6858,6866,6871,6886,6890],{"__ignoreMap":3852},[3856,6753,6754,6756,6759,6761,6764,6766,6769,6771,6774,6776,6779,6781,6783],{"class":3858,"line":3859},[3856,6755,3863],{"class":3862},[3856,6757,6758],{"class":3866}," printStatus",[3856,6760,3871],{"class":3870},[3856,6762,6763],{"class":3874},"status",[3856,6765,3878],{"class":3870},[3856,6767,6768],{"class":4060},"\"success\"",[3856,6770,3885],{"class":3870},[3856,6772,6773],{"class":4060},"\"error\"",[3856,6775,3885],{"class":3870},[3856,6777,6778],{"class":4060},"\"pending\"",[3856,6780,3891],{"class":3870},[3856,6782,3894],{"class":3881},[3856,6784,3897],{"class":3870},[3856,6786,6787,6789,6791,6793,6795,6797],{"class":3858,"line":3900},[3856,6788,4047],{"class":4046},[3856,6790,3981],{"class":3870},[3856,6792,6763],{"class":3874},[3856,6794,4057],{"class":3870},[3856,6796,6768],{"class":4060},[3856,6798,4064],{"class":3870},[3856,6800,6801],{"class":3858,"line":3907},[3856,6802,6803],{"class":3903},"    \u002F\u002F Тут status: \"success\" (literal type)\n",[3856,6805,6806,6808,6810,6812,6814,6817],{"class":3858,"line":3913},[3856,6807,4074],{"class":3874},[3856,6809,3925],{"class":3870},[3856,6811,3928],{"class":3866},[3856,6813,3871],{"class":3870},[3856,6815,6816],{"class":4060},"\"✓ Operation completed\"",[3856,6818,4896],{"class":3870},[3856,6820,6821,6823,6825,6828,6830,6832,6834,6836],{"class":3858,"line":3919},[3856,6822,4096],{"class":3870},[3856,6824,4099],{"class":4046},[3856,6826,6827],{"class":4046}," if",[3856,6829,3981],{"class":3870},[3856,6831,6763],{"class":3874},[3856,6833,4057],{"class":3870},[3856,6835,6773],{"class":4060},[3856,6837,4064],{"class":3870},[3856,6839,6840],{"class":3858,"line":3946},[3856,6841,6842],{"class":3903},"    \u002F\u002F Тут status: \"error\"\n",[3856,6844,6845,6847,6849,6851,6853,6856],{"class":3858,"line":3952},[3856,6846,4074],{"class":3874},[3856,6848,3925],{"class":3870},[3856,6850,3928],{"class":3866},[3856,6852,3871],{"class":3870},[3856,6854,6855],{"class":4060},"\"✗ Operation failed\"",[3856,6857,4896],{"class":3870},[3856,6859,6860,6862,6864],{"class":3858,"line":3958},[3856,6861,4096],{"class":3870},[3856,6863,4099],{"class":4046},[3856,6865,3897],{"class":3870},[3856,6867,6868],{"class":3858,"line":4138},[3856,6869,6870],{"class":3903},"    \u002F\u002F Тут status: \"pending\" (єдиний варіант, що залишився)\n",[3856,6872,6873,6875,6877,6879,6881,6884],{"class":3858,"line":4144},[3856,6874,4074],{"class":3874},[3856,6876,3925],{"class":3870},[3856,6878,3928],{"class":3866},[3856,6880,3871],{"class":3870},[3856,6882,6883],{"class":4060},"\"⏳ Operation in progress\"",[3856,6885,4896],{"class":3870},[3856,6887,6888],{"class":3858,"line":4149},[3856,6889,4141],{"class":3870},[3856,6891,6892],{"class":3858,"line":4156},[3856,6893,3961],{"class":3870},[3838,6895,6897],{"id":6896},"виключення-null-та-undefined-через","Виключення null та undefined через ===",[3843,6899,6900,6901,3824,6903,6906],{},"Перевірка через ",[3761,6902,5459],{},[3761,6904,6905],{},"=== undefined"," звужує тип:",[3847,6908,6910],{"className":3849,"code":6909,"language":3851,"meta":3852,"style":3852},"function processValue(value: string | null | undefined): void {\n  if (value === null) {\n    console.log(\"Value is null\");\n    return;\n  }\n  \n  if (value === undefined) {\n    console.log(\"Value is undefined\");\n    return;\n  }\n  \n  \u002F\u002F Тут value: string (null та undefined виключені)\n  console.log(value.toUpperCase());\n}\n",[3761,6911,6912,6940,6954,6968,6974,6978,6982,6996,7011,7017,7021,7025,7030,7048],{"__ignoreMap":3852},[3856,6913,6914,6916,6918,6920,6922,6924,6926,6928,6930,6932,6934,6936,6938],{"class":3858,"line":3859},[3856,6915,3863],{"class":3862},[3856,6917,3867],{"class":3866},[3856,6919,3871],{"class":3870},[3856,6921,3875],{"class":3874},[3856,6923,3878],{"class":3870},[3856,6925,3882],{"class":3881},[3856,6927,3885],{"class":3870},[3856,6929,5299],{"class":3881},[3856,6931,3885],{"class":3870},[3856,6933,5139],{"class":3881},[3856,6935,3891],{"class":3870},[3856,6937,3894],{"class":3881},[3856,6939,3897],{"class":3870},[3856,6941,6942,6944,6946,6948,6950,6952],{"class":3858,"line":3900},[3856,6943,4047],{"class":4046},[3856,6945,3981],{"class":3870},[3856,6947,3875],{"class":3874},[3856,6949,4057],{"class":3870},[3856,6951,5299],{"class":3862},[3856,6953,4064],{"class":3870},[3856,6955,6956,6958,6960,6962,6964,6966],{"class":3858,"line":3907},[3856,6957,4074],{"class":3874},[3856,6959,3925],{"class":3870},[3856,6961,3928],{"class":3866},[3856,6963,3871],{"class":3870},[3856,6965,5395],{"class":4060},[3856,6967,4896],{"class":3870},[3856,6969,6970,6972],{"class":3858,"line":3913},[3856,6971,4840],{"class":4046},[3856,6973,4931],{"class":3870},[3856,6975,6976],{"class":3858,"line":3919},[3856,6977,4141],{"class":3870},[3856,6979,6980],{"class":3858,"line":3946},[3856,6981,3916],{"class":3870},[3856,6983,6984,6986,6988,6990,6992,6994],{"class":3858,"line":3952},[3856,6985,4047],{"class":4046},[3856,6987,3981],{"class":3870},[3856,6989,3875],{"class":3874},[3856,6991,4057],{"class":3870},[3856,6993,5139],{"class":3862},[3856,6995,4064],{"class":3870},[3856,6997,6998,7000,7002,7004,7006,7009],{"class":3858,"line":3958},[3856,6999,4074],{"class":3874},[3856,7001,3925],{"class":3870},[3856,7003,3928],{"class":3866},[3856,7005,3871],{"class":3870},[3856,7007,7008],{"class":4060},"\"Value is undefined\"",[3856,7010,4896],{"class":3870},[3856,7012,7013,7015],{"class":3858,"line":4138},[3856,7014,4840],{"class":4046},[3856,7016,4931],{"class":3870},[3856,7018,7019],{"class":3858,"line":4144},[3856,7020,4141],{"class":3870},[3856,7022,7023],{"class":3858,"line":4149},[3856,7024,3916],{"class":3870},[3856,7026,7027],{"class":3858,"line":4156},[3856,7028,7029],{"class":3903},"  \u002F\u002F Тут value: string (null та undefined виключені)\n",[3856,7031,7032,7034,7036,7038,7040,7042,7044,7046],{"class":3858,"line":4173},[3856,7033,3922],{"class":3874},[3856,7035,3925],{"class":3870},[3856,7037,3928],{"class":3866},[3856,7039,3871],{"class":3870},[3856,7041,3875],{"class":3874},[3856,7043,3925],{"class":3870},[3856,7045,3937],{"class":3866},[3856,7047,5083],{"class":3870},[3856,7049,7050],{"class":3858,"line":4288},[3856,7051,3961],{"class":3870},[3843,7053,7054],{},[3793,7055,7056],{},"Або через !== для виключення:",[3847,7058,7060],{"className":3849,"code":7059,"language":3851,"meta":3852,"style":3852},"function processValue(value: string | null): void {\n  if (value !== null) {\n    \u002F\u002F Тут value: string\n    console.log(value.toUpperCase());\n  }\n}\n",[3761,7061,7062,7086,7100,7105,7123,7127],{"__ignoreMap":3852},[3856,7063,7064,7066,7068,7070,7072,7074,7076,7078,7080,7082,7084],{"class":3858,"line":3859},[3856,7065,3863],{"class":3862},[3856,7067,3867],{"class":3866},[3856,7069,3871],{"class":3870},[3856,7071,3875],{"class":3874},[3856,7073,3878],{"class":3870},[3856,7075,3882],{"class":3881},[3856,7077,3885],{"class":3870},[3856,7079,5299],{"class":3881},[3856,7081,3891],{"class":3870},[3856,7083,3894],{"class":3881},[3856,7085,3897],{"class":3870},[3856,7087,7088,7090,7092,7094,7096,7098],{"class":3858,"line":3900},[3856,7089,4047],{"class":4046},[3856,7091,3981],{"class":3870},[3856,7093,3875],{"class":3874},[3856,7095,6027],{"class":3870},[3856,7097,5299],{"class":3862},[3856,7099,4064],{"class":3870},[3856,7101,7102],{"class":3858,"line":3907},[3856,7103,7104],{"class":3903},"    \u002F\u002F Тут value: string\n",[3856,7106,7107,7109,7111,7113,7115,7117,7119,7121],{"class":3858,"line":3913},[3856,7108,4074],{"class":3874},[3856,7110,3925],{"class":3870},[3856,7112,3928],{"class":3866},[3856,7114,3871],{"class":3870},[3856,7116,3875],{"class":3874},[3856,7118,3925],{"class":3870},[3856,7120,3937],{"class":3866},[3856,7122,5083],{"class":3870},[3856,7124,7125],{"class":3858,"line":3919},[3856,7126,4141],{"class":3870},[3856,7128,7129],{"class":3858,"line":3946},[3856,7130,3961],{"class":3870},[3838,7132,7134],{"id":7133},"switch-statement-для-звуження","Switch statement для звуження",[3843,7136,7137,7140],{},[3761,7138,7139],{},"switch"," також звужує типи:",[3847,7142,7144],{"className":3849,"code":7143,"language":3851,"meta":3852,"style":3852},"function handleEvent(event: \"click\" | \"focus\" | \"blur\"): void {\n  switch (event) {\n    case \"click\":\n      \u002F\u002F Тут event: \"click\"\n      console.log(\"Button clicked\");\n      break;\n    \n    case \"focus\":\n      \u002F\u002F Тут event: \"focus\"\n      console.log(\"Input focused\");\n      break;\n    \n    case \"blur\":\n      \u002F\u002F Тут event: \"blur\"\n      console.log(\"Input blurred\");\n      break;\n    \n    default:\n      \u002F\u002F Якщо всі варіанти оброблені, цей блок ніколи не виконається\n      const exhaustiveCheck: never = event;\n      throw new Error(`Unhandled event: ${exhaustiveCheck}`);\n  }\n}\n",[3761,7145,7146,7179,7190,7201,7206,7222,7229,7234,7243,7248,7263,7269,7273,7282,7287,7302,7308,7312,7319,7324,7344,7371,7375],{"__ignoreMap":3852},[3856,7147,7148,7150,7153,7155,7158,7160,7163,7165,7168,7170,7173,7175,7177],{"class":3858,"line":3859},[3856,7149,3863],{"class":3862},[3856,7151,7152],{"class":3866}," handleEvent",[3856,7154,3871],{"class":3870},[3856,7156,7157],{"class":3874},"event",[3856,7159,3878],{"class":3870},[3856,7161,7162],{"class":4060},"\"click\"",[3856,7164,3885],{"class":3870},[3856,7166,7167],{"class":4060},"\"focus\"",[3856,7169,3885],{"class":3870},[3856,7171,7172],{"class":4060},"\"blur\"",[3856,7174,3891],{"class":3870},[3856,7176,3894],{"class":3881},[3856,7178,3897],{"class":3870},[3856,7180,7181,7184,7186,7188],{"class":3858,"line":3900},[3856,7182,7183],{"class":4046},"  switch",[3856,7185,3981],{"class":3870},[3856,7187,7157],{"class":3874},[3856,7189,4064],{"class":3870},[3856,7191,7192,7195,7198],{"class":3858,"line":3907},[3856,7193,7194],{"class":4046},"    case",[3856,7196,7197],{"class":4060}," \"click\"",[3856,7199,7200],{"class":3870},":\n",[3856,7202,7203],{"class":3858,"line":3913},[3856,7204,7205],{"class":3903},"      \u002F\u002F Тут event: \"click\"\n",[3856,7207,7208,7211,7213,7215,7217,7220],{"class":3858,"line":3919},[3856,7209,7210],{"class":3874},"      console",[3856,7212,3925],{"class":3870},[3856,7214,3928],{"class":3866},[3856,7216,3871],{"class":3870},[3856,7218,7219],{"class":4060},"\"Button clicked\"",[3856,7221,4896],{"class":3870},[3856,7223,7224,7227],{"class":3858,"line":3946},[3856,7225,7226],{"class":4046},"      break",[3856,7228,4931],{"class":3870},[3856,7230,7231],{"class":3858,"line":3952},[3856,7232,7233],{"class":3870},"    \n",[3856,7235,7236,7238,7241],{"class":3858,"line":3958},[3856,7237,7194],{"class":4046},[3856,7239,7240],{"class":4060}," \"focus\"",[3856,7242,7200],{"class":3870},[3856,7244,7245],{"class":3858,"line":4138},[3856,7246,7247],{"class":3903},"      \u002F\u002F Тут event: \"focus\"\n",[3856,7249,7250,7252,7254,7256,7258,7261],{"class":3858,"line":4144},[3856,7251,7210],{"class":3874},[3856,7253,3925],{"class":3870},[3856,7255,3928],{"class":3866},[3856,7257,3871],{"class":3870},[3856,7259,7260],{"class":4060},"\"Input focused\"",[3856,7262,4896],{"class":3870},[3856,7264,7265,7267],{"class":3858,"line":4149},[3856,7266,7226],{"class":4046},[3856,7268,4931],{"class":3870},[3856,7270,7271],{"class":3858,"line":4156},[3856,7272,7233],{"class":3870},[3856,7274,7275,7277,7280],{"class":3858,"line":4173},[3856,7276,7194],{"class":4046},[3856,7278,7279],{"class":4060}," \"blur\"",[3856,7281,7200],{"class":3870},[3856,7283,7284],{"class":3858,"line":4288},[3856,7285,7286],{"class":3903},"      \u002F\u002F Тут event: \"blur\"\n",[3856,7288,7289,7291,7293,7295,7297,7300],{"class":3858,"line":4293},[3856,7290,7210],{"class":3874},[3856,7292,3925],{"class":3870},[3856,7294,3928],{"class":3866},[3856,7296,3871],{"class":3870},[3856,7298,7299],{"class":4060},"\"Input blurred\"",[3856,7301,4896],{"class":3870},[3856,7303,7304,7306],{"class":3858,"line":4299},[3856,7305,7226],{"class":4046},[3856,7307,4931],{"class":3870},[3856,7309,7310],{"class":3858,"line":4304},[3856,7311,7233],{"class":3870},[3856,7313,7314,7317],{"class":3858,"line":4310},[3856,7315,7316],{"class":4046},"    default",[3856,7318,7200],{"class":3870},[3856,7320,7321],{"class":3858,"line":4316},[3856,7322,7323],{"class":3903},"      \u002F\u002F Якщо всі варіанти оброблені, цей блок ніколи не виконається\n",[3856,7325,7326,7329,7333,7335,7338,7340,7342],{"class":3858,"line":4322},[3856,7327,7328],{"class":3862},"      const",[3856,7330,7332],{"class":7331},"s-QsJ"," exhaustiveCheck",[3856,7334,3878],{"class":3870},[3856,7336,7337],{"class":3881},"never",[3856,7339,6507],{"class":3870},[3856,7341,7157],{"class":3874},[3856,7343,4931],{"class":3870},[3856,7345,7346,7349,7352,7355,7357,7360,7362,7365,7367,7369],{"class":3858,"line":4328},[3856,7347,7348],{"class":4046},"      throw",[3856,7350,7351],{"class":3862}," new",[3856,7353,7354],{"class":3866}," Error",[3856,7356,3871],{"class":3870},[3856,7358,7359],{"class":4060},"`Unhandled event: ",[3856,7361,5238],{"class":3862},[3856,7363,7364],{"class":3874},"exhaustiveCheck",[3856,7366,5249],{"class":3862},[3856,7368,5252],{"class":4060},[3856,7370,4896],{"class":3870},[3856,7372,7373],{"class":3858,"line":4333},[3856,7374,4141],{"class":3870},[3856,7376,7377],{"class":3858,"line":4338},[3856,7378,3961],{"class":3870},[4483,7380,7381,7384,7385,7387,7388,7391,7392,7394,7395,3925],{},[3793,7382,7383],{},"Exhaustiveness checking:"," Призначення змінної типу ",[3761,7386,7337],{}," у блоці ",[3761,7389,7390],{},"default"," — це патерн для перевірки повноти обробки всіх варіантів. Якщо ви додасте новий варіант до union type, але забудете обробити його у ",[3761,7393,7139],{},", TypeScript видасть помилку у блоці ",[3761,7396,7390],{},[3830,7398],{},[3833,7400,7402],{"id":7401},"оператор-in-для-звуження","Оператор in для звуження",[3838,7404,7406],{"id":7405},"перевірка-наявності-властивості","Перевірка наявності властивості",[3843,7408,6263,7409,7411],{},[3761,7410,3770],{}," перевіряє, чи існує властивість в об'єкті:",[3847,7413,7415],{"className":4515,"code":7414,"language":4517,"meta":3852,"style":3852},"let user = { name: \"Alice\", age: 28 };\n\nconsole.log(\"name\" in user);    \u002F\u002F true\nconsole.log(\"email\" in user);   \u002F\u002F false\nconsole.log(\"toString\" in user); \u002F\u002F true (успадковано від Object.prototype)\n",[3761,7416,7417,7444,7448,7471,7493],{"__ignoreMap":3852},[3856,7418,7419,7421,7424,7427,7430,7433,7435,7438,7441],{"class":3858,"line":3859},[3856,7420,6494],{"class":3862},[3856,7422,7423],{"class":3874}," user",[3856,7425,7426],{"class":3870}," = { ",[3856,7428,7429],{"class":3874},"name:",[3856,7431,7432],{"class":4060}," \"Alice\"",[3856,7434,3764],{"class":3870},[3856,7436,7437],{"class":3874},"age:",[3856,7439,7440],{"class":4128}," 28",[3856,7442,7443],{"class":3870}," };\n",[3856,7445,7446],{"class":3858,"line":3900},[3856,7447,4153],{"emptyLinePlaceholder":4152},[3856,7449,7450,7452,7454,7456,7458,7461,7464,7466,7468],{"class":3858,"line":3907},[3856,7451,4524],{"class":3874},[3856,7453,3925],{"class":3870},[3856,7455,3928],{"class":3866},[3856,7457,3871],{"class":3870},[3856,7459,7460],{"class":4060},"\"name\"",[3856,7462,7463],{"class":3862}," in",[3856,7465,7423],{"class":3874},[3856,7467,5288],{"class":3870},[3856,7469,7470],{"class":3903},"\u002F\u002F true\n",[3856,7472,7473,7475,7477,7479,7481,7484,7486,7488,7490],{"class":3858,"line":3913},[3856,7474,4524],{"class":3874},[3856,7476,3925],{"class":3870},[3856,7478,3928],{"class":3866},[3856,7480,3871],{"class":3870},[3856,7482,7483],{"class":4060},"\"email\"",[3856,7485,7463],{"class":3862},[3856,7487,7423],{"class":3874},[3856,7489,5949],{"class":3870},[3856,7491,7492],{"class":3903},"\u002F\u002F false\n",[3856,7494,7495,7497,7499,7501,7503,7506,7508,7510,7513],{"class":3858,"line":3919},[3856,7496,4524],{"class":3874},[3856,7498,3925],{"class":3870},[3856,7500,3928],{"class":3866},[3856,7502,3871],{"class":3870},[3856,7504,7505],{"class":4060},"\"toString\"",[3856,7507,7463],{"class":3862},[3856,7509,7423],{"class":3874},[3856,7511,7512],{"class":3870},"); ",[3856,7514,7515],{"class":3903},"\u002F\u002F true (успадковано від Object.prototype)\n",[3838,7517,7519],{"id":7518},"використання-in-як-type-guard","Використання in як type guard",[3843,7521,7522,7523,7525],{},"TypeScript розуміє оператор ",[3761,7524,3770],{}," та використовує його для звуження union types:",[3847,7527,7529],{"className":3849,"code":7528,"language":3851,"meta":3852,"style":3852},"function processShape(shape: { kind: \"circle\"; radius: number } | { kind: \"square\"; side: number }): number {\n  if (\"radius\" in shape) {\n    \u002F\u002F Тут TypeScript знає, що shape має властивість radius\n    \u002F\u002F Отже, це { kind: \"circle\"; radius: number }\n    return Math.PI * shape.radius ** 2;\n  } else {\n    \u002F\u002F Тут shape: { kind: \"square\"; side: number }\n    return shape.side ** 2;\n  }\n}\n\nconsole.log(processShape({ kind: \"circle\", radius: 5 }));  \u002F\u002F 78.54\nconsole.log(processShape({ kind: \"square\", side: 4 }));    \u002F\u002F 16\n",[3761,7530,7531,7590,7606,7611,7616,7644,7652,7657,7673,7677,7681,7685,7721],{"__ignoreMap":3852},[3856,7532,7533,7535,7538,7540,7543,7546,7549,7551,7554,7557,7560,7562,7564,7567,7569,7571,7574,7576,7579,7581,7583,7586,7588],{"class":3858,"line":3859},[3856,7534,3863],{"class":3862},[3856,7536,7537],{"class":3866}," processShape",[3856,7539,3871],{"class":3870},[3856,7541,7542],{"class":3874},"shape",[3856,7544,7545],{"class":3870},": { ",[3856,7547,7548],{"class":3874},"kind",[3856,7550,3878],{"class":3870},[3856,7552,7553],{"class":4060},"\"circle\"",[3856,7555,7556],{"class":3870},"; ",[3856,7558,7559],{"class":3874},"radius",[3856,7561,3878],{"class":3870},[3856,7563,3888],{"class":3881},[3856,7565,7566],{"class":3870}," } | { ",[3856,7568,7548],{"class":3874},[3856,7570,3878],{"class":3870},[3856,7572,7573],{"class":4060},"\"square\"",[3856,7575,7556],{"class":3870},[3856,7577,7578],{"class":3874},"side",[3856,7580,3878],{"class":3870},[3856,7582,3888],{"class":3881},[3856,7584,7585],{"class":3870}," }): ",[3856,7587,3888],{"class":3881},[3856,7589,3897],{"class":3870},[3856,7591,7592,7594,7596,7599,7601,7604],{"class":3858,"line":3900},[3856,7593,4047],{"class":4046},[3856,7595,3981],{"class":3870},[3856,7597,7598],{"class":4060},"\"radius\"",[3856,7600,7463],{"class":3862},[3856,7602,7603],{"class":3874}," shape",[3856,7605,4064],{"class":3870},[3856,7607,7608],{"class":3858,"line":3907},[3856,7609,7610],{"class":3903},"    \u002F\u002F Тут TypeScript знає, що shape має властивість radius\n",[3856,7612,7613],{"class":3858,"line":3913},[3856,7614,7615],{"class":3903},"    \u002F\u002F Отже, це { kind: \"circle\"; radius: number }\n",[3856,7617,7618,7620,7623,7625,7628,7631,7633,7635,7637,7640,7642],{"class":3858,"line":3919},[3856,7619,4840],{"class":4046},[3856,7621,7622],{"class":3874}," Math",[3856,7624,3925],{"class":3870},[3856,7626,7627],{"class":7331},"PI",[3856,7629,7630],{"class":3870}," * ",[3856,7632,7542],{"class":3874},[3856,7634,3925],{"class":3870},[3856,7636,7559],{"class":3874},[3856,7638,7639],{"class":3870}," ** ",[3856,7641,4129],{"class":4128},[3856,7643,4931],{"class":3870},[3856,7645,7646,7648,7650],{"class":3858,"line":3946},[3856,7647,4096],{"class":3870},[3856,7649,4099],{"class":4046},[3856,7651,3897],{"class":3870},[3856,7653,7654],{"class":3858,"line":3952},[3856,7655,7656],{"class":3903},"    \u002F\u002F Тут shape: { kind: \"square\"; side: number }\n",[3856,7658,7659,7661,7663,7665,7667,7669,7671],{"class":3858,"line":3958},[3856,7660,4840],{"class":4046},[3856,7662,7603],{"class":3874},[3856,7664,3925],{"class":3870},[3856,7666,7578],{"class":3874},[3856,7668,7639],{"class":3870},[3856,7670,4129],{"class":4128},[3856,7672,4931],{"class":3870},[3856,7674,7675],{"class":3858,"line":4138},[3856,7676,4141],{"class":3870},[3856,7678,7679],{"class":3858,"line":4144},[3856,7680,3961],{"class":3870},[3856,7682,7683],{"class":3858,"line":4149},[3856,7684,4153],{"emptyLinePlaceholder":4152},[3856,7686,7687,7689,7691,7693,7695,7698,7701,7704,7707,7709,7712,7715,7718],{"class":3858,"line":4156},[3856,7688,4524],{"class":3874},[3856,7690,3925],{"class":3870},[3856,7692,3928],{"class":3866},[3856,7694,3871],{"class":3870},[3856,7696,7697],{"class":3866},"processShape",[3856,7699,7700],{"class":3870},"({ ",[3856,7702,7703],{"class":3874},"kind:",[3856,7705,7706],{"class":4060}," \"circle\"",[3856,7708,3764],{"class":3870},[3856,7710,7711],{"class":3874},"radius:",[3856,7713,7714],{"class":4128}," 5",[3856,7716,7717],{"class":3870}," }));  ",[3856,7719,7720],{"class":3903},"\u002F\u002F 78.54\n",[3856,7722,7723,7725,7727,7729,7731,7733,7735,7737,7740,7742,7745,7748,7751],{"class":3858,"line":4173},[3856,7724,4524],{"class":3874},[3856,7726,3925],{"class":3870},[3856,7728,3928],{"class":3866},[3856,7730,3871],{"class":3870},[3856,7732,7697],{"class":3866},[3856,7734,7700],{"class":3870},[3856,7736,7703],{"class":3874},[3856,7738,7739],{"class":4060}," \"square\"",[3856,7741,3764],{"class":3870},[3856,7743,7744],{"class":3874},"side:",[3856,7746,7747],{"class":4128}," 4",[3856,7749,7750],{"class":3870}," }));    ",[3856,7752,7753],{"class":3903},"\u002F\u002F 16\n",[3843,7755,7756],{},[3793,7757,7758],{},"Приклад з різними структурами:",[3847,7760,7762],{"className":3849,"code":7761,"language":3851,"meta":3852,"style":3852},"function printInfo(entity: { name: string; email: string } | { name: string; phone: string }): void {\n  console.log(`Name: ${entity.name}`);\n  \n  if (\"email\" in entity) {\n    \u002F\u002F Тут entity має властивість email\n    console.log(`Email: ${entity.email}`);\n  } else {\n    \u002F\u002F Тут entity має властивість phone\n    console.log(`Phone: ${entity.phone}`);\n  }\n}\n\nprintInfo({ name: \"Alice\", email: \"alice@example.com\" });\n\u002F\u002F Name: Alice\n\u002F\u002F Email: alice@example.com\n\nprintInfo({ name: \"Bob\", phone: \"+380991234567\" });\n\u002F\u002F Name: Bob\n\u002F\u002F Phone: +380991234567\n",[3761,7763,7764,7816,7842,7846,7861,7866,7893,7901,7906,7933,7937,7941,7945,7967,7972,7977,7981,8002,8007],{"__ignoreMap":3852},[3856,7765,7766,7768,7771,7773,7776,7778,7780,7782,7784,7786,7789,7791,7793,7795,7797,7799,7801,7803,7806,7808,7810,7812,7814],{"class":3858,"line":3859},[3856,7767,3863],{"class":3862},[3856,7769,7770],{"class":3866}," printInfo",[3856,7772,3871],{"class":3870},[3856,7774,7775],{"class":3874},"entity",[3856,7777,7545],{"class":3870},[3856,7779,5805],{"class":3874},[3856,7781,3878],{"class":3870},[3856,7783,3882],{"class":3881},[3856,7785,7556],{"class":3870},[3856,7787,7788],{"class":3874},"email",[3856,7790,3878],{"class":3870},[3856,7792,3882],{"class":3881},[3856,7794,7566],{"class":3870},[3856,7796,5805],{"class":3874},[3856,7798,3878],{"class":3870},[3856,7800,3882],{"class":3881},[3856,7802,7556],{"class":3870},[3856,7804,7805],{"class":3874},"phone",[3856,7807,3878],{"class":3870},[3856,7809,3882],{"class":3881},[3856,7811,7585],{"class":3870},[3856,7813,3894],{"class":3881},[3856,7815,3897],{"class":3870},[3856,7817,7818,7820,7822,7824,7826,7828,7830,7832,7834,7836,7838,7840],{"class":3858,"line":3900},[3856,7819,3922],{"class":3874},[3856,7821,3925],{"class":3870},[3856,7823,3928],{"class":3866},[3856,7825,3871],{"class":3870},[3856,7827,6058],{"class":4060},[3856,7829,5238],{"class":3862},[3856,7831,7775],{"class":3874},[3856,7833,3925],{"class":5243},[3856,7835,5805],{"class":3874},[3856,7837,5249],{"class":3862},[3856,7839,5252],{"class":4060},[3856,7841,4896],{"class":3870},[3856,7843,7844],{"class":3858,"line":3907},[3856,7845,3916],{"class":3870},[3856,7847,7848,7850,7852,7854,7856,7859],{"class":3858,"line":3913},[3856,7849,4047],{"class":4046},[3856,7851,3981],{"class":3870},[3856,7853,7483],{"class":4060},[3856,7855,7463],{"class":3862},[3856,7857,7858],{"class":3874}," entity",[3856,7860,4064],{"class":3870},[3856,7862,7863],{"class":3858,"line":3919},[3856,7864,7865],{"class":3903},"    \u002F\u002F Тут entity має властивість email\n",[3856,7867,7868,7870,7872,7874,7876,7879,7881,7883,7885,7887,7889,7891],{"class":3858,"line":3946},[3856,7869,4074],{"class":3874},[3856,7871,3925],{"class":3870},[3856,7873,3928],{"class":3866},[3856,7875,3871],{"class":3870},[3856,7877,7878],{"class":4060},"`Email: ",[3856,7880,5238],{"class":3862},[3856,7882,7775],{"class":3874},[3856,7884,3925],{"class":5243},[3856,7886,7788],{"class":3874},[3856,7888,5249],{"class":3862},[3856,7890,5252],{"class":4060},[3856,7892,4896],{"class":3870},[3856,7894,7895,7897,7899],{"class":3858,"line":3952},[3856,7896,4096],{"class":3870},[3856,7898,4099],{"class":4046},[3856,7900,3897],{"class":3870},[3856,7902,7903],{"class":3858,"line":3958},[3856,7904,7905],{"class":3903},"    \u002F\u002F Тут entity має властивість phone\n",[3856,7907,7908,7910,7912,7914,7916,7919,7921,7923,7925,7927,7929,7931],{"class":3858,"line":4138},[3856,7909,4074],{"class":3874},[3856,7911,3925],{"class":3870},[3856,7913,3928],{"class":3866},[3856,7915,3871],{"class":3870},[3856,7917,7918],{"class":4060},"`Phone: ",[3856,7920,5238],{"class":3862},[3856,7922,7775],{"class":3874},[3856,7924,3925],{"class":5243},[3856,7926,7805],{"class":3874},[3856,7928,5249],{"class":3862},[3856,7930,5252],{"class":4060},[3856,7932,4896],{"class":3870},[3856,7934,7935],{"class":3858,"line":4144},[3856,7936,4141],{"class":3870},[3856,7938,7939],{"class":3858,"line":4149},[3856,7940,3961],{"class":3870},[3856,7942,7943],{"class":3858,"line":4156},[3856,7944,4153],{"emptyLinePlaceholder":4152},[3856,7946,7947,7950,7952,7954,7956,7958,7961,7964],{"class":3858,"line":4173},[3856,7948,7949],{"class":3866},"printInfo",[3856,7951,7700],{"class":3870},[3856,7953,7429],{"class":3874},[3856,7955,7432],{"class":4060},[3856,7957,3764],{"class":3870},[3856,7959,7960],{"class":3874},"email:",[3856,7962,7963],{"class":4060}," \"alice@example.com\"",[3856,7965,7966],{"class":3870}," });\n",[3856,7968,7969],{"class":3858,"line":4288},[3856,7970,7971],{"class":3903},"\u002F\u002F Name: Alice\n",[3856,7973,7974],{"class":3858,"line":4293},[3856,7975,7976],{"class":3903},"\u002F\u002F Email: alice@example.com\n",[3856,7978,7979],{"class":3858,"line":4299},[3856,7980,4153],{"emptyLinePlaceholder":4152},[3856,7982,7983,7985,7987,7989,7992,7994,7997,8000],{"class":3858,"line":4304},[3856,7984,7949],{"class":3866},[3856,7986,7700],{"class":3870},[3856,7988,7429],{"class":3874},[3856,7990,7991],{"class":4060}," \"Bob\"",[3856,7993,3764],{"class":3870},[3856,7995,7996],{"class":3874},"phone:",[3856,7998,7999],{"class":4060}," \"+380991234567\"",[3856,8001,7966],{"class":3870},[3856,8003,8004],{"class":3858,"line":4310},[3856,8005,8006],{"class":3903},"\u002F\u002F Name: Bob\n",[3856,8008,8009],{"class":3858,"line":4316},[3856,8010,8011],{"class":3903},"\u002F\u002F Phone: +380991234567\n",[3838,8013,8015],{"id":8014},"обмеження-оператора-in","Обмеження оператора in",[3843,8017,6263,8018,8020,8021,8024,8025,4737],{},[3761,8019,3770],{}," перевіряє ",[3793,8022,8023],{},"наявність"," властивості, але не її ",[3793,8026,8027],{},"тип",[3847,8029,8031],{"className":3849,"code":8030,"language":3851,"meta":3852,"style":3852},"function example(obj: { x: number } | { y: string }): void {\n  if (\"x\" in obj) {\n    console.log(obj.x);  \u002F\u002F OK: obj має x\n  }\n}\n\n\u002F\u002F Але це може призвести до помилок:\nexample({ x: 42, y: \"hello\" });  \u002F\u002F obj має ОБИ властивості!\n",[3761,8032,8033,8066,8082,8103,8107,8111,8115,8120],{"__ignoreMap":3852},[3856,8034,8035,8037,8039,8041,8044,8046,8048,8050,8052,8054,8056,8058,8060,8062,8064],{"class":3858,"line":3859},[3856,8036,3863],{"class":3862},[3856,8038,5023],{"class":3866},[3856,8040,3871],{"class":3870},[3856,8042,8043],{"class":3874},"obj",[3856,8045,7545],{"class":3870},[3856,8047,5028],{"class":3874},[3856,8049,3878],{"class":3870},[3856,8051,3888],{"class":3881},[3856,8053,7566],{"class":3870},[3856,8055,6607],{"class":3874},[3856,8057,3878],{"class":3870},[3856,8059,3882],{"class":3881},[3856,8061,7585],{"class":3870},[3856,8063,3894],{"class":3881},[3856,8065,3897],{"class":3870},[3856,8067,8068,8070,8072,8075,8077,8080],{"class":3858,"line":3900},[3856,8069,4047],{"class":4046},[3856,8071,3981],{"class":3870},[3856,8073,8074],{"class":4060},"\"x\"",[3856,8076,7463],{"class":3862},[3856,8078,8079],{"class":3874}," obj",[3856,8081,4064],{"class":3870},[3856,8083,8084,8086,8088,8090,8092,8094,8096,8098,8100],{"class":3858,"line":3907},[3856,8085,4074],{"class":3874},[3856,8087,3925],{"class":3870},[3856,8089,3928],{"class":3866},[3856,8091,3871],{"class":3870},[3856,8093,8043],{"class":3874},[3856,8095,3925],{"class":3870},[3856,8097,5028],{"class":3874},[3856,8099,4167],{"class":3870},[3856,8101,8102],{"class":3903},"\u002F\u002F OK: obj має x\n",[3856,8104,8105],{"class":3858,"line":3913},[3856,8106,4141],{"class":3870},[3856,8108,8109],{"class":3858,"line":3919},[3856,8110,3961],{"class":3870},[3856,8112,8113],{"class":3858,"line":3946},[3856,8114,4153],{"emptyLinePlaceholder":4152},[3856,8116,8117],{"class":3858,"line":3952},[3856,8118,8119],{"class":3903},"\u002F\u002F Але це може призвести до помилок:\n",[3856,8121,8122,8125,8127,8130,8132,8134,8137,8139,8142],{"class":3858,"line":3958},[3856,8123,8124],{"class":3866},"example",[3856,8126,7700],{"class":3870},[3856,8128,8129],{"class":3874},"x:",[3856,8131,4555],{"class":4128},[3856,8133,3764],{"class":3870},[3856,8135,8136],{"class":3874},"y:",[3856,8138,4535],{"class":4060},[3856,8140,8141],{"class":3870}," });  ",[3856,8143,8144],{"class":3903},"\u002F\u002F obj має ОБИ властивості!\n",[3843,8146,8147,8148,8151],{},"У складних випадках краще використовувати ",[3793,8149,8150],{},"discriminated unions"," (про них далі).",[5440,8153,8154,8163,8228],{},[3843,8155,6263,8156,8158,8159,8162],{},[3761,8157,3770],{}," перевіряє наявність властивості ",[3793,8160,8161],{},"як власної, так і успадкованої"," з прототипу:",[3847,8164,8166],{"className":4515,"code":8165,"language":4517,"meta":3852,"style":3852},"let obj = { name: \"Alice\" };\n\nconsole.log(\"name\" in obj);      \u002F\u002F true (власна властивість)\nconsole.log(\"toString\" in obj);  \u002F\u002F true (успадкована з Object.prototype)\n",[3761,8167,8168,8182,8186,8207],{"__ignoreMap":3852},[3856,8169,8170,8172,8174,8176,8178,8180],{"class":3858,"line":3859},[3856,8171,6494],{"class":3862},[3856,8173,8079],{"class":3874},[3856,8175,7426],{"class":3870},[3856,8177,7429],{"class":3874},[3856,8179,7432],{"class":4060},[3856,8181,7443],{"class":3870},[3856,8183,8184],{"class":3858,"line":3900},[3856,8185,4153],{"emptyLinePlaceholder":4152},[3856,8187,8188,8190,8192,8194,8196,8198,8200,8202,8204],{"class":3858,"line":3907},[3856,8189,4524],{"class":3874},[3856,8191,3925],{"class":3870},[3856,8193,3928],{"class":3866},[3856,8195,3871],{"class":3870},[3856,8197,7460],{"class":4060},[3856,8199,7463],{"class":3862},[3856,8201,8079],{"class":3874},[3856,8203,5274],{"class":3870},[3856,8205,8206],{"class":3903},"\u002F\u002F true (власна властивість)\n",[3856,8208,8209,8211,8213,8215,8217,8219,8221,8223,8225],{"class":3858,"line":3913},[3856,8210,4524],{"class":3874},[3856,8212,3925],{"class":3870},[3856,8214,3928],{"class":3866},[3856,8216,3871],{"class":3870},[3856,8218,7505],{"class":4060},[3856,8220,7463],{"class":3862},[3856,8222,8079],{"class":3874},[3856,8224,4167],{"class":3870},[3856,8226,8227],{"class":3903},"\u002F\u002F true (успадкована з Object.prototype)\n",[3843,8229,8230,8231,3824,8234,3925],{},"Якщо потрібна перевірка лише власних властивостей, використовуйте ",[3761,8232,8233],{},"Object.hasOwn(obj, \"prop\")",[3761,8235,8236],{},"obj.hasOwnProperty(\"prop\")",[3830,8238],{},[3833,8240,8242],{"id":8241},"instanceof-для-класів","Instanceof для класів",[3838,8244,8246],{"id":8245},"оператор-instanceof-у-javascript","Оператор instanceof у JavaScript",[3843,8248,6263,8249,8251],{},[3761,8250,3767],{}," перевіряє, чи є об'єкт екземпляром певного класу (конструктора):",[3847,8253,8255],{"className":4515,"code":8254,"language":4517,"meta":3852,"style":3852},"class Dog {\n  bark() {\n    console.log(\"Woof!\");\n  }\n}\n\nclass Cat {\n  meow() {\n    console.log(\"Meow!\");\n  }\n}\n\nlet pet1 = new Dog();\nlet pet2 = new Cat();\n\nconsole.log(pet1 instanceof Dog);  \u002F\u002F true\nconsole.log(pet1 instanceof Cat);  \u002F\u002F false\nconsole.log(pet2 instanceof Cat);  \u002F\u002F true\n\nconsole.log([] instanceof Array);   \u002F\u002F true\nconsole.log({} instanceof Object);  \u002F\u002F true\nconsole.log(new Date() instanceof Date);  \u002F\u002F true\n",[3761,8256,8257,8267,8275,8290,8294,8298,8302,8311,8318,8333,8337,8341,8345,8361,8376,8380,8402,8422,8443,8447,8467,8487],{"__ignoreMap":3852},[3856,8258,8259,8262,8265],{"class":3858,"line":3859},[3856,8260,8261],{"class":3862},"class",[3856,8263,8264],{"class":3881}," Dog",[3856,8266,3897],{"class":3870},[3856,8268,8269,8272],{"class":3858,"line":3900},[3856,8270,8271],{"class":3866},"  bark",[3856,8273,8274],{"class":3870},"() {\n",[3856,8276,8277,8279,8281,8283,8285,8288],{"class":3858,"line":3907},[3856,8278,4074],{"class":3874},[3856,8280,3925],{"class":3870},[3856,8282,3928],{"class":3866},[3856,8284,3871],{"class":3870},[3856,8286,8287],{"class":4060},"\"Woof!\"",[3856,8289,4896],{"class":3870},[3856,8291,8292],{"class":3858,"line":3913},[3856,8293,4141],{"class":3870},[3856,8295,8296],{"class":3858,"line":3919},[3856,8297,3961],{"class":3870},[3856,8299,8300],{"class":3858,"line":3946},[3856,8301,4153],{"emptyLinePlaceholder":4152},[3856,8303,8304,8306,8309],{"class":3858,"line":3952},[3856,8305,8261],{"class":3862},[3856,8307,8308],{"class":3881}," Cat",[3856,8310,3897],{"class":3870},[3856,8312,8313,8316],{"class":3858,"line":3958},[3856,8314,8315],{"class":3866},"  meow",[3856,8317,8274],{"class":3870},[3856,8319,8320,8322,8324,8326,8328,8331],{"class":3858,"line":4138},[3856,8321,4074],{"class":3874},[3856,8323,3925],{"class":3870},[3856,8325,3928],{"class":3866},[3856,8327,3871],{"class":3870},[3856,8329,8330],{"class":4060},"\"Meow!\"",[3856,8332,4896],{"class":3870},[3856,8334,8335],{"class":3858,"line":4144},[3856,8336,4141],{"class":3870},[3856,8338,8339],{"class":3858,"line":4149},[3856,8340,3961],{"class":3870},[3856,8342,8343],{"class":3858,"line":4156},[3856,8344,4153],{"emptyLinePlaceholder":4152},[3856,8346,8347,8349,8352,8354,8357,8359],{"class":3858,"line":4173},[3856,8348,6494],{"class":3862},[3856,8350,8351],{"class":3874}," pet1",[3856,8353,6507],{"class":3870},[3856,8355,8356],{"class":3862},"new",[3856,8358,8264],{"class":3866},[3856,8360,4849],{"class":3870},[3856,8362,8363,8365,8368,8370,8372,8374],{"class":3858,"line":4288},[3856,8364,6494],{"class":3862},[3856,8366,8367],{"class":3874}," pet2",[3856,8369,6507],{"class":3870},[3856,8371,8356],{"class":3862},[3856,8373,8308],{"class":3866},[3856,8375,4849],{"class":3870},[3856,8377,8378],{"class":3858,"line":4293},[3856,8379,4153],{"emptyLinePlaceholder":4152},[3856,8381,8382,8384,8386,8388,8390,8393,8396,8398,8400],{"class":3858,"line":4299},[3856,8383,4524],{"class":3874},[3856,8385,3925],{"class":3870},[3856,8387,3928],{"class":3866},[3856,8389,3871],{"class":3870},[3856,8391,8392],{"class":3874},"pet1",[3856,8394,8395],{"class":3862}," instanceof",[3856,8397,8264],{"class":3881},[3856,8399,4167],{"class":3870},[3856,8401,7470],{"class":3903},[3856,8403,8404,8406,8408,8410,8412,8414,8416,8418,8420],{"class":3858,"line":4304},[3856,8405,4524],{"class":3874},[3856,8407,3925],{"class":3870},[3856,8409,3928],{"class":3866},[3856,8411,3871],{"class":3870},[3856,8413,8392],{"class":3874},[3856,8415,8395],{"class":3862},[3856,8417,8308],{"class":3881},[3856,8419,4167],{"class":3870},[3856,8421,7492],{"class":3903},[3856,8423,8424,8426,8428,8430,8432,8435,8437,8439,8441],{"class":3858,"line":4310},[3856,8425,4524],{"class":3874},[3856,8427,3925],{"class":3870},[3856,8429,3928],{"class":3866},[3856,8431,3871],{"class":3870},[3856,8433,8434],{"class":3874},"pet2",[3856,8436,8395],{"class":3862},[3856,8438,8308],{"class":3881},[3856,8440,4167],{"class":3870},[3856,8442,7470],{"class":3903},[3856,8444,8445],{"class":3858,"line":4316},[3856,8446,4153],{"emptyLinePlaceholder":4152},[3856,8448,8449,8451,8453,8455,8458,8460,8463,8465],{"class":3858,"line":4322},[3856,8450,4524],{"class":3874},[3856,8452,3925],{"class":3870},[3856,8454,3928],{"class":3866},[3856,8456,8457],{"class":3870},"([] ",[3856,8459,3767],{"class":3862},[3856,8461,8462],{"class":3881}," Array",[3856,8464,5949],{"class":3870},[3856,8466,7470],{"class":3903},[3856,8468,8469,8471,8473,8475,8478,8480,8483,8485],{"class":3858,"line":4328},[3856,8470,4524],{"class":3874},[3856,8472,3925],{"class":3870},[3856,8474,3928],{"class":3866},[3856,8476,8477],{"class":3870},"({} ",[3856,8479,3767],{"class":3862},[3856,8481,8482],{"class":3881}," Object",[3856,8484,4167],{"class":3870},[3856,8486,7470],{"class":3903},[3856,8488,8489,8491,8493,8495,8497,8499,8502,8505,8507,8509,8511],{"class":3858,"line":4333},[3856,8490,4524],{"class":3874},[3856,8492,3925],{"class":3870},[3856,8494,3928],{"class":3866},[3856,8496,3871],{"class":3870},[3856,8498,8356],{"class":3862},[3856,8500,8501],{"class":3866}," Date",[3856,8503,8504],{"class":3870},"() ",[3856,8506,3767],{"class":3862},[3856,8508,8501],{"class":3881},[3856,8510,4167],{"class":3870},[3856,8512,7470],{"class":3903},[3838,8514,8516],{"id":8515},"instanceof-як-type-guard","Instanceof як type guard",[3843,8518,8519,8520,8522],{},"TypeScript використовує ",[3761,8521,3767],{}," для звуження типів до конкретного класу:",[3847,8524,8526],{"className":3849,"code":8525,"language":3851,"meta":3852,"style":3852},"class Dog {\n  bark(): void {\n    console.log(\"Woof!\");\n  }\n}\n\nclass Cat {\n  meow(): void {\n    console.log(\"Meow!\");\n  }\n}\n\nfunction makeSound(animal: Dog | Cat): void {\n  if (animal instanceof Dog) {\n    \u002F\u002F Тут animal: Dog\n    animal.bark();\n  } else {\n    \u002F\u002F Тут animal: Cat\n    animal.meow();\n  }\n}\n\nmakeSound(new Dog());  \u002F\u002F \"Woof!\"\nmakeSound(new Cat());  \u002F\u002F \"Meow!\"\n",[3761,8527,8528,8536,8547,8561,8565,8569,8573,8581,8591,8605,8609,8613,8617,8645,8659,8664,8676,8684,8689,8700,8704,8708,8712,8728],{"__ignoreMap":3852},[3856,8529,8530,8532,8534],{"class":3858,"line":3859},[3856,8531,8261],{"class":3862},[3856,8533,8264],{"class":3881},[3856,8535,3897],{"class":3870},[3856,8537,8538,8540,8543,8545],{"class":3858,"line":3900},[3856,8539,8271],{"class":3866},[3856,8541,8542],{"class":3870},"(): ",[3856,8544,3894],{"class":3881},[3856,8546,3897],{"class":3870},[3856,8548,8549,8551,8553,8555,8557,8559],{"class":3858,"line":3907},[3856,8550,4074],{"class":3874},[3856,8552,3925],{"class":3870},[3856,8554,3928],{"class":3866},[3856,8556,3871],{"class":3870},[3856,8558,8287],{"class":4060},[3856,8560,4896],{"class":3870},[3856,8562,8563],{"class":3858,"line":3913},[3856,8564,4141],{"class":3870},[3856,8566,8567],{"class":3858,"line":3919},[3856,8568,3961],{"class":3870},[3856,8570,8571],{"class":3858,"line":3946},[3856,8572,4153],{"emptyLinePlaceholder":4152},[3856,8574,8575,8577,8579],{"class":3858,"line":3952},[3856,8576,8261],{"class":3862},[3856,8578,8308],{"class":3881},[3856,8580,3897],{"class":3870},[3856,8582,8583,8585,8587,8589],{"class":3858,"line":3958},[3856,8584,8315],{"class":3866},[3856,8586,8542],{"class":3870},[3856,8588,3894],{"class":3881},[3856,8590,3897],{"class":3870},[3856,8592,8593,8595,8597,8599,8601,8603],{"class":3858,"line":4138},[3856,8594,4074],{"class":3874},[3856,8596,3925],{"class":3870},[3856,8598,3928],{"class":3866},[3856,8600,3871],{"class":3870},[3856,8602,8330],{"class":4060},[3856,8604,4896],{"class":3870},[3856,8606,8607],{"class":3858,"line":4144},[3856,8608,4141],{"class":3870},[3856,8610,8611],{"class":3858,"line":4149},[3856,8612,3961],{"class":3870},[3856,8614,8615],{"class":3858,"line":4156},[3856,8616,4153],{"emptyLinePlaceholder":4152},[3856,8618,8619,8621,8624,8626,8629,8631,8634,8636,8639,8641,8643],{"class":3858,"line":4173},[3856,8620,3863],{"class":3862},[3856,8622,8623],{"class":3866}," makeSound",[3856,8625,3871],{"class":3870},[3856,8627,8628],{"class":3874},"animal",[3856,8630,3878],{"class":3870},[3856,8632,8633],{"class":3881},"Dog",[3856,8635,3885],{"class":3870},[3856,8637,8638],{"class":3881},"Cat",[3856,8640,3891],{"class":3870},[3856,8642,3894],{"class":3881},[3856,8644,3897],{"class":3870},[3856,8646,8647,8649,8651,8653,8655,8657],{"class":3858,"line":4288},[3856,8648,4047],{"class":4046},[3856,8650,3981],{"class":3870},[3856,8652,8628],{"class":3874},[3856,8654,8395],{"class":3862},[3856,8656,8264],{"class":3881},[3856,8658,4064],{"class":3870},[3856,8660,8661],{"class":3858,"line":4293},[3856,8662,8663],{"class":3903},"    \u002F\u002F Тут animal: Dog\n",[3856,8665,8666,8669,8671,8674],{"class":3858,"line":4299},[3856,8667,8668],{"class":3874},"    animal",[3856,8670,3925],{"class":3870},[3856,8672,8673],{"class":3866},"bark",[3856,8675,4849],{"class":3870},[3856,8677,8678,8680,8682],{"class":3858,"line":4304},[3856,8679,4096],{"class":3870},[3856,8681,4099],{"class":4046},[3856,8683,3897],{"class":3870},[3856,8685,8686],{"class":3858,"line":4310},[3856,8687,8688],{"class":3903},"    \u002F\u002F Тут animal: Cat\n",[3856,8690,8691,8693,8695,8698],{"class":3858,"line":4316},[3856,8692,8668],{"class":3874},[3856,8694,3925],{"class":3870},[3856,8696,8697],{"class":3866},"meow",[3856,8699,4849],{"class":3870},[3856,8701,8702],{"class":3858,"line":4322},[3856,8703,4141],{"class":3870},[3856,8705,8706],{"class":3858,"line":4328},[3856,8707,3961],{"class":3870},[3856,8709,8710],{"class":3858,"line":4333},[3856,8711,4153],{"emptyLinePlaceholder":4152},[3856,8713,8714,8717,8719,8721,8723,8725],{"class":3858,"line":4338},[3856,8715,8716],{"class":3866},"makeSound",[3856,8718,3871],{"class":3870},[3856,8720,8356],{"class":3862},[3856,8722,8264],{"class":3866},[3856,8724,3940],{"class":3870},[3856,8726,8727],{"class":3903},"\u002F\u002F \"Woof!\"\n",[3856,8729,8730,8732,8734,8736,8738,8740],{"class":3858,"line":4343},[3856,8731,8716],{"class":3866},[3856,8733,3871],{"class":3870},[3856,8735,8356],{"class":3862},[3856,8737,8308],{"class":3866},[3856,8739,3940],{"class":3870},[3856,8741,8742],{"class":3903},"\u002F\u002F \"Meow!\"\n",[3843,8744,8745],{},[3793,8746,8747],{},"Приклад з вбудованими класами:",[3847,8749,8751],{"className":3849,"code":8750,"language":3851,"meta":3852,"style":3852},"function processValue(value: Date | string): string {\n  if (value instanceof Date) {\n    \u002F\u002F Тут value: Date\n    return value.toISOString();\n  } else {\n    \u002F\u002F Тут value: string\n    return value.toUpperCase();\n  }\n}\n\nconsole.log(processValue(new Date()));  \u002F\u002F \"2026-08-29T...\"\nconsole.log(processValue(\"hello\"));     \u002F\u002F \"HELLO\"\n",[3761,8752,8753,8778,8792,8797,8810,8818,8822,8834,8838,8842,8846,8870],{"__ignoreMap":3852},[3856,8754,8755,8757,8759,8761,8763,8765,8768,8770,8772,8774,8776],{"class":3858,"line":3859},[3856,8756,3863],{"class":3862},[3856,8758,3867],{"class":3866},[3856,8760,3871],{"class":3870},[3856,8762,3875],{"class":3874},[3856,8764,3878],{"class":3870},[3856,8766,8767],{"class":3881},"Date",[3856,8769,3885],{"class":3870},[3856,8771,3882],{"class":3881},[3856,8773,3891],{"class":3870},[3856,8775,3882],{"class":3881},[3856,8777,3897],{"class":3870},[3856,8779,8780,8782,8784,8786,8788,8790],{"class":3858,"line":3900},[3856,8781,4047],{"class":4046},[3856,8783,3981],{"class":3870},[3856,8785,3875],{"class":3874},[3856,8787,8395],{"class":3862},[3856,8789,8501],{"class":3881},[3856,8791,4064],{"class":3870},[3856,8793,8794],{"class":3858,"line":3907},[3856,8795,8796],{"class":3903},"    \u002F\u002F Тут value: Date\n",[3856,8798,8799,8801,8803,8805,8808],{"class":3858,"line":3913},[3856,8800,4840],{"class":4046},[3856,8802,4054],{"class":3874},[3856,8804,3925],{"class":3870},[3856,8806,8807],{"class":3866},"toISOString",[3856,8809,4849],{"class":3870},[3856,8811,8812,8814,8816],{"class":3858,"line":3919},[3856,8813,4096],{"class":3870},[3856,8815,4099],{"class":4046},[3856,8817,3897],{"class":3870},[3856,8819,8820],{"class":3858,"line":3946},[3856,8821,7104],{"class":3903},[3856,8823,8824,8826,8828,8830,8832],{"class":3858,"line":3952},[3856,8825,4840],{"class":4046},[3856,8827,4054],{"class":3874},[3856,8829,3925],{"class":3870},[3856,8831,3937],{"class":3866},[3856,8833,4849],{"class":3870},[3856,8835,8836],{"class":3858,"line":3958},[3856,8837,4141],{"class":3870},[3856,8839,8840],{"class":3858,"line":4138},[3856,8841,3961],{"class":3870},[3856,8843,8844],{"class":3858,"line":4144},[3856,8845,4153],{"emptyLinePlaceholder":4152},[3856,8847,8848,8850,8852,8854,8856,8858,8860,8862,8864,8867],{"class":3858,"line":4149},[3856,8849,4524],{"class":3874},[3856,8851,3925],{"class":3870},[3856,8853,3928],{"class":3866},[3856,8855,3871],{"class":3870},[3856,8857,4159],{"class":3866},[3856,8859,3871],{"class":3870},[3856,8861,8356],{"class":3862},[3856,8863,8501],{"class":3866},[3856,8865,8866],{"class":3870},"()));  ",[3856,8868,8869],{"class":3903},"\u002F\u002F \"2026-08-29T...\"\n",[3856,8871,8872,8874,8876,8878,8880,8882,8884,8886,8888],{"class":3858,"line":4156},[3856,8873,4524],{"class":3874},[3856,8875,3925],{"class":3870},[3856,8877,3928],{"class":3866},[3856,8879,3871],{"class":3870},[3856,8881,4159],{"class":3866},[3856,8883,3871],{"class":3870},[3856,8885,4164],{"class":4060},[3856,8887,4132],{"class":3870},[3856,8889,4962],{"class":3903},[3838,8891,8893],{"id":8892},"перевірка-на-масив-через-instanceof","Перевірка на масив через instanceof",[3843,8895,8896,8899],{},[3761,8897,8898],{},"instanceof Array"," коректно розрізняє масиви та об'єкти:",[3847,8901,8903],{"className":3849,"code":8902,"language":3851,"meta":3852,"style":3852},"function processData(data: unknown[]| { [key: string]: unknown }): void {\n  if (data instanceof Array) {\n    \u002F\u002F Тут data: unknown[]\n    console.log(`Array with ${data.length} elements`);\n  } else {\n    \u002F\u002F Тут data: { [key: string]: unknown }\n    console.log(`Object with keys: ${Object.keys(data).join(\", \")}`);\n  }\n}\n\nprocessData([1, 2, 3]);               \u002F\u002F \"Array with 3 elements\"\nprocessData({ a: 1, b: 2, c: 3 });    \u002F\u002F \"Object with keys: a, b, c\"\n",[3761,8904,8905,8943,8957,8962,8990,8998,9003,9049,9053,9057,9061,9086],{"__ignoreMap":3852},[3856,8906,8907,8909,8912,8914,8917,8919,8922,8925,8928,8930,8932,8935,8937,8939,8941],{"class":3858,"line":3859},[3856,8908,3863],{"class":3862},[3856,8910,8911],{"class":3866}," processData",[3856,8913,3871],{"class":3870},[3856,8915,8916],{"class":3874},"data",[3856,8918,3878],{"class":3870},[3856,8920,8921],{"class":3881},"unknown",[3856,8923,8924],{"class":3870},"[]| { [",[3856,8926,8927],{"class":3874},"key",[3856,8929,3878],{"class":3870},[3856,8931,3882],{"class":3881},[3856,8933,8934],{"class":3870},"]: ",[3856,8936,8921],{"class":3881},[3856,8938,7585],{"class":3870},[3856,8940,3894],{"class":3881},[3856,8942,3897],{"class":3870},[3856,8944,8945,8947,8949,8951,8953,8955],{"class":3858,"line":3900},[3856,8946,4047],{"class":4046},[3856,8948,3981],{"class":3870},[3856,8950,8916],{"class":3874},[3856,8952,8395],{"class":3862},[3856,8954,8462],{"class":3881},[3856,8956,4064],{"class":3870},[3856,8958,8959],{"class":3858,"line":3907},[3856,8960,8961],{"class":3903},"    \u002F\u002F Тут data: unknown[]\n",[3856,8963,8964,8966,8968,8970,8972,8975,8977,8979,8981,8983,8985,8988],{"class":3858,"line":3913},[3856,8965,4074],{"class":3874},[3856,8967,3925],{"class":3870},[3856,8969,3928],{"class":3866},[3856,8971,3871],{"class":3870},[3856,8973,8974],{"class":4060},"`Array with ",[3856,8976,5238],{"class":3862},[3856,8978,8916],{"class":3874},[3856,8980,3925],{"class":5243},[3856,8982,5246],{"class":3874},[3856,8984,5249],{"class":3862},[3856,8986,8987],{"class":4060}," elements`",[3856,8989,4896],{"class":3870},[3856,8991,8992,8994,8996],{"class":3858,"line":3919},[3856,8993,4096],{"class":3870},[3856,8995,4099],{"class":4046},[3856,8997,3897],{"class":3870},[3856,8999,9000],{"class":3858,"line":3946},[3856,9001,9002],{"class":3903},"    \u002F\u002F Тут data: { [key: string]: unknown }\n",[3856,9004,9005,9007,9009,9011,9013,9016,9018,9021,9023,9026,9028,9030,9033,9036,9038,9041,9043,9045,9047],{"class":3858,"line":3952},[3856,9006,4074],{"class":3874},[3856,9008,3925],{"class":3870},[3856,9010,3928],{"class":3866},[3856,9012,3871],{"class":3870},[3856,9014,9015],{"class":4060},"`Object with keys: ",[3856,9017,5238],{"class":3862},[3856,9019,9020],{"class":3874},"Object",[3856,9022,3925],{"class":5243},[3856,9024,9025],{"class":3866},"keys",[3856,9027,3871],{"class":5243},[3856,9029,8916],{"class":3874},[3856,9031,9032],{"class":5243},").",[3856,9034,9035],{"class":3866},"join",[3856,9037,3871],{"class":5243},[3856,9039,9040],{"class":4060},"\", \"",[3856,9042,5483],{"class":5243},[3856,9044,5249],{"class":3862},[3856,9046,5252],{"class":4060},[3856,9048,4896],{"class":3870},[3856,9050,9051],{"class":3858,"line":3958},[3856,9052,4141],{"class":3870},[3856,9054,9055],{"class":3858,"line":4138},[3856,9056,3961],{"class":3870},[3856,9058,9059],{"class":3858,"line":4144},[3856,9060,4153],{"emptyLinePlaceholder":4152},[3856,9062,9063,9066,9069,9071,9073,9075,9077,9080,9083],{"class":3858,"line":4149},[3856,9064,9065],{"class":3866},"processData",[3856,9067,9068],{"class":3870},"([",[3856,9070,5607],{"class":4128},[3856,9072,3764],{"class":3870},[3856,9074,4129],{"class":4128},[3856,9076,3764],{"class":3870},[3856,9078,9079],{"class":4128},"3",[3856,9081,9082],{"class":3870},"]);               ",[3856,9084,9085],{"class":3903},"\u002F\u002F \"Array with 3 elements\"\n",[3856,9087,9088,9090,9092,9095,9098,9100,9103,9106,9108,9111,9114,9117],{"class":3858,"line":4156},[3856,9089,9065],{"class":3866},[3856,9091,7700],{"class":3870},[3856,9093,9094],{"class":3874},"a:",[3856,9096,9097],{"class":4128}," 1",[3856,9099,3764],{"class":3870},[3856,9101,9102],{"class":3874},"b:",[3856,9104,9105],{"class":4128}," 2",[3856,9107,3764],{"class":3870},[3856,9109,9110],{"class":3874},"c:",[3856,9112,9113],{"class":4128}," 3",[3856,9115,9116],{"class":3870}," });    ",[3856,9118,9119],{"class":3903},"\u002F\u002F \"Object with keys: a, b, c\"\n",[3843,9121,9122],{},[3793,9123,9124,9125],{},"Альтернатива: ",[3761,9126,9127],{},"Array.isArray()",[3843,9129,9130,9131,9133],{},"Для перевірки на масив краще використовувати ",[3761,9132,9127],{},", бо він працює навіть з масивами з інших iframe\u002Fконтекстів:",[3847,9135,9137],{"className":3849,"code":9136,"language":3851,"meta":3852,"style":3852},"function processData(data: unknown[] | { [key: string]: unknown }): void {\n  if (Array.isArray(data)) {\n    \u002F\u002F Тут data: unknown[]\n    console.log(`Array with ${data.length} elements`);\n  } else {\n    \u002F\u002F Тут data: { [key: string]: unknown }\n    console.log(`Object with keys: ${Object.keys(data).join(\", \")}`);\n  }\n}\n",[3761,9138,9139,9172,9192,9196,9222,9230,9234,9274,9278],{"__ignoreMap":3852},[3856,9140,9141,9143,9145,9147,9149,9151,9153,9156,9158,9160,9162,9164,9166,9168,9170],{"class":3858,"line":3859},[3856,9142,3863],{"class":3862},[3856,9144,8911],{"class":3866},[3856,9146,3871],{"class":3870},[3856,9148,8916],{"class":3874},[3856,9150,3878],{"class":3870},[3856,9152,8921],{"class":3881},[3856,9154,9155],{"class":3870},"[] | { [",[3856,9157,8927],{"class":3874},[3856,9159,3878],{"class":3870},[3856,9161,3882],{"class":3881},[3856,9163,8934],{"class":3870},[3856,9165,8921],{"class":3881},[3856,9167,7585],{"class":3870},[3856,9169,3894],{"class":3881},[3856,9171,3897],{"class":3870},[3856,9173,9174,9176,9178,9181,9183,9186,9188,9190],{"class":3858,"line":3900},[3856,9175,4047],{"class":4046},[3856,9177,3981],{"class":3870},[3856,9179,9180],{"class":3874},"Array",[3856,9182,3925],{"class":3870},[3856,9184,9185],{"class":3866},"isArray",[3856,9187,3871],{"class":3870},[3856,9189,8916],{"class":3874},[3856,9191,6531],{"class":3870},[3856,9193,9194],{"class":3858,"line":3907},[3856,9195,8961],{"class":3903},[3856,9197,9198,9200,9202,9204,9206,9208,9210,9212,9214,9216,9218,9220],{"class":3858,"line":3913},[3856,9199,4074],{"class":3874},[3856,9201,3925],{"class":3870},[3856,9203,3928],{"class":3866},[3856,9205,3871],{"class":3870},[3856,9207,8974],{"class":4060},[3856,9209,5238],{"class":3862},[3856,9211,8916],{"class":3874},[3856,9213,3925],{"class":5243},[3856,9215,5246],{"class":3874},[3856,9217,5249],{"class":3862},[3856,9219,8987],{"class":4060},[3856,9221,4896],{"class":3870},[3856,9223,9224,9226,9228],{"class":3858,"line":3919},[3856,9225,4096],{"class":3870},[3856,9227,4099],{"class":4046},[3856,9229,3897],{"class":3870},[3856,9231,9232],{"class":3858,"line":3946},[3856,9233,9002],{"class":3903},[3856,9235,9236,9238,9240,9242,9244,9246,9248,9250,9252,9254,9256,9258,9260,9262,9264,9266,9268,9270,9272],{"class":3858,"line":3952},[3856,9237,4074],{"class":3874},[3856,9239,3925],{"class":3870},[3856,9241,3928],{"class":3866},[3856,9243,3871],{"class":3870},[3856,9245,9015],{"class":4060},[3856,9247,5238],{"class":3862},[3856,9249,9020],{"class":3874},[3856,9251,3925],{"class":5243},[3856,9253,9025],{"class":3866},[3856,9255,3871],{"class":5243},[3856,9257,8916],{"class":3874},[3856,9259,9032],{"class":5243},[3856,9261,9035],{"class":3866},[3856,9263,3871],{"class":5243},[3856,9265,9040],{"class":4060},[3856,9267,5483],{"class":5243},[3856,9269,5249],{"class":3862},[3856,9271,5252],{"class":4060},[3856,9273,4896],{"class":3870},[3856,9275,9276],{"class":3858,"line":3958},[3856,9277,4141],{"class":3870},[3856,9279,9280],{"class":3858,"line":4138},[3856,9281,3961],{"class":3870},[6259,9283,9284,9289,9303],{},[3843,9285,9286],{},[3793,9287,9288],{},"Array.isArray() vs instanceof Array:",[3746,9290,9291,9297],{},[3749,9292,9293,9296],{},[3761,9294,9295],{},"Array.isArray(value)"," — рекомендований спосіб, працює з масивами з інших контекстів.",[3749,9298,9299,9302],{},[3761,9300,9301],{},"value instanceof Array"," — може не спрацювати для масивів, створених в іншому iframe або window.",[3843,9304,9305,9306,9308],{},"У TypeScript обидва підходи звужують тип до масиву, але ",[3761,9307,9127],{}," більш надійний.",[3830,9310],{},[3833,9312,9314],{"id":9313},"discriminated-unions-розрізнені-union-типи","Discriminated Unions (розрізнені union типи)",[3838,9316,9318],{"id":9317},"проблема-складних-union-types","Проблема складних union types",[3843,9320,9321,9322,9324],{},"Коли union type складається з кількох об'єктних типів з різними властивостями, перевірки через ",[3761,9323,3770],{}," стають громіздкими:",[3847,9326,9328],{"className":3849,"code":9327,"language":3851,"meta":3852,"style":3852},"function processShape(\n  shape:\n    | { radius: number }\n    | { side: number }\n    | { width: number; height: number }\n): number {\n  if (\"radius\" in shape) {\n    return Math.PI * shape.radius ** 2;\n  } else if (\"side\" in shape) {\n    return shape.side ** 2;\n  } else {\n    return shape.width * shape.height;\n  }\n}\n",[3761,9329,9330,9339,9346,9360,9372,9394,9402,9416,9440,9459,9475,9483,9503,9507],{"__ignoreMap":3852},[3856,9331,9332,9334,9336],{"class":3858,"line":3859},[3856,9333,3863],{"class":3862},[3856,9335,7537],{"class":3866},[3856,9337,9338],{"class":3870},"(\n",[3856,9340,9341,9344],{"class":3858,"line":3900},[3856,9342,9343],{"class":3874},"  shape",[3856,9345,7200],{"class":3870},[3856,9347,9348,9351,9353,9355,9357],{"class":3858,"line":3907},[3856,9349,9350],{"class":3870},"    | { ",[3856,9352,7559],{"class":3874},[3856,9354,3878],{"class":3870},[3856,9356,3888],{"class":3881},[3856,9358,9359],{"class":3870}," }\n",[3856,9361,9362,9364,9366,9368,9370],{"class":3858,"line":3913},[3856,9363,9350],{"class":3870},[3856,9365,7578],{"class":3874},[3856,9367,3878],{"class":3870},[3856,9369,3888],{"class":3881},[3856,9371,9359],{"class":3870},[3856,9373,9374,9376,9379,9381,9383,9385,9388,9390,9392],{"class":3858,"line":3919},[3856,9375,9350],{"class":3870},[3856,9377,9378],{"class":3874},"width",[3856,9380,3878],{"class":3870},[3856,9382,3888],{"class":3881},[3856,9384,7556],{"class":3870},[3856,9386,9387],{"class":3874},"height",[3856,9389,3878],{"class":3870},[3856,9391,3888],{"class":3881},[3856,9393,9359],{"class":3870},[3856,9395,9396,9398,9400],{"class":3858,"line":3946},[3856,9397,3891],{"class":3870},[3856,9399,3888],{"class":3881},[3856,9401,3897],{"class":3870},[3856,9403,9404,9406,9408,9410,9412,9414],{"class":3858,"line":3952},[3856,9405,4047],{"class":4046},[3856,9407,3981],{"class":3870},[3856,9409,7598],{"class":4060},[3856,9411,7463],{"class":3862},[3856,9413,7603],{"class":3874},[3856,9415,4064],{"class":3870},[3856,9417,9418,9420,9422,9424,9426,9428,9430,9432,9434,9436,9438],{"class":3858,"line":3958},[3856,9419,4840],{"class":4046},[3856,9421,7622],{"class":3874},[3856,9423,3925],{"class":3870},[3856,9425,7627],{"class":7331},[3856,9427,7630],{"class":3870},[3856,9429,7542],{"class":3874},[3856,9431,3925],{"class":3870},[3856,9433,7559],{"class":3874},[3856,9435,7639],{"class":3870},[3856,9437,4129],{"class":4128},[3856,9439,4931],{"class":3870},[3856,9441,9442,9444,9446,9448,9450,9453,9455,9457],{"class":3858,"line":4138},[3856,9443,4096],{"class":3870},[3856,9445,4099],{"class":4046},[3856,9447,6827],{"class":4046},[3856,9449,3981],{"class":3870},[3856,9451,9452],{"class":4060},"\"side\"",[3856,9454,7463],{"class":3862},[3856,9456,7603],{"class":3874},[3856,9458,4064],{"class":3870},[3856,9460,9461,9463,9465,9467,9469,9471,9473],{"class":3858,"line":4144},[3856,9462,4840],{"class":4046},[3856,9464,7603],{"class":3874},[3856,9466,3925],{"class":3870},[3856,9468,7578],{"class":3874},[3856,9470,7639],{"class":3870},[3856,9472,4129],{"class":4128},[3856,9474,4931],{"class":3870},[3856,9476,9477,9479,9481],{"class":3858,"line":4149},[3856,9478,4096],{"class":3870},[3856,9480,4099],{"class":4046},[3856,9482,3897],{"class":3870},[3856,9484,9485,9487,9489,9491,9493,9495,9497,9499,9501],{"class":3858,"line":4156},[3856,9486,4840],{"class":4046},[3856,9488,7603],{"class":3874},[3856,9490,3925],{"class":3870},[3856,9492,9378],{"class":3874},[3856,9494,7630],{"class":3870},[3856,9496,7542],{"class":3874},[3856,9498,3925],{"class":3870},[3856,9500,9387],{"class":3874},[3856,9502,4931],{"class":3870},[3856,9504,9505],{"class":3858,"line":4173},[3856,9506,4141],{"class":3870},[3856,9508,9509],{"class":3858,"line":4288},[3856,9510,3961],{"class":3870},[3843,9512,9513],{},"Цей код працює, але:",[3746,9515,9516,9519,9525],{},[3749,9517,9518],{},"Важко читати та підтримувати",[3749,9520,9521,9522,5483],{},"Легко додати об'єкт з неоднозначними властивостями (наприклад, ",[3761,9523,9524],{},"{ radius: 5, side: 4 }",[3749,9526,9527],{},"Немає гарантії, що всі варіанти оброблені",[3838,9529,9531],{"id":9530},"що-таке-discriminated-union","Що таке Discriminated Union",[3843,9533,9534,3981,9537,9540,9541,3824,9544,9547,9548,9551,9552,9555],{},[3793,9535,9536],{},"Discriminated Union",[3753,9538,9539],{},"розрізнений union тип",", також відомий як ",[3753,9542,9543],{},"tagged union",[3753,9545,9546],{},"algebraic data type",") — це union type, де кожен варіант має ",[3793,9549,9550],{},"спільну властивість з унікальним літеральним значенням",", яка виступає ",[3793,9553,9554],{},"дискримінатором"," для розрізнення варіантів.",[3847,9557,9559],{"className":3849,"code":9558,"language":3851,"meta":3852,"style":3852},"\u002F\u002F Discriminated union з властивістю kind\ntype Circle = {\n  kind: \"circle\";     \u002F\u002F дискримінатор\n  radius: number;\n};\n\ntype Square = {\n  kind: \"square\";     \u002F\u002F дискримінатор\n  side: number;\n};\n\ntype Rectangle = {\n  kind: \"rectangle\";  \u002F\u002F дискримінатор\n  width: number;\n  height: number;\n};\n\ntype Shape = Circle | Square | Rectangle;\n",[3761,9560,9561,9566,9577,9592,9603,9608,9612,9621,9633,9644,9648,9652,9661,9674,9685,9696,9700,9704],{"__ignoreMap":3852},[3856,9562,9563],{"class":3858,"line":3859},[3856,9564,9565],{"class":3903},"\u002F\u002F Discriminated union з властивістю kind\n",[3856,9567,9568,9571,9574],{"class":3858,"line":3900},[3856,9569,9570],{"class":3862},"type",[3856,9572,9573],{"class":3881}," Circle",[3856,9575,9576],{"class":3870}," = {\n",[3856,9578,9579,9582,9584,9586,9589],{"class":3858,"line":3907},[3856,9580,9581],{"class":3874},"  kind",[3856,9583,3878],{"class":3870},[3856,9585,7553],{"class":4060},[3856,9587,9588],{"class":3870},";     ",[3856,9590,9591],{"class":3903},"\u002F\u002F дискримінатор\n",[3856,9593,9594,9597,9599,9601],{"class":3858,"line":3913},[3856,9595,9596],{"class":3874},"  radius",[3856,9598,3878],{"class":3870},[3856,9600,3888],{"class":3881},[3856,9602,4931],{"class":3870},[3856,9604,9605],{"class":3858,"line":3919},[3856,9606,9607],{"class":3870},"};\n",[3856,9609,9610],{"class":3858,"line":3946},[3856,9611,4153],{"emptyLinePlaceholder":4152},[3856,9613,9614,9616,9619],{"class":3858,"line":3952},[3856,9615,9570],{"class":3862},[3856,9617,9618],{"class":3881}," Square",[3856,9620,9576],{"class":3870},[3856,9622,9623,9625,9627,9629,9631],{"class":3858,"line":3958},[3856,9624,9581],{"class":3874},[3856,9626,3878],{"class":3870},[3856,9628,7573],{"class":4060},[3856,9630,9588],{"class":3870},[3856,9632,9591],{"class":3903},[3856,9634,9635,9638,9640,9642],{"class":3858,"line":4138},[3856,9636,9637],{"class":3874},"  side",[3856,9639,3878],{"class":3870},[3856,9641,3888],{"class":3881},[3856,9643,4931],{"class":3870},[3856,9645,9646],{"class":3858,"line":4144},[3856,9647,9607],{"class":3870},[3856,9649,9650],{"class":3858,"line":4149},[3856,9651,4153],{"emptyLinePlaceholder":4152},[3856,9653,9654,9656,9659],{"class":3858,"line":4156},[3856,9655,9570],{"class":3862},[3856,9657,9658],{"class":3881}," Rectangle",[3856,9660,9576],{"class":3870},[3856,9662,9663,9665,9667,9670,9672],{"class":3858,"line":4173},[3856,9664,9581],{"class":3874},[3856,9666,3878],{"class":3870},[3856,9668,9669],{"class":4060},"\"rectangle\"",[3856,9671,6478],{"class":3870},[3856,9673,9591],{"class":3903},[3856,9675,9676,9679,9681,9683],{"class":3858,"line":4288},[3856,9677,9678],{"class":3874},"  width",[3856,9680,3878],{"class":3870},[3856,9682,3888],{"class":3881},[3856,9684,4931],{"class":3870},[3856,9686,9687,9690,9692,9694],{"class":3858,"line":4293},[3856,9688,9689],{"class":3874},"  height",[3856,9691,3878],{"class":3870},[3856,9693,3888],{"class":3881},[3856,9695,4931],{"class":3870},[3856,9697,9698],{"class":3858,"line":4299},[3856,9699,9607],{"class":3870},[3856,9701,9702],{"class":3858,"line":4304},[3856,9703,4153],{"emptyLinePlaceholder":4152},[3856,9705,9706,9708,9711,9713,9716,9718,9721,9723,9726],{"class":3858,"line":4310},[3856,9707,9570],{"class":3862},[3856,9709,9710],{"class":3881}," Shape",[3856,9712,6507],{"class":3870},[3856,9714,9715],{"class":3881},"Circle",[3856,9717,3885],{"class":3870},[3856,9719,9720],{"class":3881},"Square",[3856,9722,3885],{"class":3870},[3856,9724,9725],{"class":3881},"Rectangle",[3856,9727,4931],{"class":3870},[3843,9729,9730,9731,9733,9734,3764,9736,3824,9738,9740,9741,9743,9744,9747],{},"Тепер кожен варіант має властивість ",[3761,9732,7548],{}," з унікальним значенням: ",[3761,9735,7553],{},[3761,9737,7573],{},[3761,9739,9669],{},". TypeScript може використовувати ",[3761,9742,7548],{}," для ",[3793,9745,9746],{},"точного"," звуження типу:",[3847,9749,9751],{"className":3849,"code":9750,"language":3851,"meta":3852,"style":3852},"function calculateArea(shape: Shape): number {\n  switch (shape.kind) {\n    case \"circle\":\n      \u002F\u002F Тут shape: Circle\n      return Math.PI * shape.radius ** 2;\n    \n    case \"square\":\n      \u002F\u002F Тут shape: Square\n      return shape.side ** 2;\n    \n    case \"rectangle\":\n      \u002F\u002F Тут shape: Rectangle\n      return shape.width * shape.height;\n    \n    default:\n      \u002F\u002F Exhaustiveness check\n      const exhaustiveCheck: never = shape;\n      throw new Error(`Unhandled shape: ${exhaustiveCheck}`);\n  }\n}\n\nconsole.log(calculateArea({ kind: \"circle\", radius: 5 }));        \u002F\u002F 78.54\nconsole.log(calculateArea({ kind: \"square\", side: 4 }));          \u002F\u002F 16\nconsole.log(calculateArea({ kind: \"rectangle\", width: 3, height: 5 }));  \u002F\u002F 15\n",[3761,9752,9753,9775,9789,9797,9802,9827,9831,9839,9844,9860,9864,9873,9878,9898,9902,9908,9913,9929,9952,9956,9960,9964,9994,10023],{"__ignoreMap":3852},[3856,9754,9755,9757,9760,9762,9764,9766,9769,9771,9773],{"class":3858,"line":3859},[3856,9756,3863],{"class":3862},[3856,9758,9759],{"class":3866}," calculateArea",[3856,9761,3871],{"class":3870},[3856,9763,7542],{"class":3874},[3856,9765,3878],{"class":3870},[3856,9767,9768],{"class":3881},"Shape",[3856,9770,3891],{"class":3870},[3856,9772,3888],{"class":3881},[3856,9774,3897],{"class":3870},[3856,9776,9777,9779,9781,9783,9785,9787],{"class":3858,"line":3900},[3856,9778,7183],{"class":4046},[3856,9780,3981],{"class":3870},[3856,9782,7542],{"class":3874},[3856,9784,3925],{"class":3870},[3856,9786,7548],{"class":3874},[3856,9788,4064],{"class":3870},[3856,9790,9791,9793,9795],{"class":3858,"line":3907},[3856,9792,7194],{"class":4046},[3856,9794,7706],{"class":4060},[3856,9796,7200],{"class":3870},[3856,9798,9799],{"class":3858,"line":3913},[3856,9800,9801],{"class":3903},"      \u002F\u002F Тут shape: Circle\n",[3856,9803,9804,9807,9809,9811,9813,9815,9817,9819,9821,9823,9825],{"class":3858,"line":3919},[3856,9805,9806],{"class":4046},"      return",[3856,9808,7622],{"class":3874},[3856,9810,3925],{"class":3870},[3856,9812,7627],{"class":7331},[3856,9814,7630],{"class":3870},[3856,9816,7542],{"class":3874},[3856,9818,3925],{"class":3870},[3856,9820,7559],{"class":3874},[3856,9822,7639],{"class":3870},[3856,9824,4129],{"class":4128},[3856,9826,4931],{"class":3870},[3856,9828,9829],{"class":3858,"line":3946},[3856,9830,7233],{"class":3870},[3856,9832,9833,9835,9837],{"class":3858,"line":3952},[3856,9834,7194],{"class":4046},[3856,9836,7739],{"class":4060},[3856,9838,7200],{"class":3870},[3856,9840,9841],{"class":3858,"line":3958},[3856,9842,9843],{"class":3903},"      \u002F\u002F Тут shape: Square\n",[3856,9845,9846,9848,9850,9852,9854,9856,9858],{"class":3858,"line":4138},[3856,9847,9806],{"class":4046},[3856,9849,7603],{"class":3874},[3856,9851,3925],{"class":3870},[3856,9853,7578],{"class":3874},[3856,9855,7639],{"class":3870},[3856,9857,4129],{"class":4128},[3856,9859,4931],{"class":3870},[3856,9861,9862],{"class":3858,"line":4144},[3856,9863,7233],{"class":3870},[3856,9865,9866,9868,9871],{"class":3858,"line":4149},[3856,9867,7194],{"class":4046},[3856,9869,9870],{"class":4060}," \"rectangle\"",[3856,9872,7200],{"class":3870},[3856,9874,9875],{"class":3858,"line":4156},[3856,9876,9877],{"class":3903},"      \u002F\u002F Тут shape: Rectangle\n",[3856,9879,9880,9882,9884,9886,9888,9890,9892,9894,9896],{"class":3858,"line":4173},[3856,9881,9806],{"class":4046},[3856,9883,7603],{"class":3874},[3856,9885,3925],{"class":3870},[3856,9887,9378],{"class":3874},[3856,9889,7630],{"class":3870},[3856,9891,7542],{"class":3874},[3856,9893,3925],{"class":3870},[3856,9895,9387],{"class":3874},[3856,9897,4931],{"class":3870},[3856,9899,9900],{"class":3858,"line":4288},[3856,9901,7233],{"class":3870},[3856,9903,9904,9906],{"class":3858,"line":4293},[3856,9905,7316],{"class":4046},[3856,9907,7200],{"class":3870},[3856,9909,9910],{"class":3858,"line":4299},[3856,9911,9912],{"class":3903},"      \u002F\u002F Exhaustiveness check\n",[3856,9914,9915,9917,9919,9921,9923,9925,9927],{"class":3858,"line":4304},[3856,9916,7328],{"class":3862},[3856,9918,7332],{"class":7331},[3856,9920,3878],{"class":3870},[3856,9922,7337],{"class":3881},[3856,9924,6507],{"class":3870},[3856,9926,7542],{"class":3874},[3856,9928,4931],{"class":3870},[3856,9930,9931,9933,9935,9937,9939,9942,9944,9946,9948,9950],{"class":3858,"line":4310},[3856,9932,7348],{"class":4046},[3856,9934,7351],{"class":3862},[3856,9936,7354],{"class":3866},[3856,9938,3871],{"class":3870},[3856,9940,9941],{"class":4060},"`Unhandled shape: ",[3856,9943,5238],{"class":3862},[3856,9945,7364],{"class":3874},[3856,9947,5249],{"class":3862},[3856,9949,5252],{"class":4060},[3856,9951,4896],{"class":3870},[3856,9953,9954],{"class":3858,"line":4316},[3856,9955,4141],{"class":3870},[3856,9957,9958],{"class":3858,"line":4322},[3856,9959,3961],{"class":3870},[3856,9961,9962],{"class":3858,"line":4328},[3856,9963,4153],{"emptyLinePlaceholder":4152},[3856,9965,9966,9968,9970,9972,9974,9977,9979,9981,9983,9985,9987,9989,9992],{"class":3858,"line":4333},[3856,9967,4524],{"class":3874},[3856,9969,3925],{"class":3870},[3856,9971,3928],{"class":3866},[3856,9973,3871],{"class":3870},[3856,9975,9976],{"class":3866},"calculateArea",[3856,9978,7700],{"class":3870},[3856,9980,7703],{"class":3874},[3856,9982,7706],{"class":4060},[3856,9984,3764],{"class":3870},[3856,9986,7711],{"class":3874},[3856,9988,7714],{"class":4128},[3856,9990,9991],{"class":3870}," }));        ",[3856,9993,7720],{"class":3903},[3856,9995,9996,9998,10000,10002,10004,10006,10008,10010,10012,10014,10016,10018,10021],{"class":3858,"line":4338},[3856,9997,4524],{"class":3874},[3856,9999,3925],{"class":3870},[3856,10001,3928],{"class":3866},[3856,10003,3871],{"class":3870},[3856,10005,9976],{"class":3866},[3856,10007,7700],{"class":3870},[3856,10009,7703],{"class":3874},[3856,10011,7739],{"class":4060},[3856,10013,3764],{"class":3870},[3856,10015,7744],{"class":3874},[3856,10017,7747],{"class":4128},[3856,10019,10020],{"class":3870}," }));          ",[3856,10022,7753],{"class":3903},[3856,10024,10025,10027,10029,10031,10033,10035,10037,10039,10041,10043,10046,10048,10050,10053,10055,10057],{"class":3858,"line":4343},[3856,10026,4524],{"class":3874},[3856,10028,3925],{"class":3870},[3856,10030,3928],{"class":3866},[3856,10032,3871],{"class":3870},[3856,10034,9976],{"class":3866},[3856,10036,7700],{"class":3870},[3856,10038,7703],{"class":3874},[3856,10040,9870],{"class":4060},[3856,10042,3764],{"class":3870},[3856,10044,10045],{"class":3874},"width:",[3856,10047,9113],{"class":4128},[3856,10049,3764],{"class":3870},[3856,10051,10052],{"class":3874},"height:",[3856,10054,7714],{"class":4128},[3856,10056,7717],{"class":3870},[3856,10058,10059],{"class":3903},"\u002F\u002F 15\n",[4214,10061,10063],{"alt":10062},"Discriminated Union з дискримінатором kind",[3847,10064,10066],{"className":4219,"code":10065,"language":4221,"meta":3852,"style":3852},"@startuml\nskinparam style plain\nskinparam backgroundColor #FFFFFF\n\nrectangle \"Shape Union Type\" as Union #FCA5A5 {\n    note bottom\n    Shape = Circle | Square | Rectangle\n    end note\n}\n\nrectangle \"Circle\" as Circle #86EFAC {\n    note bottom\n    kind: \"circle\"\n    radius: number\n    end note\n}\n\nrectangle \"Square\" as Square #93C5FD {\n    note bottom\n    kind: \"square\"\n    side: number\n    end note\n}\n\nrectangle \"Rectangle\" as Rectangle #FCD34D {\n    note bottom\n    kind: \"rectangle\"\n    width: number\n    height: number\n    end note\n}\n\nUnion -down-> Circle : shape.kind === \"circle\"\nUnion -down-> Square : shape.kind === \"square\"\nUnion -down-> Rectangle : shape.kind === \"rectangle\"\n\nnote right of Union\n  Властивість kind —\n  це дискримінатор,\n  що дозволяє TypeScript\n  точно визначити варіант\nend note\n@enduml\n",[3761,10067,10068,10072,10076,10080,10084,10089,10093,10098,10102,10106,10110,10115,10119,10124,10129,10133,10137,10141,10146,10150,10155,10160,10164,10168,10172,10177,10181,10186,10191,10196,10200,10204,10208,10213,10218,10223,10227,10232,10237,10242,10247,10252,10257],{"__ignoreMap":3852},[3856,10069,10070],{"class":3858,"line":3859},[3856,10071,4228],{},[3856,10073,10074],{"class":3858,"line":3900},[3856,10075,4233],{},[3856,10077,10078],{"class":3858,"line":3907},[3856,10079,4238],{},[3856,10081,10082],{"class":3858,"line":3913},[3856,10083,4153],{"emptyLinePlaceholder":4152},[3856,10085,10086],{"class":3858,"line":3919},[3856,10087,10088],{},"rectangle \"Shape Union Type\" as Union #FCA5A5 {\n",[3856,10090,10091],{"class":3858,"line":3946},[3856,10092,4252],{},[3856,10094,10095],{"class":3858,"line":3952},[3856,10096,10097],{},"    Shape = Circle | Square | Rectangle\n",[3856,10099,10100],{"class":3858,"line":3958},[3856,10101,4272],{},[3856,10103,10104],{"class":3858,"line":4138},[3856,10105,3961],{},[3856,10107,10108],{"class":3858,"line":4144},[3856,10109,4153],{"emptyLinePlaceholder":4152},[3856,10111,10112],{"class":3858,"line":4149},[3856,10113,10114],{},"rectangle \"Circle\" as Circle #86EFAC {\n",[3856,10116,10117],{"class":3858,"line":4156},[3856,10118,4252],{},[3856,10120,10121],{"class":3858,"line":4173},[3856,10122,10123],{},"    kind: \"circle\"\n",[3856,10125,10126],{"class":3858,"line":4288},[3856,10127,10128],{},"    radius: number\n",[3856,10130,10131],{"class":3858,"line":4293},[3856,10132,4272],{},[3856,10134,10135],{"class":3858,"line":4299},[3856,10136,3961],{},[3856,10138,10139],{"class":3858,"line":4304},[3856,10140,4153],{"emptyLinePlaceholder":4152},[3856,10142,10143],{"class":3858,"line":4310},[3856,10144,10145],{},"rectangle \"Square\" as Square #93C5FD {\n",[3856,10147,10148],{"class":3858,"line":4316},[3856,10149,4252],{},[3856,10151,10152],{"class":3858,"line":4322},[3856,10153,10154],{},"    kind: \"square\"\n",[3856,10156,10157],{"class":3858,"line":4328},[3856,10158,10159],{},"    side: number\n",[3856,10161,10162],{"class":3858,"line":4333},[3856,10163,4272],{},[3856,10165,10166],{"class":3858,"line":4338},[3856,10167,3961],{},[3856,10169,10170],{"class":3858,"line":4343},[3856,10171,4153],{"emptyLinePlaceholder":4152},[3856,10173,10174],{"class":3858,"line":4349},[3856,10175,10176],{},"rectangle \"Rectangle\" as Rectangle #FCD34D {\n",[3856,10178,10179],{"class":3858,"line":4354},[3856,10180,4252],{},[3856,10182,10183],{"class":3858,"line":4360},[3856,10184,10185],{},"    kind: \"rectangle\"\n",[3856,10187,10188],{"class":3858,"line":4366},[3856,10189,10190],{},"    width: number\n",[3856,10192,10193],{"class":3858,"line":4372},[3856,10194,10195],{},"    height: number\n",[3856,10197,10198],{"class":3858,"line":4378},[3856,10199,4272],{},[3856,10201,10202],{"class":3858,"line":4383},[3856,10203,3961],{},[3856,10205,10206],{"class":3858,"line":4388},[3856,10207,4153],{"emptyLinePlaceholder":4152},[3856,10209,10210],{"class":3858,"line":4393},[3856,10211,10212],{},"Union -down-> Circle : shape.kind === \"circle\"\n",[3856,10214,10215],{"class":3858,"line":4399},[3856,10216,10217],{},"Union -down-> Square : shape.kind === \"square\"\n",[3856,10219,10220],{"class":3858,"line":4405},[3856,10221,10222],{},"Union -down-> Rectangle : shape.kind === \"rectangle\"\n",[3856,10224,10225],{"class":3858,"line":4411},[3856,10226,4153],{"emptyLinePlaceholder":4152},[3856,10228,10229],{"class":3858,"line":4416},[3856,10230,10231],{},"note right of Union\n",[3856,10233,10234],{"class":3858,"line":4422},[3856,10235,10236],{},"  Властивість kind —\n",[3856,10238,10239],{"class":3858,"line":4428},[3856,10240,10241],{},"  це дискримінатор,\n",[3856,10243,10244],{"class":3858,"line":4434},[3856,10245,10246],{},"  що дозволяє TypeScript\n",[3856,10248,10249],{"class":3858,"line":4440},[3856,10250,10251],{},"  точно визначити варіант\n",[3856,10253,10255],{"class":3858,"line":10254},42,[3856,10256,4437],{},[3856,10258,10260],{"class":3858,"line":10259},43,[3856,10261,4443],{},[3838,10263,10265],{"id":10264},"переваги-discriminated-unions","Переваги Discriminated Unions",[4456,10267,10268,10276,10282,10288],{},[3749,10269,10270,10273,10274,3925],{},[3793,10271,10272],{},"Чіткість:"," Код легко читати — одна перевірка дискримінатора замість кількох перевірок через ",[3761,10275,3770],{},[3749,10277,10278,10281],{},[3793,10279,10280],{},"Безпека:"," TypeScript гарантує, що ви обробили всі варіанти (через exhaustiveness check).",[3749,10283,10284,10287],{},[3793,10285,10286],{},"Автодоповнення:"," IDE підказує доступні властивості після звуження типу.",[3749,10289,10290,10293,10294,10296,10297,10299,10300,9032],{},[3793,10291,10292],{},"Неможливість неоднозначності:"," Не можна створити об'єкт, що одночасно є ",[3761,10295,9715],{}," і ",[3761,10298,9720],{}," (різні значення ",[3761,10301,7548],{},[3838,10303,10305],{"id":10304},"практичний-приклад-result-type","Практичний приклад: Result type",[3843,10307,10308],{},"Discriminated unions ідеально підходять для моделювання результатів операцій, що можуть завершитися успіхом або помилкою:",[3847,10310,10312],{"className":3849,"code":10311,"language":3851,"meta":3852,"style":3852},"type Success = {\n  status: \"success\";\n  data: string;\n};\n\ntype Error = {\n  status: \"error\";\n  errorMessage: string;\n};\n\ntype Result = Success | Error;\n\nfunction parseJSON(json: string): Result {\n  try {\n    let data = JSON.parse(json);\n    return { status: \"success\", data: data };\n  } catch (error) {\n    return { status: \"error\", errorMessage: String(error) };\n  }\n}\n\nfunction handleResult(result: Result): void {\n  if (result.status === \"success\") {\n    \u002F\u002F Тут result: Success\n    console.log(`Data: ${result.data}`);\n  } else {\n    \u002F\u002F Тут result: Error\n    console.error(`Error: ${result.errorMessage}`);\n  }\n}\n\nlet result1 = parseJSON('{\"name\": \"Alice\"}');\nhandleResult(result1);  \u002F\u002F \"Data: [object Object]\"\n\nlet result2 = parseJSON('invalid json');\nhandleResult(result2);  \u002F\u002F \"Error: SyntaxError: Unexpected token i in JSON at position 0\"\n",[3761,10313,10314,10323,10334,10345,10349,10353,10361,10371,10382,10386,10390,10409,10413,10436,10443,10467,10489,10503,10529,10533,10537,10541,10563,10581,10586,10613,10621,10626,10654,10658,10662,10666,10685,10700,10704,10722],{"__ignoreMap":3852},[3856,10315,10316,10318,10321],{"class":3858,"line":3859},[3856,10317,9570],{"class":3862},[3856,10319,10320],{"class":3881}," Success",[3856,10322,9576],{"class":3870},[3856,10324,10325,10328,10330,10332],{"class":3858,"line":3900},[3856,10326,10327],{"class":3874},"  status",[3856,10329,3878],{"class":3870},[3856,10331,6768],{"class":4060},[3856,10333,4931],{"class":3870},[3856,10335,10336,10339,10341,10343],{"class":3858,"line":3907},[3856,10337,10338],{"class":3874},"  data",[3856,10340,3878],{"class":3870},[3856,10342,3882],{"class":3881},[3856,10344,4931],{"class":3870},[3856,10346,10347],{"class":3858,"line":3913},[3856,10348,9607],{"class":3870},[3856,10350,10351],{"class":3858,"line":3919},[3856,10352,4153],{"emptyLinePlaceholder":4152},[3856,10354,10355,10357,10359],{"class":3858,"line":3946},[3856,10356,9570],{"class":3862},[3856,10358,7354],{"class":3881},[3856,10360,9576],{"class":3870},[3856,10362,10363,10365,10367,10369],{"class":3858,"line":3952},[3856,10364,10327],{"class":3874},[3856,10366,3878],{"class":3870},[3856,10368,6773],{"class":4060},[3856,10370,4931],{"class":3870},[3856,10372,10373,10376,10378,10380],{"class":3858,"line":3958},[3856,10374,10375],{"class":3874},"  errorMessage",[3856,10377,3878],{"class":3870},[3856,10379,3882],{"class":3881},[3856,10381,4931],{"class":3870},[3856,10383,10384],{"class":3858,"line":4138},[3856,10385,9607],{"class":3870},[3856,10387,10388],{"class":3858,"line":4144},[3856,10389,4153],{"emptyLinePlaceholder":4152},[3856,10391,10392,10394,10397,10399,10402,10404,10407],{"class":3858,"line":4149},[3856,10393,9570],{"class":3862},[3856,10395,10396],{"class":3881}," Result",[3856,10398,6507],{"class":3870},[3856,10400,10401],{"class":3881},"Success",[3856,10403,3885],{"class":3870},[3856,10405,10406],{"class":3881},"Error",[3856,10408,4931],{"class":3870},[3856,10410,10411],{"class":3858,"line":4156},[3856,10412,4153],{"emptyLinePlaceholder":4152},[3856,10414,10415,10417,10420,10422,10425,10427,10429,10431,10434],{"class":3858,"line":4173},[3856,10416,3863],{"class":3862},[3856,10418,10419],{"class":3866}," parseJSON",[3856,10421,3871],{"class":3870},[3856,10423,10424],{"class":3874},"json",[3856,10426,3878],{"class":3870},[3856,10428,3882],{"class":3881},[3856,10430,3891],{"class":3870},[3856,10432,10433],{"class":3881},"Result",[3856,10435,3897],{"class":3870},[3856,10437,10438,10441],{"class":3858,"line":4288},[3856,10439,10440],{"class":4046},"  try",[3856,10442,3897],{"class":3870},[3856,10444,10445,10448,10451,10453,10456,10458,10461,10463,10465],{"class":3858,"line":4293},[3856,10446,10447],{"class":3862},"    let",[3856,10449,10450],{"class":3874}," data",[3856,10452,6507],{"class":3870},[3856,10454,10455],{"class":7331},"JSON",[3856,10457,3925],{"class":3870},[3856,10459,10460],{"class":3866},"parse",[3856,10462,3871],{"class":3870},[3856,10464,10424],{"class":3874},[3856,10466,4896],{"class":3870},[3856,10468,10469,10471,10474,10477,10480,10482,10485,10487],{"class":3858,"line":4299},[3856,10470,4840],{"class":4046},[3856,10472,10473],{"class":3870}," { ",[3856,10475,10476],{"class":3874},"status:",[3856,10478,10479],{"class":4060}," \"success\"",[3856,10481,3764],{"class":3870},[3856,10483,10484],{"class":3874},"data:",[3856,10486,10450],{"class":3874},[3856,10488,7443],{"class":3870},[3856,10490,10491,10493,10496,10498,10501],{"class":3858,"line":4304},[3856,10492,4096],{"class":3870},[3856,10494,10495],{"class":4046},"catch",[3856,10497,3981],{"class":3870},[3856,10499,10500],{"class":3874},"error",[3856,10502,4064],{"class":3870},[3856,10504,10505,10507,10509,10511,10514,10516,10519,10522,10524,10526],{"class":3858,"line":4310},[3856,10506,4840],{"class":4046},[3856,10508,10473],{"class":3870},[3856,10510,10476],{"class":3874},[3856,10512,10513],{"class":4060}," \"error\"",[3856,10515,3764],{"class":3870},[3856,10517,10518],{"class":3874},"errorMessage:",[3856,10520,10521],{"class":3866}," String",[3856,10523,3871],{"class":3870},[3856,10525,10500],{"class":3874},[3856,10527,10528],{"class":3870},") };\n",[3856,10530,10531],{"class":3858,"line":4316},[3856,10532,4141],{"class":3870},[3856,10534,10535],{"class":3858,"line":4322},[3856,10536,3961],{"class":3870},[3856,10538,10539],{"class":3858,"line":4328},[3856,10540,4153],{"emptyLinePlaceholder":4152},[3856,10542,10543,10545,10548,10550,10553,10555,10557,10559,10561],{"class":3858,"line":4333},[3856,10544,3863],{"class":3862},[3856,10546,10547],{"class":3866}," handleResult",[3856,10549,3871],{"class":3870},[3856,10551,10552],{"class":3874},"result",[3856,10554,3878],{"class":3870},[3856,10556,10433],{"class":3881},[3856,10558,3891],{"class":3870},[3856,10560,3894],{"class":3881},[3856,10562,3897],{"class":3870},[3856,10564,10565,10567,10569,10571,10573,10575,10577,10579],{"class":3858,"line":4338},[3856,10566,4047],{"class":4046},[3856,10568,3981],{"class":3870},[3856,10570,10552],{"class":3874},[3856,10572,3925],{"class":3870},[3856,10574,6763],{"class":3874},[3856,10576,4057],{"class":3870},[3856,10578,6768],{"class":4060},[3856,10580,4064],{"class":3870},[3856,10582,10583],{"class":3858,"line":4343},[3856,10584,10585],{"class":3903},"    \u002F\u002F Тут result: Success\n",[3856,10587,10588,10590,10592,10594,10596,10599,10601,10603,10605,10607,10609,10611],{"class":3858,"line":4349},[3856,10589,4074],{"class":3874},[3856,10591,3925],{"class":3870},[3856,10593,3928],{"class":3866},[3856,10595,3871],{"class":3870},[3856,10597,10598],{"class":4060},"`Data: ",[3856,10600,5238],{"class":3862},[3856,10602,10552],{"class":3874},[3856,10604,3925],{"class":5243},[3856,10606,8916],{"class":3874},[3856,10608,5249],{"class":3862},[3856,10610,5252],{"class":4060},[3856,10612,4896],{"class":3870},[3856,10614,10615,10617,10619],{"class":3858,"line":4354},[3856,10616,4096],{"class":3870},[3856,10618,4099],{"class":4046},[3856,10620,3897],{"class":3870},[3856,10622,10623],{"class":3858,"line":4360},[3856,10624,10625],{"class":3903},"    \u002F\u002F Тут result: Error\n",[3856,10627,10628,10630,10632,10634,10636,10639,10641,10643,10645,10648,10650,10652],{"class":3858,"line":4366},[3856,10629,4074],{"class":3874},[3856,10631,3925],{"class":3870},[3856,10633,10500],{"class":3866},[3856,10635,3871],{"class":3870},[3856,10637,10638],{"class":4060},"`Error: ",[3856,10640,5238],{"class":3862},[3856,10642,10552],{"class":3874},[3856,10644,3925],{"class":5243},[3856,10646,10647],{"class":3874},"errorMessage",[3856,10649,5249],{"class":3862},[3856,10651,5252],{"class":4060},[3856,10653,4896],{"class":3870},[3856,10655,10656],{"class":3858,"line":4372},[3856,10657,4141],{"class":3870},[3856,10659,10660],{"class":3858,"line":4378},[3856,10661,3961],{"class":3870},[3856,10663,10664],{"class":3858,"line":4383},[3856,10665,4153],{"emptyLinePlaceholder":4152},[3856,10667,10668,10670,10673,10675,10678,10680,10683],{"class":3858,"line":4388},[3856,10669,6494],{"class":3862},[3856,10671,10672],{"class":3874}," result1",[3856,10674,6507],{"class":3870},[3856,10676,10677],{"class":3866},"parseJSON",[3856,10679,3871],{"class":3870},[3856,10681,10682],{"class":4060},"'{\"name\": \"Alice\"}'",[3856,10684,4896],{"class":3870},[3856,10686,10687,10690,10692,10695,10697],{"class":3858,"line":4393},[3856,10688,10689],{"class":3866},"handleResult",[3856,10691,3871],{"class":3870},[3856,10693,10694],{"class":3874},"result1",[3856,10696,4167],{"class":3870},[3856,10698,10699],{"class":3903},"\u002F\u002F \"Data: [object Object]\"\n",[3856,10701,10702],{"class":3858,"line":4399},[3856,10703,4153],{"emptyLinePlaceholder":4152},[3856,10705,10706,10708,10711,10713,10715,10717,10720],{"class":3858,"line":4405},[3856,10707,6494],{"class":3862},[3856,10709,10710],{"class":3874}," result2",[3856,10712,6507],{"class":3870},[3856,10714,10677],{"class":3866},[3856,10716,3871],{"class":3870},[3856,10718,10719],{"class":4060},"'invalid json'",[3856,10721,4896],{"class":3870},[3856,10723,10724,10726,10728,10731,10733],{"class":3858,"line":4411},[3856,10725,10689],{"class":3866},[3856,10727,3871],{"class":3870},[3856,10729,10730],{"class":3874},"result2",[3856,10732,4167],{"class":3870},[3856,10734,10735],{"class":3903},"\u002F\u002F \"Error: SyntaxError: Unexpected token i in JSON at position 0\"\n",[3838,10737,10739],{"id":10738},"вибір-імені-для-дискримінатора","Вибір імені для дискримінатора",[3843,10741,10742],{},"Найчастіше використовують імена:",[3746,10744,10745,10750,10755,10760],{},[3749,10746,10747,10749],{},[3761,10748,7548],{}," — для типів сутностей (shape, animal, vehicle)",[3749,10751,10752,10754],{},[3761,10753,9570],{}," — для типів повідомлень або подій (event, action)",[3749,10756,10757,10759],{},[3761,10758,6763],{}," — для станів (success\u002Ferror, pending\u002Ffulfilled\u002Frejected)",[3749,10761,10762,10765],{},[3761,10763,10764],{},"tag"," — загальна назва для будь-яких варіантів",[3843,10767,10768],{},"Вибирайте ім'я, що найкраще відображає суть вашого union type.",[6259,10770,10771,10772,5786,10775,10778],{},"Discriminated unions — це ",[3793,10773,10774],{},"найпотужніший",[3793,10776,10777],{},"найбезпечніший"," спосіб моделювання варіативних даних у TypeScript. Використовуйте їх завжди, коли маєте union type з кількох об'єктних типів.",[3830,10780],{},[3833,10782,10784],{"id":10783},"custom-type-guards-власні-функції-guards","Custom Type Guards (власні функції-guards)",[3838,10786,10788],{"id":10787},"проблема-складних-перевірок","Проблема складних перевірок",[3843,10790,10791,10792,3764,10794,3764,10796,10798],{},"Іноді вбудованих type guards (",[3761,10793,3763],{},[3761,10795,3767],{},[3761,10797,3770],{},") недостатньо для складних перевірок:",[3847,10800,10802],{"className":3849,"code":10801,"language":3851,"meta":3852,"style":3852},"function isValidEmail(value: string): boolean {\n  return \u002F^[\\w.-]+@[\\w.-]+\\.\\w+$\u002F.test(value);\n}\n\nfunction processInput(input: string): void {\n  if (isValidEmail(input)) {\n    \u002F\u002F TypeScript НЕ знає, що тут input — це валідний email\n    \u002F\u002F input все ще має тип string\n    sendEmail(input);  \u002F\u002F TypeScript не може перевірити коректність\n  }\n}\n",[3761,10803,10804,10825,10887,10891,10895,10917,10932,10937,10942,10956,10960],{"__ignoreMap":3852},[3856,10805,10806,10808,10811,10813,10815,10817,10819,10821,10823],{"class":3858,"line":3859},[3856,10807,3863],{"class":3862},[3856,10809,10810],{"class":3866}," isValidEmail",[3856,10812,3871],{"class":3870},[3856,10814,3875],{"class":3874},[3856,10816,3878],{"class":3870},[3856,10818,3882],{"class":3881},[3856,10820,3891],{"class":3870},[3856,10822,4808],{"class":3881},[3856,10824,3897],{"class":3870},[3856,10826,10827,10829,10833,10837,10841,10844,10847,10851,10854,10856,10858,10860,10862,10866,10869,10871,10874,10876,10878,10881,10883,10885],{"class":3858,"line":3900},[3856,10828,4914],{"class":4046},[3856,10830,10832],{"class":10831},"shsrj"," \u002F",[3856,10834,10836],{"class":10835},"siofk","^",[3856,10838,10840],{"class":10839},"sAV2Q","[",[3856,10842,10843],{"class":10831},"\\w.-",[3856,10845,10846],{"class":10839},"]",[3856,10848,10850],{"class":10849},"sYsli","+",[3856,10852,10853],{"class":10831},"@",[3856,10855,10840],{"class":10839},[3856,10857,10843],{"class":10831},[3856,10859,10846],{"class":10839},[3856,10861,10850],{"class":10849},[3856,10863,10865],{"class":10864},"sjcCO","\\.",[3856,10867,10868],{"class":10831},"\\w",[3856,10870,10850],{"class":10849},[3856,10872,10873],{"class":10835},"$",[3856,10875,5975],{"class":10831},[3856,10877,3925],{"class":3870},[3856,10879,10880],{"class":3866},"test",[3856,10882,3871],{"class":3870},[3856,10884,3875],{"class":3874},[3856,10886,4896],{"class":3870},[3856,10888,10889],{"class":3858,"line":3907},[3856,10890,3961],{"class":3870},[3856,10892,10893],{"class":3858,"line":3913},[3856,10894,4153],{"emptyLinePlaceholder":4152},[3856,10896,10897,10899,10902,10904,10907,10909,10911,10913,10915],{"class":3858,"line":3919},[3856,10898,3863],{"class":3862},[3856,10900,10901],{"class":3866}," processInput",[3856,10903,3871],{"class":3870},[3856,10905,10906],{"class":3874},"input",[3856,10908,3878],{"class":3870},[3856,10910,3882],{"class":3881},[3856,10912,3891],{"class":3870},[3856,10914,3894],{"class":3881},[3856,10916,3897],{"class":3870},[3856,10918,10919,10921,10923,10926,10928,10930],{"class":3858,"line":3946},[3856,10920,4047],{"class":4046},[3856,10922,3981],{"class":3870},[3856,10924,10925],{"class":3866},"isValidEmail",[3856,10927,3871],{"class":3870},[3856,10929,10906],{"class":3874},[3856,10931,6531],{"class":3870},[3856,10933,10934],{"class":3858,"line":3952},[3856,10935,10936],{"class":3903},"    \u002F\u002F TypeScript НЕ знає, що тут input — це валідний email\n",[3856,10938,10939],{"class":3858,"line":3958},[3856,10940,10941],{"class":3903},"    \u002F\u002F input все ще має тип string\n",[3856,10943,10944,10947,10949,10951,10953],{"class":3858,"line":4138},[3856,10945,10946],{"class":3866},"    sendEmail",[3856,10948,3871],{"class":3870},[3856,10950,10906],{"class":3874},[3856,10952,4167],{"class":3870},[3856,10954,10955],{"class":3903},"\u002F\u002F TypeScript не може перевірити коректність\n",[3856,10957,10958],{"class":3858,"line":4144},[3856,10959,4141],{"class":3870},[3856,10961,10962],{"class":3858,"line":4149},[3856,10963,3961],{"class":3870},[3843,10965,10966,10967,4745,10969,10971,10972,10975,10976,10978],{},"Функція ",[3761,10968,10925],{},[3761,10970,4808],{},", але TypeScript ",[3793,10973,10974],{},"не розуміє",", що це звужує тип. Нам потрібен спосіб сказати TypeScript: \"якщо ця функція повернула ",[3761,10977,3823],{},", то значення гарантовано має певний тип\".",[3838,10980,10982],{"id":10981},"синтаксис-type-predicate","Синтаксис Type Predicate",[3843,10984,10985,3981,10988,10991,10992,10995,10996,10999],{},[3793,10986,10987],{},"Type predicate",[3753,10989,10990],{},"предикат типу",") — це спеціальний тип повернення функції у форматі ",[3761,10993,10994],{},"parameterName is Type",", що ",[3793,10997,10998],{},"явно"," повідомляє TypeScript про звуження типу:",[3847,11001,11003],{"className":3849,"code":11002,"language":3851,"meta":3852,"style":3852},"function isString(value: unknown): value is string {\n  return typeof value === \"string\";\n}\n\nfunction processValue(value: string | number): void {\n  if (isString(value)) {\n    \u002F\u002F Тут TypeScript ЗНАЄ, що value — це string\n    console.log(value.toUpperCase());\n  } else {\n    \u002F\u002F Тут value: number\n    console.log(value.toFixed(2));\n  }\n}\n",[3761,11004,11005,11030,11045,11049,11053,11077,11092,11097,11115,11123,11128,11150,11154],{"__ignoreMap":3852},[3856,11006,11007,11009,11012,11014,11016,11018,11020,11022,11024,11026,11028],{"class":3858,"line":3859},[3856,11008,3863],{"class":3862},[3856,11010,11011],{"class":3866}," isString",[3856,11013,3871],{"class":3870},[3856,11015,3875],{"class":3874},[3856,11017,3878],{"class":3870},[3856,11019,8921],{"class":3881},[3856,11021,3891],{"class":3870},[3856,11023,3875],{"class":3874},[3856,11025,6399],{"class":3862},[3856,11027,6402],{"class":3881},[3856,11029,3897],{"class":3870},[3856,11031,11032,11034,11037,11039,11041,11043],{"class":3858,"line":3900},[3856,11033,4914],{"class":4046},[3856,11035,11036],{"class":3862}," typeof",[3856,11038,4054],{"class":3874},[3856,11040,4057],{"class":3870},[3856,11042,4061],{"class":4060},[3856,11044,4931],{"class":3870},[3856,11046,11047],{"class":3858,"line":3907},[3856,11048,3961],{"class":3870},[3856,11050,11051],{"class":3858,"line":3913},[3856,11052,4153],{"emptyLinePlaceholder":4152},[3856,11054,11055,11057,11059,11061,11063,11065,11067,11069,11071,11073,11075],{"class":3858,"line":3919},[3856,11056,3863],{"class":3862},[3856,11058,3867],{"class":3866},[3856,11060,3871],{"class":3870},[3856,11062,3875],{"class":3874},[3856,11064,3878],{"class":3870},[3856,11066,3882],{"class":3881},[3856,11068,3885],{"class":3870},[3856,11070,3888],{"class":3881},[3856,11072,3891],{"class":3870},[3856,11074,3894],{"class":3881},[3856,11076,3897],{"class":3870},[3856,11078,11079,11081,11083,11086,11088,11090],{"class":3858,"line":3946},[3856,11080,4047],{"class":4046},[3856,11082,3981],{"class":3870},[3856,11084,11085],{"class":3866},"isString",[3856,11087,3871],{"class":3870},[3856,11089,3875],{"class":3874},[3856,11091,6531],{"class":3870},[3856,11093,11094],{"class":3858,"line":3952},[3856,11095,11096],{"class":3903},"    \u002F\u002F Тут TypeScript ЗНАЄ, що value — це string\n",[3856,11098,11099,11101,11103,11105,11107,11109,11111,11113],{"class":3858,"line":3958},[3856,11100,4074],{"class":3874},[3856,11102,3925],{"class":3870},[3856,11104,3928],{"class":3866},[3856,11106,3871],{"class":3870},[3856,11108,3875],{"class":3874},[3856,11110,3925],{"class":3870},[3856,11112,3937],{"class":3866},[3856,11114,5083],{"class":3870},[3856,11116,11117,11119,11121],{"class":3858,"line":4138},[3856,11118,4096],{"class":3870},[3856,11120,4099],{"class":4046},[3856,11122,3897],{"class":3870},[3856,11124,11125],{"class":3858,"line":4144},[3856,11126,11127],{"class":3903},"    \u002F\u002F Тут value: number\n",[3856,11129,11130,11132,11134,11136,11138,11140,11142,11144,11146,11148],{"class":3858,"line":4149},[3856,11131,4074],{"class":3874},[3856,11133,3925],{"class":3870},[3856,11135,3928],{"class":3866},[3856,11137,3871],{"class":3870},[3856,11139,3875],{"class":3874},[3856,11141,3925],{"class":3870},[3856,11143,4123],{"class":3866},[3856,11145,3871],{"class":3870},[3856,11147,4129],{"class":4128},[3856,11149,5119],{"class":3870},[3856,11151,11152],{"class":3858,"line":4156},[3856,11153,4141],{"class":3870},[3856,11155,11156],{"class":3858,"line":4173},[3856,11157,3961],{"class":3870},[3843,11159,11160],{},[3793,11161,11162],{},"Синтаксис:",[3847,11164,11166],{"className":3849,"code":11165,"language":3851,"meta":3852,"style":3852},"function isTypeName(value: WideType): value is NarrowType {\n  \u002F\u002F логіка перевірки\n  return \u002F* boolean вираз *\u002F;\n}\n",[3761,11167,11168,11195,11200,11209],{"__ignoreMap":3852},[3856,11169,11170,11172,11175,11177,11179,11181,11184,11186,11188,11190,11193],{"class":3858,"line":3859},[3856,11171,3863],{"class":3862},[3856,11173,11174],{"class":3866}," isTypeName",[3856,11176,3871],{"class":3870},[3856,11178,3875],{"class":3874},[3856,11180,3878],{"class":3870},[3856,11182,11183],{"class":3881},"WideType",[3856,11185,3891],{"class":3870},[3856,11187,3875],{"class":3874},[3856,11189,6399],{"class":3862},[3856,11191,11192],{"class":3881}," NarrowType",[3856,11194,3897],{"class":3870},[3856,11196,11197],{"class":3858,"line":3900},[3856,11198,11199],{"class":3903},"  \u002F\u002F логіка перевірки\n",[3856,11201,11202,11204,11207],{"class":3858,"line":3907},[3856,11203,4914],{"class":4046},[3856,11205,11206],{"class":3903}," \u002F* boolean вираз *\u002F",[3856,11208,4931],{"class":3870},[3856,11210,11211],{"class":3858,"line":3913},[3856,11212,3961],{"class":3870},[3746,11214,11215,11233],{},[3749,11216,11217,4749,11220,11223,11224,11226,11227,4204,11229,11232],{},[3761,11218,11219],{},"value is NarrowType",[3793,11221,11222],{},"type predicate",", що каже: \"якщо функція повертає ",[3761,11225,3823],{},", то параметр ",[3761,11228,3875],{},[3761,11230,11231],{},"NarrowType","\"",[3749,11234,11235,11236,11239],{},"TypeScript ",[3793,11237,11238],{},"довіряє"," вам — він не перевіряє логіку перевірки! Ви відповідаєте за коректність реалізації.",[3838,11241,11243],{"id":11242},"приклад-перевірка-на-масив","Приклад: перевірка на масив",[3847,11245,11247],{"className":3849,"code":11246,"language":3851,"meta":3852,"style":3852},"function isNumberArray(value: unknown): value is number[] {\n  return Array.isArray(value) && value.every(item => typeof item === \"number\");\n}\n\nfunction processData(data: unknown): void {\n  if (isNumberArray(data)) {\n    \u002F\u002F Тут data: number[]\n    let sum = data.reduce((acc, n) => acc + n, 0);\n    console.log(`Sum: ${sum}`);\n  } else {\n    console.log(\"Not a number array\");\n  }\n}\n\nprocessData([1, 2, 3, 4, 5]);      \u002F\u002F \"Sum: 15\"\nprocessData([1, \"two\", 3]);        \u002F\u002F \"Not a number array\"\nprocessData({ a: 1, b: 2 });       \u002F\u002F \"Not a number array\"\n",[3761,11248,11249,11276,11319,11323,11327,11347,11362,11367,11413,11437,11445,11460,11464,11468,11472,11504,11527],{"__ignoreMap":3852},[3856,11250,11251,11253,11256,11258,11260,11262,11264,11266,11268,11270,11273],{"class":3858,"line":3859},[3856,11252,3863],{"class":3862},[3856,11254,11255],{"class":3866}," isNumberArray",[3856,11257,3871],{"class":3870},[3856,11259,3875],{"class":3874},[3856,11261,3878],{"class":3870},[3856,11263,8921],{"class":3881},[3856,11265,3891],{"class":3870},[3856,11267,3875],{"class":3874},[3856,11269,6399],{"class":3862},[3856,11271,11272],{"class":3881}," number",[3856,11274,11275],{"class":3870},"[] {\n",[3856,11277,11278,11280,11282,11284,11286,11288,11290,11293,11295,11297,11300,11302,11305,11308,11310,11313,11315,11317],{"class":3858,"line":3900},[3856,11279,4914],{"class":4046},[3856,11281,8462],{"class":3874},[3856,11283,3925],{"class":3870},[3856,11285,9185],{"class":3866},[3856,11287,3871],{"class":3870},[3856,11289,3875],{"class":3874},[3856,11291,11292],{"class":3870},") && ",[3856,11294,3875],{"class":3874},[3856,11296,3925],{"class":3870},[3856,11298,11299],{"class":3866},"every",[3856,11301,3871],{"class":3870},[3856,11303,11304],{"class":3874},"item",[3856,11306,11307],{"class":3862}," =>",[3856,11309,11036],{"class":3862},[3856,11311,11312],{"class":3874}," item",[3856,11314,4057],{"class":3870},[3856,11316,4872],{"class":4060},[3856,11318,4896],{"class":3870},[3856,11320,11321],{"class":3858,"line":3907},[3856,11322,3961],{"class":3870},[3856,11324,11325],{"class":3858,"line":3913},[3856,11326,4153],{"emptyLinePlaceholder":4152},[3856,11328,11329,11331,11333,11335,11337,11339,11341,11343,11345],{"class":3858,"line":3919},[3856,11330,3863],{"class":3862},[3856,11332,8911],{"class":3866},[3856,11334,3871],{"class":3870},[3856,11336,8916],{"class":3874},[3856,11338,3878],{"class":3870},[3856,11340,8921],{"class":3881},[3856,11342,3891],{"class":3870},[3856,11344,3894],{"class":3881},[3856,11346,3897],{"class":3870},[3856,11348,11349,11351,11353,11356,11358,11360],{"class":3858,"line":3946},[3856,11350,4047],{"class":4046},[3856,11352,3981],{"class":3870},[3856,11354,11355],{"class":3866},"isNumberArray",[3856,11357,3871],{"class":3870},[3856,11359,8916],{"class":3874},[3856,11361,6531],{"class":3870},[3856,11363,11364],{"class":3858,"line":3952},[3856,11365,11366],{"class":3903},"    \u002F\u002F Тут data: number[]\n",[3856,11368,11369,11371,11374,11376,11378,11380,11383,11386,11389,11391,11393,11396,11399,11402,11405,11407,11409,11411],{"class":3858,"line":3958},[3856,11370,10447],{"class":3862},[3856,11372,11373],{"class":3874}," sum",[3856,11375,6507],{"class":3870},[3856,11377,8916],{"class":3874},[3856,11379,3925],{"class":3870},[3856,11381,11382],{"class":3866},"reduce",[3856,11384,11385],{"class":3870},"((",[3856,11387,11388],{"class":3874},"acc",[3856,11390,3764],{"class":3870},[3856,11392,4647],{"class":3874},[3856,11394,11395],{"class":3870},") ",[3856,11397,11398],{"class":3862},"=>",[3856,11400,11401],{"class":3874}," acc",[3856,11403,11404],{"class":3870}," + ",[3856,11406,4647],{"class":3874},[3856,11408,3764],{"class":3870},[3856,11410,5550],{"class":4128},[3856,11412,4896],{"class":3870},[3856,11414,11415,11417,11419,11421,11423,11426,11428,11431,11433,11435],{"class":3858,"line":4138},[3856,11416,4074],{"class":3874},[3856,11418,3925],{"class":3870},[3856,11420,3928],{"class":3866},[3856,11422,3871],{"class":3870},[3856,11424,11425],{"class":4060},"`Sum: ",[3856,11427,5238],{"class":3862},[3856,11429,11430],{"class":3874},"sum",[3856,11432,5249],{"class":3862},[3856,11434,5252],{"class":4060},[3856,11436,4896],{"class":3870},[3856,11438,11439,11441,11443],{"class":3858,"line":4144},[3856,11440,4096],{"class":3870},[3856,11442,4099],{"class":4046},[3856,11444,3897],{"class":3870},[3856,11446,11447,11449,11451,11453,11455,11458],{"class":3858,"line":4149},[3856,11448,4074],{"class":3874},[3856,11450,3925],{"class":3870},[3856,11452,3928],{"class":3866},[3856,11454,3871],{"class":3870},[3856,11456,11457],{"class":4060},"\"Not a number array\"",[3856,11459,4896],{"class":3870},[3856,11461,11462],{"class":3858,"line":4156},[3856,11463,4141],{"class":3870},[3856,11465,11466],{"class":3858,"line":4173},[3856,11467,3961],{"class":3870},[3856,11469,11470],{"class":3858,"line":4288},[3856,11471,4153],{"emptyLinePlaceholder":4152},[3856,11473,11474,11476,11478,11480,11482,11484,11486,11488,11490,11493,11495,11498,11501],{"class":3858,"line":4293},[3856,11475,9065],{"class":3866},[3856,11477,9068],{"class":3870},[3856,11479,5607],{"class":4128},[3856,11481,3764],{"class":3870},[3856,11483,4129],{"class":4128},[3856,11485,3764],{"class":3870},[3856,11487,9079],{"class":4128},[3856,11489,3764],{"class":3870},[3856,11491,11492],{"class":4128},"4",[3856,11494,3764],{"class":3870},[3856,11496,11497],{"class":4128},"5",[3856,11499,11500],{"class":3870},"]);      ",[3856,11502,11503],{"class":3903},"\u002F\u002F \"Sum: 15\"\n",[3856,11505,11506,11508,11510,11512,11514,11517,11519,11521,11524],{"class":3858,"line":4299},[3856,11507,9065],{"class":3866},[3856,11509,9068],{"class":3870},[3856,11511,5607],{"class":4128},[3856,11513,3764],{"class":3870},[3856,11515,11516],{"class":4060},"\"two\"",[3856,11518,3764],{"class":3870},[3856,11520,9079],{"class":4128},[3856,11522,11523],{"class":3870},"]);        ",[3856,11525,11526],{"class":3903},"\u002F\u002F \"Not a number array\"\n",[3856,11528,11529,11531,11533,11535,11537,11539,11541,11543,11546],{"class":3858,"line":4304},[3856,11530,9065],{"class":3866},[3856,11532,7700],{"class":3870},[3856,11534,9094],{"class":3874},[3856,11536,9097],{"class":4128},[3856,11538,3764],{"class":3870},[3856,11540,9102],{"class":3874},[3856,11542,9105],{"class":4128},[3856,11544,11545],{"class":3870}," });       ",[3856,11547,11526],{"class":3903},[3838,11549,11551],{"id":11550},"приклад-перевірка-структури-обєкта","Приклад: перевірка структури об'єкта",[3847,11553,11555],{"className":3849,"code":11554,"language":3851,"meta":3852,"style":3852},"function isUser(value: unknown): value is { name: string; age: number } {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    \"name\" in value &&\n    typeof (value as any).name === \"string\" &&\n    \"age\" in value &&\n    typeof (value as any).age === \"number\"\n  );\n}\n\nfunction greetUser(data: unknown): void {\n  if (isUser(data)) {\n    \u002F\u002F Тут data: { name: string; age: number }\n    console.log(`Hello, ${data.name}! You are ${data.age} years old.`);\n  } else {\n    console.log(\"Invalid user data\");\n  }\n}\n\ngreetUser({ name: \"Alice\", age: 28 });        \u002F\u002F \"Hello, Alice! You are 28 years old.\"\ngreetUser({ name: \"Bob\" });                   \u002F\u002F \"Invalid user data\"\ngreetUser({ name: \"Charlie\", age: \"30\" });    \u002F\u002F \"Invalid user data\"\n",[3761,11556,11557,11599,11606,11620,11631,11642,11666,11677,11698,11703,11707,11711,11732,11747,11752,11792,11800,11815,11819,11823,11827,11850,11866],{"__ignoreMap":3852},[3856,11558,11559,11561,11564,11566,11568,11570,11572,11574,11576,11578,11580,11583,11585,11587,11589,11592,11594,11596],{"class":3858,"line":3859},[3856,11560,3863],{"class":3862},[3856,11562,11563],{"class":3866}," isUser",[3856,11565,3871],{"class":3870},[3856,11567,3875],{"class":3874},[3856,11569,3878],{"class":3870},[3856,11571,8921],{"class":3881},[3856,11573,3891],{"class":3870},[3856,11575,3875],{"class":3874},[3856,11577,6399],{"class":3862},[3856,11579,10473],{"class":3870},[3856,11581,5805],{"class":11582},"s5IvJ",[3856,11584,3878],{"class":3870},[3856,11586,3882],{"class":3874},[3856,11588,7556],{"class":3870},[3856,11590,11591],{"class":11582},"age",[3856,11593,3878],{"class":3870},[3856,11595,3888],{"class":3874},[3856,11597,11598],{"class":3870}," } {\n",[3856,11600,11601,11603],{"class":3858,"line":3900},[3856,11602,4914],{"class":4046},[3856,11604,11605],{"class":3870}," (\n",[3856,11607,11608,11611,11613,11615,11617],{"class":3858,"line":3907},[3856,11609,11610],{"class":3862},"    typeof",[3856,11612,4054],{"class":3874},[3856,11614,4057],{"class":3870},[3856,11616,4748],{"class":4060},[3856,11618,11619],{"class":3870}," &&\n",[3856,11621,11622,11625,11627,11629],{"class":3858,"line":3913},[3856,11623,11624],{"class":3874},"    value",[3856,11626,6027],{"class":3870},[3856,11628,5299],{"class":3862},[3856,11630,11619],{"class":3870},[3856,11632,11633,11636,11638,11640],{"class":3858,"line":3919},[3856,11634,11635],{"class":4060},"    \"name\"",[3856,11637,7463],{"class":3862},[3856,11639,4054],{"class":3874},[3856,11641,11619],{"class":3870},[3856,11643,11644,11646,11648,11650,11653,11656,11658,11660,11662,11664],{"class":3858,"line":3946},[3856,11645,11610],{"class":3862},[3856,11647,3981],{"class":3870},[3856,11649,3875],{"class":3874},[3856,11651,11652],{"class":4046}," as",[3856,11654,11655],{"class":3881}," any",[3856,11657,9032],{"class":3870},[3856,11659,5805],{"class":3874},[3856,11661,4057],{"class":3870},[3856,11663,4061],{"class":4060},[3856,11665,11619],{"class":3870},[3856,11667,11668,11671,11673,11675],{"class":3858,"line":3952},[3856,11669,11670],{"class":4060},"    \"age\"",[3856,11672,7463],{"class":3862},[3856,11674,4054],{"class":3874},[3856,11676,11619],{"class":3870},[3856,11678,11679,11681,11683,11685,11687,11689,11691,11693,11695],{"class":3858,"line":3958},[3856,11680,11610],{"class":3862},[3856,11682,3981],{"class":3870},[3856,11684,3875],{"class":3874},[3856,11686,11652],{"class":4046},[3856,11688,11655],{"class":3881},[3856,11690,9032],{"class":3870},[3856,11692,11591],{"class":3874},[3856,11694,4057],{"class":3870},[3856,11696,11697],{"class":4060},"\"number\"\n",[3856,11699,11700],{"class":3858,"line":4138},[3856,11701,11702],{"class":3870},"  );\n",[3856,11704,11705],{"class":3858,"line":4144},[3856,11706,3961],{"class":3870},[3856,11708,11709],{"class":3858,"line":4149},[3856,11710,4153],{"emptyLinePlaceholder":4152},[3856,11712,11713,11715,11718,11720,11722,11724,11726,11728,11730],{"class":3858,"line":4156},[3856,11714,3863],{"class":3862},[3856,11716,11717],{"class":3866}," greetUser",[3856,11719,3871],{"class":3870},[3856,11721,8916],{"class":3874},[3856,11723,3878],{"class":3870},[3856,11725,8921],{"class":3881},[3856,11727,3891],{"class":3870},[3856,11729,3894],{"class":3881},[3856,11731,3897],{"class":3870},[3856,11733,11734,11736,11738,11741,11743,11745],{"class":3858,"line":4173},[3856,11735,4047],{"class":4046},[3856,11737,3981],{"class":3870},[3856,11739,11740],{"class":3866},"isUser",[3856,11742,3871],{"class":3870},[3856,11744,8916],{"class":3874},[3856,11746,6531],{"class":3870},[3856,11748,11749],{"class":3858,"line":4288},[3856,11750,11751],{"class":3903},"    \u002F\u002F Тут data: { name: string; age: number }\n",[3856,11753,11754,11756,11758,11760,11762,11764,11766,11768,11770,11772,11774,11777,11779,11781,11783,11785,11787,11790],{"class":3858,"line":4293},[3856,11755,4074],{"class":3874},[3856,11757,3925],{"class":3870},[3856,11759,3928],{"class":3866},[3856,11761,3871],{"class":3870},[3856,11763,5856],{"class":4060},[3856,11765,5238],{"class":3862},[3856,11767,8916],{"class":3874},[3856,11769,3925],{"class":5243},[3856,11771,5805],{"class":3874},[3856,11773,5249],{"class":3862},[3856,11775,11776],{"class":4060},"! You are ",[3856,11778,5238],{"class":3862},[3856,11780,8916],{"class":3874},[3856,11782,3925],{"class":5243},[3856,11784,11591],{"class":3874},[3856,11786,5249],{"class":3862},[3856,11788,11789],{"class":4060}," years old.`",[3856,11791,4896],{"class":3870},[3856,11793,11794,11796,11798],{"class":3858,"line":4299},[3856,11795,4096],{"class":3870},[3856,11797,4099],{"class":4046},[3856,11799,3897],{"class":3870},[3856,11801,11802,11804,11806,11808,11810,11813],{"class":3858,"line":4304},[3856,11803,4074],{"class":3874},[3856,11805,3925],{"class":3870},[3856,11807,3928],{"class":3866},[3856,11809,3871],{"class":3870},[3856,11811,11812],{"class":4060},"\"Invalid user data\"",[3856,11814,4896],{"class":3870},[3856,11816,11817],{"class":3858,"line":4310},[3856,11818,4141],{"class":3870},[3856,11820,11821],{"class":3858,"line":4316},[3856,11822,3961],{"class":3870},[3856,11824,11825],{"class":3858,"line":4322},[3856,11826,4153],{"emptyLinePlaceholder":4152},[3856,11828,11829,11832,11834,11836,11838,11840,11842,11844,11847],{"class":3858,"line":4328},[3856,11830,11831],{"class":3866},"greetUser",[3856,11833,7700],{"class":3870},[3856,11835,7429],{"class":3874},[3856,11837,7432],{"class":4060},[3856,11839,3764],{"class":3870},[3856,11841,7437],{"class":3874},[3856,11843,7440],{"class":4128},[3856,11845,11846],{"class":3870}," });        ",[3856,11848,11849],{"class":3903},"\u002F\u002F \"Hello, Alice! You are 28 years old.\"\n",[3856,11851,11852,11854,11856,11858,11860,11863],{"class":3858,"line":4333},[3856,11853,11831],{"class":3866},[3856,11855,7700],{"class":3870},[3856,11857,7429],{"class":3874},[3856,11859,7991],{"class":4060},[3856,11861,11862],{"class":3870}," });                   ",[3856,11864,11865],{"class":3903},"\u002F\u002F \"Invalid user data\"\n",[3856,11867,11868,11870,11872,11874,11877,11879,11881,11884,11886],{"class":3858,"line":4338},[3856,11869,11831],{"class":3866},[3856,11871,7700],{"class":3870},[3856,11873,7429],{"class":3874},[3856,11875,11876],{"class":4060}," \"Charlie\"",[3856,11878,3764],{"class":3870},[3856,11880,7437],{"class":3874},[3856,11882,11883],{"class":4060}," \"30\"",[3856,11885,9116],{"class":3870},[3856,11887,11865],{"class":3903},[3838,11889,11891],{"id":11890},"приклад-перевірка-на-nullundefined","Приклад: перевірка на null\u002Fundefined",[3847,11893,11895],{"className":3849,"code":11894,"language":3851,"meta":3852,"style":3852},"function isNotNull\u003CT>(value: T | null | undefined): value is T {\n  return value !== null && value !== undefined;\n}\n\nfunction processNames(names: (string | null | undefined)[]): void {\n  \u002F\u002F Фільтрація null та undefined через custom type guard\n  let validNames = names.filter(isNotNull);\n  \n  \u002F\u002F Тут validNames: string[] (без null та undefined)\n  validNames.forEach(name => {\n    console.log(name.toUpperCase());  \u002F\u002F OK: всі елементи — string\n  });\n}\n\nprocessNames([\"Alice\", null, \"Bob\", undefined, \"Charlie\"]);\n\u002F\u002F ALICE\n\u002F\u002F BOB\n\u002F\u002F CHARLIE\n",[3761,11896,11897,11938,11958,11962,11966,11998,12003,12027,12031,12036,12054,12075,12080,12084,12088,12118,12123,12128],{"__ignoreMap":3852},[3856,11898,11899,11901,11904,11907,11910,11913,11915,11917,11919,11921,11923,11925,11927,11929,11931,11933,11936],{"class":3858,"line":3859},[3856,11900,3863],{"class":3862},[3856,11902,11903],{"class":3866}," isNotNull",[3856,11905,11906],{"class":3870},"\u003C",[3856,11908,11909],{"class":3881},"T",[3856,11911,11912],{"class":3870},">(",[3856,11914,3875],{"class":3874},[3856,11916,3878],{"class":3870},[3856,11918,11909],{"class":3881},[3856,11920,3885],{"class":3870},[3856,11922,5299],{"class":3881},[3856,11924,3885],{"class":3870},[3856,11926,5139],{"class":3881},[3856,11928,3891],{"class":3870},[3856,11930,3875],{"class":3874},[3856,11932,6399],{"class":3862},[3856,11934,11935],{"class":3881}," T",[3856,11937,3897],{"class":3870},[3856,11939,11940,11942,11944,11946,11948,11950,11952,11954,11956],{"class":3858,"line":3900},[3856,11941,4914],{"class":4046},[3856,11943,4054],{"class":3874},[3856,11945,6027],{"class":3870},[3856,11947,5299],{"class":3862},[3856,11949,6032],{"class":3870},[3856,11951,3875],{"class":3874},[3856,11953,6027],{"class":3870},[3856,11955,5139],{"class":3862},[3856,11957,4931],{"class":3870},[3856,11959,11960],{"class":3858,"line":3907},[3856,11961,3961],{"class":3870},[3856,11963,11964],{"class":3858,"line":3913},[3856,11965,4153],{"emptyLinePlaceholder":4152},[3856,11967,11968,11970,11973,11975,11978,11981,11983,11985,11987,11989,11991,11994,11996],{"class":3858,"line":3919},[3856,11969,3863],{"class":3862},[3856,11971,11972],{"class":3866}," processNames",[3856,11974,3871],{"class":3870},[3856,11976,11977],{"class":3874},"names",[3856,11979,11980],{"class":3870},": (",[3856,11982,3882],{"class":3881},[3856,11984,3885],{"class":3870},[3856,11986,5299],{"class":3881},[3856,11988,3885],{"class":3870},[3856,11990,5139],{"class":3881},[3856,11992,11993],{"class":3870},")[]): ",[3856,11995,3894],{"class":3881},[3856,11997,3897],{"class":3870},[3856,11999,12000],{"class":3858,"line":3946},[3856,12001,12002],{"class":3903},"  \u002F\u002F Фільтрація null та undefined через custom type guard\n",[3856,12004,12005,12008,12011,12013,12015,12017,12020,12022,12025],{"class":3858,"line":3952},[3856,12006,12007],{"class":3862},"  let",[3856,12009,12010],{"class":3874}," validNames",[3856,12012,6507],{"class":3870},[3856,12014,11977],{"class":3874},[3856,12016,3925],{"class":3870},[3856,12018,12019],{"class":3866},"filter",[3856,12021,3871],{"class":3870},[3856,12023,12024],{"class":3874},"isNotNull",[3856,12026,4896],{"class":3870},[3856,12028,12029],{"class":3858,"line":3958},[3856,12030,3916],{"class":3870},[3856,12032,12033],{"class":3858,"line":4138},[3856,12034,12035],{"class":3903},"  \u002F\u002F Тут validNames: string[] (без null та undefined)\n",[3856,12037,12038,12041,12043,12046,12048,12050,12052],{"class":3858,"line":4144},[3856,12039,12040],{"class":3874},"  validNames",[3856,12042,3925],{"class":3870},[3856,12044,12045],{"class":3866},"forEach",[3856,12047,3871],{"class":3870},[3856,12049,5805],{"class":3874},[3856,12051,11307],{"class":3862},[3856,12053,3897],{"class":3870},[3856,12055,12056,12058,12060,12062,12064,12066,12068,12070,12072],{"class":3858,"line":4149},[3856,12057,4074],{"class":3874},[3856,12059,3925],{"class":3870},[3856,12061,3928],{"class":3866},[3856,12063,3871],{"class":3870},[3856,12065,5805],{"class":3874},[3856,12067,3925],{"class":3870},[3856,12069,3937],{"class":3866},[3856,12071,3940],{"class":3870},[3856,12073,12074],{"class":3903},"\u002F\u002F OK: всі елементи — string\n",[3856,12076,12077],{"class":3858,"line":4156},[3856,12078,12079],{"class":3870},"  });\n",[3856,12081,12082],{"class":3858,"line":4173},[3856,12083,3961],{"class":3870},[3856,12085,12086],{"class":3858,"line":4288},[3856,12087,4153],{"emptyLinePlaceholder":4152},[3856,12089,12090,12093,12095,12097,12099,12101,12103,12106,12108,12110,12112,12115],{"class":3858,"line":4293},[3856,12091,12092],{"class":3866},"processNames",[3856,12094,9068],{"class":3870},[3856,12096,5919],{"class":4060},[3856,12098,3764],{"class":3870},[3856,12100,5299],{"class":3862},[3856,12102,3764],{"class":3870},[3856,12104,12105],{"class":4060},"\"Bob\"",[3856,12107,3764],{"class":3870},[3856,12109,5139],{"class":3862},[3856,12111,3764],{"class":3870},[3856,12113,12114],{"class":4060},"\"Charlie\"",[3856,12116,12117],{"class":3870},"]);\n",[3856,12119,12120],{"class":3858,"line":4299},[3856,12121,12122],{"class":3903},"\u002F\u002F ALICE\n",[3856,12124,12125],{"class":3858,"line":4304},[3856,12126,12127],{"class":3903},"\u002F\u002F BOB\n",[3856,12129,12130],{"class":3858,"line":4310},[3856,12131,12132],{"class":3903},"\u002F\u002F CHARLIE\n",[5440,12134,12135,12143,12262],{},[3843,12136,12137,4193,12140,12142],{},[3793,12138,12139],{},"Відповідальність за коректність:",[3793,12141,11238],{}," вашому type predicate. Якщо ви напишете неправильну перевірку, TypeScript не виявить помилку:",[3847,12144,12146],{"className":3849,"code":12145,"language":3851,"meta":3852,"style":3852},"\u002F\u002F ❌ НЕПРАВИЛЬНО: функція каже, що value — це string, але не перевіряє!\nfunction isBrokenString(value: unknown): value is string {\n  return true;  \u002F\u002F завжди повертає true, навіть для чисел!\n}\n\nlet value: unknown = 42;\n\nif (isBrokenString(value)) {\n  \u002F\u002F TypeScript думає, що value — це string\n  console.log(value.toUpperCase());  \u002F\u002F Runtime error: toUpperCase is not a function\n}\n",[3761,12147,12148,12153,12178,12189,12193,12197,12213,12217,12232,12237,12258],{"__ignoreMap":3852},[3856,12149,12150],{"class":3858,"line":3859},[3856,12151,12152],{"class":3903},"\u002F\u002F ❌ НЕПРАВИЛЬНО: функція каже, що value — це string, але не перевіряє!\n",[3856,12154,12155,12157,12160,12162,12164,12166,12168,12170,12172,12174,12176],{"class":3858,"line":3900},[3856,12156,3863],{"class":3862},[3856,12158,12159],{"class":3866}," isBrokenString",[3856,12161,3871],{"class":3870},[3856,12163,3875],{"class":3874},[3856,12165,3878],{"class":3870},[3856,12167,8921],{"class":3881},[3856,12169,3891],{"class":3870},[3856,12171,3875],{"class":3874},[3856,12173,6399],{"class":3862},[3856,12175,6402],{"class":3881},[3856,12177,3897],{"class":3870},[3856,12179,12180,12182,12184,12186],{"class":3858,"line":3907},[3856,12181,4914],{"class":4046},[3856,12183,4576],{"class":3862},[3856,12185,6478],{"class":3870},[3856,12187,12188],{"class":3903},"\u002F\u002F завжди повертає true, навіть для чисел!\n",[3856,12190,12191],{"class":3858,"line":3913},[3856,12192,3961],{"class":3870},[3856,12194,12195],{"class":3858,"line":3919},[3856,12196,4153],{"emptyLinePlaceholder":4152},[3856,12198,12199,12201,12203,12205,12207,12209,12211],{"class":3858,"line":3946},[3856,12200,6494],{"class":3862},[3856,12202,4054],{"class":3874},[3856,12204,3878],{"class":3870},[3856,12206,8921],{"class":3881},[3856,12208,6507],{"class":3870},[3856,12210,4180],{"class":4128},[3856,12212,4931],{"class":3870},[3856,12214,12215],{"class":3858,"line":3952},[3856,12216,4153],{"emptyLinePlaceholder":4152},[3856,12218,12219,12221,12223,12226,12228,12230],{"class":3858,"line":3958},[3856,12220,4200],{"class":4046},[3856,12222,3981],{"class":3870},[3856,12224,12225],{"class":3866},"isBrokenString",[3856,12227,3871],{"class":3870},[3856,12229,3875],{"class":3874},[3856,12231,6531],{"class":3870},[3856,12233,12234],{"class":3858,"line":4138},[3856,12235,12236],{"class":3903},"  \u002F\u002F TypeScript думає, що value — це string\n",[3856,12238,12239,12241,12243,12245,12247,12249,12251,12253,12255],{"class":3858,"line":4144},[3856,12240,3922],{"class":3874},[3856,12242,3925],{"class":3870},[3856,12244,3928],{"class":3866},[3856,12246,3871],{"class":3870},[3856,12248,3875],{"class":3874},[3856,12250,3925],{"class":3870},[3856,12252,3937],{"class":3866},[3856,12254,3940],{"class":3870},[3856,12256,12257],{"class":3903},"\u002F\u002F Runtime error: toUpperCase is not a function\n",[3856,12259,12260],{"class":3858,"line":4149},[3856,12261,3961],{"class":3870},[3843,12263,12264,12265,12268],{},"Завжди переконуйтеся, що логіка перевірки у type guard функції ",[3793,12266,12267],{},"дійсно"," відповідає типу, що ви заявляєте.",[3838,12270,12272],{"id":12271},"generics-у-type-guards","Generics у Type Guards",[3843,12274,12275],{},"Type guards можна робити універсальними через generics (хоча ви ще не вивчали generics, це корисний патерн):",[3847,12277,12279],{"className":3849,"code":12278,"language":3851,"meta":3852,"style":3852},"function isArrayOf\u003CT>(\n  value: unknown,\n  itemCheck: (item: unknown) => item is T\n): value is T[] {\n  return Array.isArray(value) && value.every(itemCheck);\n}\n\nfunction isNumber(value: unknown): value is number {\n  return typeof value === \"number\";\n}\n\nfunction isString(value: unknown): value is string {\n  return typeof value === \"string\";\n}\n\nlet data1: unknown = [1, 2, 3];\nlet data2: unknown = [\"a\", \"b\", \"c\"];\nlet data3: unknown = [1, \"two\", 3];\n\nif (isArrayOf(data1, isNumber)) {\n  \u002F\u002F Тут data1: number[]\n  console.log(data1.map(n => n * 2));\n}\n\nif (isArrayOf(data2, isString)) {\n  \u002F\u002F Тут data2: string[]\n  console.log(data2.map(s => s.toUpperCase()));\n}\n\nif (isArrayOf(data3, isNumber)) {\n  \u002F\u002F Не пройде перевірку\n} else {\n  console.log(\"data3 is not a number array\");\n}\n",[3761,12280,12281,12295,12307,12331,12343,12372,12376,12380,12405,12419,12423,12427,12451,12465,12469,12473,12500,12528,12553,12557,12578,12583,12615,12619,12623,12642,12647,12680,12684,12688,12707,12712,12721,12736],{"__ignoreMap":3852},[3856,12282,12283,12285,12288,12290,12292],{"class":3858,"line":3859},[3856,12284,3863],{"class":3862},[3856,12286,12287],{"class":3866}," isArrayOf",[3856,12289,11906],{"class":3870},[3856,12291,11909],{"class":3881},[3856,12293,12294],{"class":3870},">(\n",[3856,12296,12297,12300,12302,12304],{"class":3858,"line":3900},[3856,12298,12299],{"class":3874},"  value",[3856,12301,3878],{"class":3870},[3856,12303,8921],{"class":3881},[3856,12305,12306],{"class":3870},",\n",[3856,12308,12309,12312,12314,12316,12318,12320,12322,12324,12326,12328],{"class":3858,"line":3907},[3856,12310,12311],{"class":3866},"  itemCheck",[3856,12313,11980],{"class":3870},[3856,12315,11304],{"class":3874},[3856,12317,3878],{"class":3870},[3856,12319,8921],{"class":3881},[3856,12321,11395],{"class":3870},[3856,12323,11398],{"class":3862},[3856,12325,11312],{"class":3874},[3856,12327,6399],{"class":3862},[3856,12329,12330],{"class":3881}," T\n",[3856,12332,12333,12335,12337,12339,12341],{"class":3858,"line":3913},[3856,12334,3891],{"class":3870},[3856,12336,3875],{"class":3874},[3856,12338,6399],{"class":3862},[3856,12340,11935],{"class":3881},[3856,12342,11275],{"class":3870},[3856,12344,12345,12347,12349,12351,12353,12355,12357,12359,12361,12363,12365,12367,12370],{"class":3858,"line":3919},[3856,12346,4914],{"class":4046},[3856,12348,8462],{"class":3874},[3856,12350,3925],{"class":3870},[3856,12352,9185],{"class":3866},[3856,12354,3871],{"class":3870},[3856,12356,3875],{"class":3874},[3856,12358,11292],{"class":3870},[3856,12360,3875],{"class":3874},[3856,12362,3925],{"class":3870},[3856,12364,11299],{"class":3866},[3856,12366,3871],{"class":3870},[3856,12368,12369],{"class":3874},"itemCheck",[3856,12371,4896],{"class":3870},[3856,12373,12374],{"class":3858,"line":3946},[3856,12375,3961],{"class":3870},[3856,12377,12378],{"class":3858,"line":3952},[3856,12379,4153],{"emptyLinePlaceholder":4152},[3856,12381,12382,12384,12387,12389,12391,12393,12395,12397,12399,12401,12403],{"class":3858,"line":3958},[3856,12383,3863],{"class":3862},[3856,12385,12386],{"class":3866}," isNumber",[3856,12388,3871],{"class":3870},[3856,12390,3875],{"class":3874},[3856,12392,3878],{"class":3870},[3856,12394,8921],{"class":3881},[3856,12396,3891],{"class":3870},[3856,12398,3875],{"class":3874},[3856,12400,6399],{"class":3862},[3856,12402,11272],{"class":3881},[3856,12404,3897],{"class":3870},[3856,12406,12407,12409,12411,12413,12415,12417],{"class":3858,"line":4138},[3856,12408,4914],{"class":4046},[3856,12410,11036],{"class":3862},[3856,12412,4054],{"class":3874},[3856,12414,4057],{"class":3870},[3856,12416,4872],{"class":4060},[3856,12418,4931],{"class":3870},[3856,12420,12421],{"class":3858,"line":4144},[3856,12422,3961],{"class":3870},[3856,12424,12425],{"class":3858,"line":4149},[3856,12426,4153],{"emptyLinePlaceholder":4152},[3856,12428,12429,12431,12433,12435,12437,12439,12441,12443,12445,12447,12449],{"class":3858,"line":4156},[3856,12430,3863],{"class":3862},[3856,12432,11011],{"class":3866},[3856,12434,3871],{"class":3870},[3856,12436,3875],{"class":3874},[3856,12438,3878],{"class":3870},[3856,12440,8921],{"class":3881},[3856,12442,3891],{"class":3870},[3856,12444,3875],{"class":3874},[3856,12446,6399],{"class":3862},[3856,12448,6402],{"class":3881},[3856,12450,3897],{"class":3870},[3856,12452,12453,12455,12457,12459,12461,12463],{"class":3858,"line":4173},[3856,12454,4914],{"class":4046},[3856,12456,11036],{"class":3862},[3856,12458,4054],{"class":3874},[3856,12460,4057],{"class":3870},[3856,12462,4061],{"class":4060},[3856,12464,4931],{"class":3870},[3856,12466,12467],{"class":3858,"line":4288},[3856,12468,3961],{"class":3870},[3856,12470,12471],{"class":3858,"line":4293},[3856,12472,4153],{"emptyLinePlaceholder":4152},[3856,12474,12475,12477,12480,12482,12484,12487,12489,12491,12493,12495,12497],{"class":3858,"line":4299},[3856,12476,6494],{"class":3862},[3856,12478,12479],{"class":3874}," data1",[3856,12481,3878],{"class":3870},[3856,12483,8921],{"class":3881},[3856,12485,12486],{"class":3870}," = [",[3856,12488,5607],{"class":4128},[3856,12490,3764],{"class":3870},[3856,12492,4129],{"class":4128},[3856,12494,3764],{"class":3870},[3856,12496,9079],{"class":4128},[3856,12498,12499],{"class":3870},"];\n",[3856,12501,12502,12504,12507,12509,12511,12513,12516,12518,12521,12523,12526],{"class":3858,"line":4304},[3856,12503,6494],{"class":3862},[3856,12505,12506],{"class":3874}," data2",[3856,12508,3878],{"class":3870},[3856,12510,8921],{"class":3881},[3856,12512,12486],{"class":3870},[3856,12514,12515],{"class":4060},"\"a\"",[3856,12517,3764],{"class":3870},[3856,12519,12520],{"class":4060},"\"b\"",[3856,12522,3764],{"class":3870},[3856,12524,12525],{"class":4060},"\"c\"",[3856,12527,12499],{"class":3870},[3856,12529,12530,12532,12535,12537,12539,12541,12543,12545,12547,12549,12551],{"class":3858,"line":4310},[3856,12531,6494],{"class":3862},[3856,12533,12534],{"class":3874}," data3",[3856,12536,3878],{"class":3870},[3856,12538,8921],{"class":3881},[3856,12540,12486],{"class":3870},[3856,12542,5607],{"class":4128},[3856,12544,3764],{"class":3870},[3856,12546,11516],{"class":4060},[3856,12548,3764],{"class":3870},[3856,12550,9079],{"class":4128},[3856,12552,12499],{"class":3870},[3856,12554,12555],{"class":3858,"line":4316},[3856,12556,4153],{"emptyLinePlaceholder":4152},[3856,12558,12559,12561,12563,12566,12568,12571,12573,12576],{"class":3858,"line":4322},[3856,12560,4200],{"class":4046},[3856,12562,3981],{"class":3870},[3856,12564,12565],{"class":3866},"isArrayOf",[3856,12567,3871],{"class":3870},[3856,12569,12570],{"class":3874},"data1",[3856,12572,3764],{"class":3870},[3856,12574,12575],{"class":3874},"isNumber",[3856,12577,6531],{"class":3870},[3856,12579,12580],{"class":3858,"line":4328},[3856,12581,12582],{"class":3903},"  \u002F\u002F Тут data1: number[]\n",[3856,12584,12585,12587,12589,12591,12593,12595,12597,12600,12602,12604,12606,12609,12611,12613],{"class":3858,"line":4333},[3856,12586,3922],{"class":3874},[3856,12588,3925],{"class":3870},[3856,12590,3928],{"class":3866},[3856,12592,3871],{"class":3870},[3856,12594,12570],{"class":3874},[3856,12596,3925],{"class":3870},[3856,12598,12599],{"class":3866},"map",[3856,12601,3871],{"class":3870},[3856,12603,4647],{"class":3874},[3856,12605,11307],{"class":3862},[3856,12607,12608],{"class":3874}," n",[3856,12610,7630],{"class":3870},[3856,12612,4129],{"class":4128},[3856,12614,5119],{"class":3870},[3856,12616,12617],{"class":3858,"line":4338},[3856,12618,3961],{"class":3870},[3856,12620,12621],{"class":3858,"line":4343},[3856,12622,4153],{"emptyLinePlaceholder":4152},[3856,12624,12625,12627,12629,12631,12633,12636,12638,12640],{"class":3858,"line":4349},[3856,12626,4200],{"class":4046},[3856,12628,3981],{"class":3870},[3856,12630,12565],{"class":3866},[3856,12632,3871],{"class":3870},[3856,12634,12635],{"class":3874},"data2",[3856,12637,3764],{"class":3870},[3856,12639,11085],{"class":3874},[3856,12641,6531],{"class":3870},[3856,12643,12644],{"class":3858,"line":4354},[3856,12645,12646],{"class":3903},"  \u002F\u002F Тут data2: string[]\n",[3856,12648,12649,12651,12653,12655,12657,12659,12661,12663,12665,12668,12670,12673,12675,12677],{"class":3858,"line":4360},[3856,12650,3922],{"class":3874},[3856,12652,3925],{"class":3870},[3856,12654,3928],{"class":3866},[3856,12656,3871],{"class":3870},[3856,12658,12635],{"class":3874},[3856,12660,3925],{"class":3870},[3856,12662,12599],{"class":3866},[3856,12664,3871],{"class":3870},[3856,12666,12667],{"class":3874},"s",[3856,12669,11307],{"class":3862},[3856,12671,12672],{"class":3874}," s",[3856,12674,3925],{"class":3870},[3856,12676,3937],{"class":3866},[3856,12678,12679],{"class":3870},"()));\n",[3856,12681,12682],{"class":3858,"line":4366},[3856,12683,3961],{"class":3870},[3856,12685,12686],{"class":3858,"line":4372},[3856,12687,4153],{"emptyLinePlaceholder":4152},[3856,12689,12690,12692,12694,12696,12698,12701,12703,12705],{"class":3858,"line":4378},[3856,12691,4200],{"class":4046},[3856,12693,3981],{"class":3870},[3856,12695,12565],{"class":3866},[3856,12697,3871],{"class":3870},[3856,12699,12700],{"class":3874},"data3",[3856,12702,3764],{"class":3870},[3856,12704,12575],{"class":3874},[3856,12706,6531],{"class":3870},[3856,12708,12709],{"class":3858,"line":4383},[3856,12710,12711],{"class":3903},"  \u002F\u002F Не пройде перевірку\n",[3856,12713,12714,12717,12719],{"class":3858,"line":4388},[3856,12715,12716],{"class":3870},"} ",[3856,12718,4099],{"class":4046},[3856,12720,3897],{"class":3870},[3856,12722,12723,12725,12727,12729,12731,12734],{"class":3858,"line":4393},[3856,12724,3922],{"class":3874},[3856,12726,3925],{"class":3870},[3856,12728,3928],{"class":3866},[3856,12730,3871],{"class":3870},[3856,12732,12733],{"class":4060},"\"data3 is not a number array\"",[3856,12735,4896],{"class":3870},[3856,12737,12738],{"class":3858,"line":4399},[3856,12739,3961],{"class":3870},[3830,12741],{},[3833,12743,12745],{"id":12744},"control-flow-analysis","Control Flow Analysis",[3838,12747,12749],{"id":12748},"typescript-відстежує-потік-виконання","TypeScript відстежує потік виконання",[3843,12751,12752,12753,3981,12756,12759],{},"TypeScript не просто перевіряє типи у ізольованих виразах — він ",[3793,12754,12755],{},"аналізує потік виконання коду",[3753,12757,12758],{},"control flow analysis",") та відстежує, як типи змінюються в різних гілках:",[3847,12761,12763],{"className":3849,"code":12762,"language":3851,"meta":3852,"style":3852},"function example(x: string | number | null): void {\n  \u002F\u002F Тут x: string | number | null\n  \n  if (x === null) {\n    \u002F\u002F Тут x: null\n    console.log(\"x is null\");\n    return;\n  }\n  \n  \u002F\u002F Після return TypeScript знає, що x НЕ null\n  \u002F\u002F Тут x: string | number\n  \n  if (typeof x === \"string\") {\n    \u002F\u002F Тут x: string\n    console.log(x.toUpperCase());\n    return;\n  }\n  \n  \u002F\u002F Після return TypeScript знає, що x НЕ string\n  \u002F\u002F Тут x: number (єдиний варіант, що залишився)\n  console.log(x.toFixed(2));\n}\n",[3761,12764,12765,12793,12798,12802,12816,12821,12836,12842,12846,12850,12855,12860,12864,12880,12885,12903,12909,12913,12917,12922,12927,12949],{"__ignoreMap":3852},[3856,12766,12767,12769,12771,12773,12775,12777,12779,12781,12783,12785,12787,12789,12791],{"class":3858,"line":3859},[3856,12768,3863],{"class":3862},[3856,12770,5023],{"class":3866},[3856,12772,3871],{"class":3870},[3856,12774,5028],{"class":3874},[3856,12776,3878],{"class":3870},[3856,12778,3882],{"class":3881},[3856,12780,3885],{"class":3870},[3856,12782,3888],{"class":3881},[3856,12784,3885],{"class":3870},[3856,12786,5299],{"class":3881},[3856,12788,3891],{"class":3870},[3856,12790,3894],{"class":3881},[3856,12792,3897],{"class":3870},[3856,12794,12795],{"class":3858,"line":3900},[3856,12796,12797],{"class":3903},"  \u002F\u002F Тут x: string | number | null\n",[3856,12799,12800],{"class":3858,"line":3907},[3856,12801,3916],{"class":3870},[3856,12803,12804,12806,12808,12810,12812,12814],{"class":3858,"line":3913},[3856,12805,4047],{"class":4046},[3856,12807,3981],{"class":3870},[3856,12809,5028],{"class":3874},[3856,12811,4057],{"class":3870},[3856,12813,5299],{"class":3862},[3856,12815,4064],{"class":3870},[3856,12817,12818],{"class":3858,"line":3919},[3856,12819,12820],{"class":3903},"    \u002F\u002F Тут x: null\n",[3856,12822,12823,12825,12827,12829,12831,12834],{"class":3858,"line":3946},[3856,12824,4074],{"class":3874},[3856,12826,3925],{"class":3870},[3856,12828,3928],{"class":3866},[3856,12830,3871],{"class":3870},[3856,12832,12833],{"class":4060},"\"x is null\"",[3856,12835,4896],{"class":3870},[3856,12837,12838,12840],{"class":3858,"line":3952},[3856,12839,4840],{"class":4046},[3856,12841,4931],{"class":3870},[3856,12843,12844],{"class":3858,"line":3958},[3856,12845,4141],{"class":3870},[3856,12847,12848],{"class":3858,"line":4138},[3856,12849,3916],{"class":3870},[3856,12851,12852],{"class":3858,"line":4144},[3856,12853,12854],{"class":3903},"  \u002F\u002F Після return TypeScript знає, що x НЕ null\n",[3856,12856,12857],{"class":3858,"line":4149},[3856,12858,12859],{"class":3903},"  \u002F\u002F Тут x: string | number\n",[3856,12861,12862],{"class":3858,"line":4156},[3856,12863,3916],{"class":3870},[3856,12865,12866,12868,12870,12872,12874,12876,12878],{"class":3858,"line":4173},[3856,12867,4047],{"class":4046},[3856,12869,3981],{"class":3870},[3856,12871,3763],{"class":3862},[3856,12873,5053],{"class":3874},[3856,12875,4057],{"class":3870},[3856,12877,4061],{"class":4060},[3856,12879,4064],{"class":3870},[3856,12881,12882],{"class":3858,"line":4288},[3856,12883,12884],{"class":3903},"    \u002F\u002F Тут x: string\n",[3856,12886,12887,12889,12891,12893,12895,12897,12899,12901],{"class":3858,"line":4293},[3856,12888,4074],{"class":3874},[3856,12890,3925],{"class":3870},[3856,12892,3928],{"class":3866},[3856,12894,3871],{"class":3870},[3856,12896,5028],{"class":3874},[3856,12898,3925],{"class":3870},[3856,12900,3937],{"class":3866},[3856,12902,5083],{"class":3870},[3856,12904,12905,12907],{"class":3858,"line":4299},[3856,12906,4840],{"class":4046},[3856,12908,4931],{"class":3870},[3856,12910,12911],{"class":3858,"line":4304},[3856,12912,4141],{"class":3870},[3856,12914,12915],{"class":3858,"line":4310},[3856,12916,3916],{"class":3870},[3856,12918,12919],{"class":3858,"line":4316},[3856,12920,12921],{"class":3903},"  \u002F\u002F Після return TypeScript знає, що x НЕ string\n",[3856,12923,12924],{"class":3858,"line":4322},[3856,12925,12926],{"class":3903},"  \u002F\u002F Тут x: number (єдиний варіант, що залишився)\n",[3856,12928,12929,12931,12933,12935,12937,12939,12941,12943,12945,12947],{"class":3858,"line":4328},[3856,12930,3922],{"class":3874},[3856,12932,3925],{"class":3870},[3856,12934,3928],{"class":3866},[3856,12936,3871],{"class":3870},[3856,12938,5028],{"class":3874},[3856,12940,3925],{"class":3870},[3856,12942,4123],{"class":3866},[3856,12944,3871],{"class":3870},[3856,12946,4129],{"class":4128},[3856,12948,5119],{"class":3870},[3856,12950,12951],{"class":3858,"line":4333},[3856,12952,3961],{"class":3870},[3843,12954,11235,12955,12958],{},[3793,12956,12957],{},"пам'ятає",", які типи були виключені у попередніх перевірках, та звужує тип до залишкових варіантів.",[3838,12960,12962],{"id":12961},"early-return-для-звуження","Early return для звуження",[3843,12964,12965,12966,12969],{},"Патерн ",[3793,12967,12968],{},"early return"," (ранній вихід) ефективно звужує типи:",[3847,12971,12973],{"className":3849,"code":12972,"language":3851,"meta":3852,"style":3852},"function processValue(value: string | number | null | undefined): void {\n  if (value === null) {\n    console.log(\"Value is null\");\n    return;\n  }\n  \n  if (value === undefined) {\n    console.log(\"Value is undefined\");\n    return;\n  }\n  \n  \u002F\u002F Тут value: string | number (null та undefined виключені)\n  \n  if (typeof value === \"string\") {\n    console.log(value.toUpperCase());\n    return;\n  }\n  \n  \u002F\u002F Тут value: number (єдиний варіант)\n  console.log(value.toFixed(2));\n}\n",[3761,12974,12975,13007,13021,13035,13041,13045,13049,13063,13077,13083,13087,13091,13096,13100,13116,13134,13140,13144,13148,13153,13175],{"__ignoreMap":3852},[3856,12976,12977,12979,12981,12983,12985,12987,12989,12991,12993,12995,12997,12999,13001,13003,13005],{"class":3858,"line":3859},[3856,12978,3863],{"class":3862},[3856,12980,3867],{"class":3866},[3856,12982,3871],{"class":3870},[3856,12984,3875],{"class":3874},[3856,12986,3878],{"class":3870},[3856,12988,3882],{"class":3881},[3856,12990,3885],{"class":3870},[3856,12992,3888],{"class":3881},[3856,12994,3885],{"class":3870},[3856,12996,5299],{"class":3881},[3856,12998,3885],{"class":3870},[3856,13000,5139],{"class":3881},[3856,13002,3891],{"class":3870},[3856,13004,3894],{"class":3881},[3856,13006,3897],{"class":3870},[3856,13008,13009,13011,13013,13015,13017,13019],{"class":3858,"line":3900},[3856,13010,4047],{"class":4046},[3856,13012,3981],{"class":3870},[3856,13014,3875],{"class":3874},[3856,13016,4057],{"class":3870},[3856,13018,5299],{"class":3862},[3856,13020,4064],{"class":3870},[3856,13022,13023,13025,13027,13029,13031,13033],{"class":3858,"line":3907},[3856,13024,4074],{"class":3874},[3856,13026,3925],{"class":3870},[3856,13028,3928],{"class":3866},[3856,13030,3871],{"class":3870},[3856,13032,5395],{"class":4060},[3856,13034,4896],{"class":3870},[3856,13036,13037,13039],{"class":3858,"line":3913},[3856,13038,4840],{"class":4046},[3856,13040,4931],{"class":3870},[3856,13042,13043],{"class":3858,"line":3919},[3856,13044,4141],{"class":3870},[3856,13046,13047],{"class":3858,"line":3946},[3856,13048,3916],{"class":3870},[3856,13050,13051,13053,13055,13057,13059,13061],{"class":3858,"line":3952},[3856,13052,4047],{"class":4046},[3856,13054,3981],{"class":3870},[3856,13056,3875],{"class":3874},[3856,13058,4057],{"class":3870},[3856,13060,5139],{"class":3862},[3856,13062,4064],{"class":3870},[3856,13064,13065,13067,13069,13071,13073,13075],{"class":3858,"line":3958},[3856,13066,4074],{"class":3874},[3856,13068,3925],{"class":3870},[3856,13070,3928],{"class":3866},[3856,13072,3871],{"class":3870},[3856,13074,7008],{"class":4060},[3856,13076,4896],{"class":3870},[3856,13078,13079,13081],{"class":3858,"line":4138},[3856,13080,4840],{"class":4046},[3856,13082,4931],{"class":3870},[3856,13084,13085],{"class":3858,"line":4144},[3856,13086,4141],{"class":3870},[3856,13088,13089],{"class":3858,"line":4149},[3856,13090,3916],{"class":3870},[3856,13092,13093],{"class":3858,"line":4156},[3856,13094,13095],{"class":3903},"  \u002F\u002F Тут value: string | number (null та undefined виключені)\n",[3856,13097,13098],{"class":3858,"line":4173},[3856,13099,3916],{"class":3870},[3856,13101,13102,13104,13106,13108,13110,13112,13114],{"class":3858,"line":4288},[3856,13103,4047],{"class":4046},[3856,13105,3981],{"class":3870},[3856,13107,3763],{"class":3862},[3856,13109,4054],{"class":3874},[3856,13111,4057],{"class":3870},[3856,13113,4061],{"class":4060},[3856,13115,4064],{"class":3870},[3856,13117,13118,13120,13122,13124,13126,13128,13130,13132],{"class":3858,"line":4293},[3856,13119,4074],{"class":3874},[3856,13121,3925],{"class":3870},[3856,13123,3928],{"class":3866},[3856,13125,3871],{"class":3870},[3856,13127,3875],{"class":3874},[3856,13129,3925],{"class":3870},[3856,13131,3937],{"class":3866},[3856,13133,5083],{"class":3870},[3856,13135,13136,13138],{"class":3858,"line":4299},[3856,13137,4840],{"class":4046},[3856,13139,4931],{"class":3870},[3856,13141,13142],{"class":3858,"line":4304},[3856,13143,4141],{"class":3870},[3856,13145,13146],{"class":3858,"line":4310},[3856,13147,3916],{"class":3870},[3856,13149,13150],{"class":3858,"line":4316},[3856,13151,13152],{"class":3903},"  \u002F\u002F Тут value: number (єдиний варіант)\n",[3856,13154,13155,13157,13159,13161,13163,13165,13167,13169,13171,13173],{"class":3858,"line":4322},[3856,13156,3922],{"class":3874},[3856,13158,3925],{"class":3870},[3856,13160,3928],{"class":3866},[3856,13162,3871],{"class":3870},[3856,13164,3875],{"class":3874},[3856,13166,3925],{"class":3870},[3856,13168,4123],{"class":3866},[3856,13170,3871],{"class":3870},[3856,13172,4129],{"class":4128},[3856,13174,5119],{"class":3870},[3856,13176,13177],{"class":3858,"line":4328},[3856,13178,3961],{"class":3870},[3843,13180,13181,13182,13185],{},"Цей підхід робить код більш лінійним та зрозумілим, ніж вкладені ",[3761,13183,13184],{},"if-else"," блоки.",[3838,13187,13189],{"id":13188},"логічні-оператори-та","Логічні оператори && та ||",[3843,13191,13192],{},"TypeScript розуміє логічні оператори та звужує типи відповідно:",[3847,13194,13196],{"className":3849,"code":13195,"language":3851,"meta":3852,"style":3852},"function printLength(text: string | null): void {\n  \u002F\u002F Оператор && виконує правий операнд лише якщо лівий truthy\n  text && console.log(text.length);\n  \u002F\u002F TypeScript знає, що якщо дійшло до text.length, то text не null\n}\n\nfunction getDefault(value: string | null): string {\n  \u002F\u002F Оператор || повертає лівий операнд, якщо він truthy, інакше — правий\n  return value || \"default\";\n  \u002F\u002F TypeScript знає, що якщо value є null, повернеться \"default\"\n}\n",[3761,13197,13198,13222,13227,13250,13255,13259,13263,13288,13293,13307,13312],{"__ignoreMap":3852},[3856,13199,13200,13202,13204,13206,13208,13210,13212,13214,13216,13218,13220],{"class":3858,"line":3859},[3856,13201,3863],{"class":3862},[3856,13203,5151],{"class":3866},[3856,13205,3871],{"class":3870},[3856,13207,5156],{"class":3874},[3856,13209,3878],{"class":3870},[3856,13211,3882],{"class":3881},[3856,13213,3885],{"class":3870},[3856,13215,5299],{"class":3881},[3856,13217,3891],{"class":3870},[3856,13219,3894],{"class":3881},[3856,13221,3897],{"class":3870},[3856,13223,13224],{"class":3858,"line":3900},[3856,13225,13226],{"class":3903},"  \u002F\u002F Оператор && виконує правий операнд лише якщо лівий truthy\n",[3856,13228,13229,13232,13234,13236,13238,13240,13242,13244,13246,13248],{"class":3858,"line":3907},[3856,13230,13231],{"class":3874},"  text",[3856,13233,6032],{"class":3870},[3856,13235,4524],{"class":3874},[3856,13237,3925],{"class":3870},[3856,13239,3928],{"class":3866},[3856,13241,3871],{"class":3870},[3856,13243,5156],{"class":3874},[3856,13245,3925],{"class":3870},[3856,13247,5246],{"class":3874},[3856,13249,4896],{"class":3870},[3856,13251,13252],{"class":3858,"line":3913},[3856,13253,13254],{"class":3903},"  \u002F\u002F TypeScript знає, що якщо дійшло до text.length, то text не null\n",[3856,13256,13257],{"class":3858,"line":3919},[3856,13258,3961],{"class":3870},[3856,13260,13261],{"class":3858,"line":3946},[3856,13262,4153],{"emptyLinePlaceholder":4152},[3856,13264,13265,13267,13270,13272,13274,13276,13278,13280,13282,13284,13286],{"class":3858,"line":3952},[3856,13266,3863],{"class":3862},[3856,13268,13269],{"class":3866}," getDefault",[3856,13271,3871],{"class":3870},[3856,13273,3875],{"class":3874},[3856,13275,3878],{"class":3870},[3856,13277,3882],{"class":3881},[3856,13279,3885],{"class":3870},[3856,13281,5299],{"class":3881},[3856,13283,3891],{"class":3870},[3856,13285,3882],{"class":3881},[3856,13287,3897],{"class":3870},[3856,13289,13290],{"class":3858,"line":3958},[3856,13291,13292],{"class":3903},"  \u002F\u002F Оператор || повертає лівий операнд, якщо він truthy, інакше — правий\n",[3856,13294,13295,13297,13299,13302,13305],{"class":3858,"line":4138},[3856,13296,4914],{"class":4046},[3856,13298,4054],{"class":3874},[3856,13300,13301],{"class":3870}," || ",[3856,13303,13304],{"class":4060},"\"default\"",[3856,13306,4931],{"class":3870},[3856,13308,13309],{"class":3858,"line":4144},[3856,13310,13311],{"class":3903},"  \u002F\u002F TypeScript знає, що якщо value є null, повернеться \"default\"\n",[3856,13313,13314],{"class":3858,"line":4149},[3856,13315,3961],{"class":3870},[3843,13317,13318],{},[3793,13319,13320,13321,13324],{},"Nullish coalescing (",[3761,13322,13323],{},"??","):",[3847,13326,13328],{"className":3849,"code":13327,"language":3851,"meta":3852,"style":3852},"function getDefault(value: string | null | undefined): string {\n  \u002F\u002F ?? повертає правий операнд лише якщо лівий — null або undefined\n  return value ?? \"default\";\n}\n\nconsole.log(getDefault(\"hello\"));     \u002F\u002F \"hello\"\nconsole.log(getDefault(null));        \u002F\u002F \"default\"\nconsole.log(getDefault(undefined));   \u002F\u002F \"default\"\nconsole.log(getDefault(\"\"));          \u002F\u002F \"\" (порожній рядок не замінюється!)\n",[3761,13329,13330,13358,13363,13376,13380,13384,13406,13428,13448],{"__ignoreMap":3852},[3856,13331,13332,13334,13336,13338,13340,13342,13344,13346,13348,13350,13352,13354,13356],{"class":3858,"line":3859},[3856,13333,3863],{"class":3862},[3856,13335,13269],{"class":3866},[3856,13337,3871],{"class":3870},[3856,13339,3875],{"class":3874},[3856,13341,3878],{"class":3870},[3856,13343,3882],{"class":3881},[3856,13345,3885],{"class":3870},[3856,13347,5299],{"class":3881},[3856,13349,3885],{"class":3870},[3856,13351,5139],{"class":3881},[3856,13353,3891],{"class":3870},[3856,13355,3882],{"class":3881},[3856,13357,3897],{"class":3870},[3856,13359,13360],{"class":3858,"line":3900},[3856,13361,13362],{"class":3903},"  \u002F\u002F ?? повертає правий операнд лише якщо лівий — null або undefined\n",[3856,13364,13365,13367,13369,13372,13374],{"class":3858,"line":3907},[3856,13366,4914],{"class":4046},[3856,13368,4054],{"class":3874},[3856,13370,13371],{"class":3870}," ?? ",[3856,13373,13304],{"class":4060},[3856,13375,4931],{"class":3870},[3856,13377,13378],{"class":3858,"line":3913},[3856,13379,3961],{"class":3870},[3856,13381,13382],{"class":3858,"line":3919},[3856,13383,4153],{"emptyLinePlaceholder":4152},[3856,13385,13386,13388,13390,13392,13394,13397,13399,13401,13403],{"class":3858,"line":3946},[3856,13387,4524],{"class":3874},[3856,13389,3925],{"class":3870},[3856,13391,3928],{"class":3866},[3856,13393,3871],{"class":3870},[3856,13395,13396],{"class":3866},"getDefault",[3856,13398,3871],{"class":3870},[3856,13400,4164],{"class":4060},[3856,13402,4132],{"class":3870},[3856,13404,13405],{"class":3903},"\u002F\u002F \"hello\"\n",[3856,13407,13408,13410,13412,13414,13416,13418,13420,13422,13425],{"class":3858,"line":3952},[3856,13409,4524],{"class":3874},[3856,13411,3925],{"class":3870},[3856,13413,3928],{"class":3866},[3856,13415,3871],{"class":3870},[3856,13417,13396],{"class":3866},[3856,13419,3871],{"class":3870},[3856,13421,5299],{"class":3862},[3856,13423,13424],{"class":3870},"));        ",[3856,13426,13427],{"class":3903},"\u002F\u002F \"default\"\n",[3856,13429,13430,13432,13434,13436,13438,13440,13442,13444,13446],{"class":3858,"line":3958},[3856,13431,4524],{"class":3874},[3856,13433,3925],{"class":3870},[3856,13435,3928],{"class":3866},[3856,13437,3871],{"class":3870},[3856,13439,13396],{"class":3866},[3856,13441,3871],{"class":3870},[3856,13443,5139],{"class":3862},[3856,13445,4959],{"class":3870},[3856,13447,13427],{"class":3903},[3856,13449,13450,13452,13454,13456,13458,13460,13462,13464,13467],{"class":3858,"line":4138},[3856,13451,4524],{"class":3874},[3856,13453,3925],{"class":3870},[3856,13455,3928],{"class":3866},[3856,13457,3871],{"class":3870},[3856,13459,13396],{"class":3866},[3856,13461,3871],{"class":3870},[3856,13463,5568],{"class":4060},[3856,13465,13466],{"class":3870},"));          ",[3856,13468,13469],{"class":3903},"\u002F\u002F \"\" (порожній рядок не замінюється!)\n",[3843,13471,13472,13473,5786,13476,4737],{},"Різниця між ",[3761,13474,13475],{},"||",[3761,13477,13323],{},[3746,13479,13480,13495],{},[3749,13481,13482,13484,13485,3764,13487,3764,13489,3764,13491,3764,13493,5483],{},[3761,13483,13475],{}," повертає правий операнд для будь-якого falsy значення (",[3761,13486,5550],{},[3761,13488,5568],{},[3761,13490,3827],{},[3761,13492,5299],{},[3761,13494,5139],{},[3749,13496,13497,13499,13500,9743,13503,5786,13505],{},[3761,13498,13323],{}," повертає правий операнд ",[3793,13501,13502],{},"лише",[3761,13504,5299],{},[3761,13506,5139],{},[3847,13508,13510],{"className":3849,"code":13509,"language":3851,"meta":3852,"style":3852},"console.log(0 || 10);       \u002F\u002F 10 (0 — falsy)\nconsole.log(0 ?? 10);       \u002F\u002F 0 (0 — не null\u002Fundefined)\n\nconsole.log(\"\" || \"default\");   \u002F\u002F \"default\" (порожній рядок — falsy)\nconsole.log(\"\" ?? \"default\");   \u002F\u002F \"\" (порожній рядок — не null\u002Fundefined)\n",[3761,13511,13512,13534,13555,13559,13580],{"__ignoreMap":3852},[3856,13513,13514,13516,13518,13520,13522,13524,13526,13529,13531],{"class":3858,"line":3859},[3856,13515,4524],{"class":3874},[3856,13517,3925],{"class":3870},[3856,13519,3928],{"class":3866},[3856,13521,3871],{"class":3870},[3856,13523,5550],{"class":4128},[3856,13525,13301],{"class":3870},[3856,13527,13528],{"class":4128},"10",[3856,13530,4183],{"class":3870},[3856,13532,13533],{"class":3903},"\u002F\u002F 10 (0 — falsy)\n",[3856,13535,13536,13538,13540,13542,13544,13546,13548,13550,13552],{"class":3858,"line":3900},[3856,13537,4524],{"class":3874},[3856,13539,3925],{"class":3870},[3856,13541,3928],{"class":3866},[3856,13543,3871],{"class":3870},[3856,13545,5550],{"class":4128},[3856,13547,13371],{"class":3870},[3856,13549,13528],{"class":4128},[3856,13551,4183],{"class":3870},[3856,13553,13554],{"class":3903},"\u002F\u002F 0 (0 — не null\u002Fundefined)\n",[3856,13556,13557],{"class":3858,"line":3907},[3856,13558,4153],{"emptyLinePlaceholder":4152},[3856,13560,13561,13563,13565,13567,13569,13571,13573,13575,13577],{"class":3858,"line":3913},[3856,13562,4524],{"class":3874},[3856,13564,3925],{"class":3870},[3856,13566,3928],{"class":3866},[3856,13568,3871],{"class":3870},[3856,13570,5568],{"class":4060},[3856,13572,13301],{"class":3870},[3856,13574,13304],{"class":4060},[3856,13576,5949],{"class":3870},[3856,13578,13579],{"class":3903},"\u002F\u002F \"default\" (порожній рядок — falsy)\n",[3856,13581,13582,13584,13586,13588,13590,13592,13594,13596,13598],{"class":3858,"line":3919},[3856,13583,4524],{"class":3874},[3856,13585,3925],{"class":3870},[3856,13587,3928],{"class":3866},[3856,13589,3871],{"class":3870},[3856,13591,5568],{"class":4060},[3856,13593,13371],{"class":3870},[3856,13595,13304],{"class":4060},[3856,13597,5949],{"class":3870},[3856,13599,13600],{"class":3903},"\u002F\u002F \"\" (порожній рядок — не null\u002Fundefined)\n",[3838,13602,13604],{"id":13603},"optional-chaining-для-безпечного-доступу","Optional chaining (?.) для безпечного доступу",[3843,13606,13607,3981,13610,13613],{},[3793,13608,13609],{},"Optional chaining",[3761,13611,13612],{},"?.",") дозволяє безпечно отримувати доступ до властивостей, які можуть не існувати:",[3847,13615,13617],{"className":3849,"code":13616,"language":3851,"meta":3852,"style":3852},"let user: { name: string; address?: { city: string } } | null = getUser();\n\n\u002F\u002F Без optional chaining:\nlet city1: string | undefined;\nif (user !== null && user.address !== undefined) {\n  city1 = user.address.city;\n}\n\n\u002F\u002F З optional chaining:\nlet city2 = user?.address?.city;\n\u002F\u002F Якщо user — null або user.address — undefined, повертається undefined\n\nconsole.log(city2);  \u002F\u002F string | undefined\n",[3761,13618,13619,13660,13664,13669,13686,13713,13732,13736,13740,13745,13766,13771,13775],{"__ignoreMap":3852},[3856,13620,13621,13623,13625,13627,13629,13631,13633,13635,13638,13641,13644,13646,13648,13651,13653,13655,13658],{"class":3858,"line":3859},[3856,13622,6494],{"class":3862},[3856,13624,7423],{"class":3874},[3856,13626,7545],{"class":3870},[3856,13628,5805],{"class":3874},[3856,13630,3878],{"class":3870},[3856,13632,3882],{"class":3881},[3856,13634,7556],{"class":3870},[3856,13636,13637],{"class":3874},"address",[3856,13639,13640],{"class":3870},"?: { ",[3856,13642,13643],{"class":3874},"city",[3856,13645,3878],{"class":3870},[3856,13647,3882],{"class":3881},[3856,13649,13650],{"class":3870}," } } | ",[3856,13652,5299],{"class":3881},[3856,13654,6507],{"class":3870},[3856,13656,13657],{"class":3866},"getUser",[3856,13659,4849],{"class":3870},[3856,13661,13662],{"class":3858,"line":3900},[3856,13663,4153],{"emptyLinePlaceholder":4152},[3856,13665,13666],{"class":3858,"line":3907},[3856,13667,13668],{"class":3903},"\u002F\u002F Без optional chaining:\n",[3856,13670,13671,13673,13676,13678,13680,13682,13684],{"class":3858,"line":3913},[3856,13672,6494],{"class":3862},[3856,13674,13675],{"class":3874}," city1",[3856,13677,3878],{"class":3870},[3856,13679,3882],{"class":3881},[3856,13681,3885],{"class":3870},[3856,13683,5139],{"class":3881},[3856,13685,4931],{"class":3870},[3856,13687,13688,13690,13692,13695,13697,13699,13701,13703,13705,13707,13709,13711],{"class":3858,"line":3919},[3856,13689,4200],{"class":4046},[3856,13691,3981],{"class":3870},[3856,13693,13694],{"class":3874},"user",[3856,13696,6027],{"class":3870},[3856,13698,5299],{"class":3862},[3856,13700,6032],{"class":3870},[3856,13702,13694],{"class":3874},[3856,13704,3925],{"class":3870},[3856,13706,13637],{"class":3874},[3856,13708,6027],{"class":3870},[3856,13710,5139],{"class":3862},[3856,13712,4064],{"class":3870},[3856,13714,13715,13718,13720,13722,13724,13726,13728,13730],{"class":3858,"line":3946},[3856,13716,13717],{"class":3874},"  city1",[3856,13719,6507],{"class":3870},[3856,13721,13694],{"class":3874},[3856,13723,3925],{"class":3870},[3856,13725,13637],{"class":3874},[3856,13727,3925],{"class":3870},[3856,13729,13643],{"class":3874},[3856,13731,4931],{"class":3870},[3856,13733,13734],{"class":3858,"line":3952},[3856,13735,3961],{"class":3870},[3856,13737,13738],{"class":3858,"line":3958},[3856,13739,4153],{"emptyLinePlaceholder":4152},[3856,13741,13742],{"class":3858,"line":4138},[3856,13743,13744],{"class":3903},"\u002F\u002F З optional chaining:\n",[3856,13746,13747,13749,13752,13754,13756,13758,13760,13762,13764],{"class":3858,"line":4144},[3856,13748,6494],{"class":3862},[3856,13750,13751],{"class":3874}," city2",[3856,13753,6507],{"class":3870},[3856,13755,13694],{"class":3874},[3856,13757,13612],{"class":3870},[3856,13759,13637],{"class":3874},[3856,13761,13612],{"class":3870},[3856,13763,13643],{"class":3874},[3856,13765,4931],{"class":3870},[3856,13767,13768],{"class":3858,"line":4149},[3856,13769,13770],{"class":3903},"\u002F\u002F Якщо user — null або user.address — undefined, повертається undefined\n",[3856,13772,13773],{"class":3858,"line":4156},[3856,13774,4153],{"emptyLinePlaceholder":4152},[3856,13776,13777,13779,13781,13783,13785,13788,13790],{"class":3858,"line":4173},[3856,13778,4524],{"class":3874},[3856,13780,3925],{"class":3870},[3856,13782,3928],{"class":3866},[3856,13784,3871],{"class":3870},[3856,13786,13787],{"class":3874},"city2",[3856,13789,4167],{"class":3870},[3856,13791,13792],{"class":3903},"\u002F\u002F string | undefined\n",[3843,13794,13795],{},[3793,13796,13797],{},"Optional chaining для методів:",[3847,13799,13801],{"className":3849,"code":13800,"language":3851,"meta":3852,"style":3852},"let user: { getName?: () => string } | null = getUser();\n\n\u002F\u002F Виклик методу через ?.\nlet name = user?.getName?.();\n\u002F\u002F Якщо user — null або getName — undefined, повертається undefined\n",[3761,13802,13803,13832,13836,13841,13859],{"__ignoreMap":3852},[3856,13804,13805,13807,13809,13811,13814,13817,13819,13821,13824,13826,13828,13830],{"class":3858,"line":3859},[3856,13806,6494],{"class":3862},[3856,13808,7423],{"class":3874},[3856,13810,7545],{"class":3870},[3856,13812,13813],{"class":3866},"getName",[3856,13815,13816],{"class":3870},"?: () ",[3856,13818,11398],{"class":3862},[3856,13820,6402],{"class":3881},[3856,13822,13823],{"class":3870}," } | ",[3856,13825,5299],{"class":3881},[3856,13827,6507],{"class":3870},[3856,13829,13657],{"class":3866},[3856,13831,4849],{"class":3870},[3856,13833,13834],{"class":3858,"line":3900},[3856,13835,4153],{"emptyLinePlaceholder":4152},[3856,13837,13838],{"class":3858,"line":3907},[3856,13839,13840],{"class":3903},"\u002F\u002F Виклик методу через ?.\n",[3856,13842,13843,13845,13848,13850,13852,13854,13856],{"class":3858,"line":3913},[3856,13844,6494],{"class":3862},[3856,13846,13847],{"class":3874}," name",[3856,13849,6507],{"class":3870},[3856,13851,13694],{"class":3874},[3856,13853,13612],{"class":3870},[3856,13855,13813],{"class":3866},[3856,13857,13858],{"class":3870},"?.();\n",[3856,13860,13861],{"class":3858,"line":3919},[3856,13862,13863],{"class":3903},"\u002F\u002F Якщо user — null або getName — undefined, повертається undefined\n",[3843,13865,13866],{},[3793,13867,13868],{},"Optional chaining для індексів:",[3847,13870,13872],{"className":3849,"code":13871,"language":3851,"meta":3852,"style":3852},"let users: string[] | null = getUsers();\n\nlet firstUser = users?.[0];\n\u002F\u002F Якщо users — null, повертається undefined\n",[3761,13873,13874,13897,13901,13920],{"__ignoreMap":3852},[3856,13875,13876,13878,13881,13883,13885,13888,13890,13892,13895],{"class":3858,"line":3859},[3856,13877,6494],{"class":3862},[3856,13879,13880],{"class":3874}," users",[3856,13882,3878],{"class":3870},[3856,13884,3882],{"class":3881},[3856,13886,13887],{"class":3870},"[] | ",[3856,13889,5299],{"class":3881},[3856,13891,6507],{"class":3870},[3856,13893,13894],{"class":3866},"getUsers",[3856,13896,4849],{"class":3870},[3856,13898,13899],{"class":3858,"line":3900},[3856,13900,4153],{"emptyLinePlaceholder":4152},[3856,13902,13903,13905,13908,13910,13913,13916,13918],{"class":3858,"line":3907},[3856,13904,6494],{"class":3862},[3856,13906,13907],{"class":3874}," firstUser",[3856,13909,6507],{"class":3870},[3856,13911,13912],{"class":3874},"users",[3856,13914,13915],{"class":3870},"?.[",[3856,13917,5550],{"class":4128},[3856,13919,12499],{"class":3870},[3856,13921,13922],{"class":3858,"line":3913},[3856,13923,13924],{"class":3903},"\u002F\u002F Якщо users — null, повертається undefined\n",[4214,13926,13928],{"alt":13927},"Control Flow Analysis: відстеження потоку виконання",[3847,13929,13931],{"className":4219,"code":13930,"language":4221,"meta":3852,"style":3852},"@startuml\nskinparam style plain\nskinparam backgroundColor #FFFFFF\n\nrectangle \"Початок:\\nx: string | number | null\" as Start #FCA5A5\n\nrectangle \"Перевірка 1:\\nx === null\" as Check1 #FBBF24\n\nrectangle \"Блок if:\\nx: null\\nreturn\" as Block1 #F87171\n\nrectangle \"Після return:\\nx: string | number\" as After1 #86EFAC\n\nrectangle \"Перевірка 2:\\ntypeof x === 'string'\" as Check2 #FBBF24\n\nrectangle \"Блок if:\\nx: string\\nreturn\" as Block2 #60A5FA\n\nrectangle \"Після return:\\nx: number\" as After2 #93C5FD\n\nStart -down-> Check1\nCheck1 -down-> Block1 : true\nCheck1 -down-> After1 : false\n\nAfter1 -down-> Check2\nCheck2 -down-> Block2 : true\nCheck2 -down-> After2 : false\n\nnote right of After1\n  TypeScript виключив null,\n  залишилось: string | number\nend note\n\nnote right of After2\n  TypeScript виключив string,\n  залишилось: number\nend note\n@enduml\n",[3761,13932,13933,13937,13941,13945,13949,13954,13958,13963,13967,13972,13976,13981,13985,13990,13994,13999,14003,14008,14012,14017,14022,14027,14031,14036,14041,14046,14050,14055,14060,14065,14069,14073,14078,14083,14088,14092],{"__ignoreMap":3852},[3856,13934,13935],{"class":3858,"line":3859},[3856,13936,4228],{},[3856,13938,13939],{"class":3858,"line":3900},[3856,13940,4233],{},[3856,13942,13943],{"class":3858,"line":3907},[3856,13944,4238],{},[3856,13946,13947],{"class":3858,"line":3913},[3856,13948,4153],{"emptyLinePlaceholder":4152},[3856,13950,13951],{"class":3858,"line":3919},[3856,13952,13953],{},"rectangle \"Початок:\\nx: string | number | null\" as Start #FCA5A5\n",[3856,13955,13956],{"class":3858,"line":3946},[3856,13957,4153],{"emptyLinePlaceholder":4152},[3856,13959,13960],{"class":3858,"line":3952},[3856,13961,13962],{},"rectangle \"Перевірка 1:\\nx === null\" as Check1 #FBBF24\n",[3856,13964,13965],{"class":3858,"line":3958},[3856,13966,4153],{"emptyLinePlaceholder":4152},[3856,13968,13969],{"class":3858,"line":4138},[3856,13970,13971],{},"rectangle \"Блок if:\\nx: null\\nreturn\" as Block1 #F87171\n",[3856,13973,13974],{"class":3858,"line":4144},[3856,13975,4153],{"emptyLinePlaceholder":4152},[3856,13977,13978],{"class":3858,"line":4149},[3856,13979,13980],{},"rectangle \"Після return:\\nx: string | number\" as After1 #86EFAC\n",[3856,13982,13983],{"class":3858,"line":4156},[3856,13984,4153],{"emptyLinePlaceholder":4152},[3856,13986,13987],{"class":3858,"line":4173},[3856,13988,13989],{},"rectangle \"Перевірка 2:\\ntypeof x === 'string'\" as Check2 #FBBF24\n",[3856,13991,13992],{"class":3858,"line":4288},[3856,13993,4153],{"emptyLinePlaceholder":4152},[3856,13995,13996],{"class":3858,"line":4293},[3856,13997,13998],{},"rectangle \"Блок if:\\nx: string\\nreturn\" as Block2 #60A5FA\n",[3856,14000,14001],{"class":3858,"line":4299},[3856,14002,4153],{"emptyLinePlaceholder":4152},[3856,14004,14005],{"class":3858,"line":4304},[3856,14006,14007],{},"rectangle \"Після return:\\nx: number\" as After2 #93C5FD\n",[3856,14009,14010],{"class":3858,"line":4310},[3856,14011,4153],{"emptyLinePlaceholder":4152},[3856,14013,14014],{"class":3858,"line":4316},[3856,14015,14016],{},"Start -down-> Check1\n",[3856,14018,14019],{"class":3858,"line":4322},[3856,14020,14021],{},"Check1 -down-> Block1 : true\n",[3856,14023,14024],{"class":3858,"line":4328},[3856,14025,14026],{},"Check1 -down-> After1 : false\n",[3856,14028,14029],{"class":3858,"line":4333},[3856,14030,4153],{"emptyLinePlaceholder":4152},[3856,14032,14033],{"class":3858,"line":4338},[3856,14034,14035],{},"After1 -down-> Check2\n",[3856,14037,14038],{"class":3858,"line":4343},[3856,14039,14040],{},"Check2 -down-> Block2 : true\n",[3856,14042,14043],{"class":3858,"line":4349},[3856,14044,14045],{},"Check2 -down-> After2 : false\n",[3856,14047,14048],{"class":3858,"line":4354},[3856,14049,4153],{"emptyLinePlaceholder":4152},[3856,14051,14052],{"class":3858,"line":4360},[3856,14053,14054],{},"note right of After1\n",[3856,14056,14057],{"class":3858,"line":4366},[3856,14058,14059],{},"  TypeScript виключив null,\n",[3856,14061,14062],{"class":3858,"line":4372},[3856,14063,14064],{},"  залишилось: string | number\n",[3856,14066,14067],{"class":3858,"line":4378},[3856,14068,4437],{},[3856,14070,14071],{"class":3858,"line":4383},[3856,14072,4153],{"emptyLinePlaceholder":4152},[3856,14074,14075],{"class":3858,"line":4388},[3856,14076,14077],{},"note right of After2\n",[3856,14079,14080],{"class":3858,"line":4393},[3856,14081,14082],{},"  TypeScript виключив string,\n",[3856,14084,14085],{"class":3858,"line":4399},[3856,14086,14087],{},"  залишилось: number\n",[3856,14089,14090],{"class":3858,"line":4405},[3856,14091,4437],{},[3856,14093,14094],{"class":3858,"line":4411},[3856,14095,4443],{},[3830,14097],{},[3833,14099,14101],{"id":14100},"assertion-functions","Assertion Functions",[3838,14103,14105],{"id":14104},"що-таке-assertion-function","Що таке assertion function",[3843,14107,14108,3981,14111,14114,14115,14118,14119,14122],{},[3793,14109,14110],{},"Assertion function",[3753,14112,14113],{},"функція-твердження",") — це функція, що ",[3793,14116,14117],{},"викидає помилку",", якщо умова не виконується. TypeScript розуміє, що після виклику такої функції умова ",[3793,14120,14121],{},"гарантовано"," виконана.",[3847,14124,14126],{"className":3849,"code":14125,"language":3851,"meta":3852,"style":3852},"function assert(condition: unknown, message?: string): asserts condition {\n  if (!condition) {\n    throw new Error(message || \"Assertion failed\");\n  }\n}\n\nfunction processValue(value: string | null): void {\n  assert(value !== null, \"Value must not be null\");\n  \n  \u002F\u002F Після assert TypeScript ЗНАЄ, що value не null\n  console.log(value.toUpperCase());  \u002F\u002F OK: value: string\n}\n\nprocessValue(\"hello\");  \u002F\u002F \"HELLO\"\nprocessValue(null);     \u002F\u002F Error: Value must not be null\n",[3761,14127,14128,14161,14172,14192,14196,14200,14204,14228,14248,14252,14257,14278,14282,14286,14298],{"__ignoreMap":3852},[3856,14129,14130,14132,14135,14137,14140,14142,14144,14146,14149,14152,14154,14157,14159],{"class":3858,"line":3859},[3856,14131,3863],{"class":3862},[3856,14133,14134],{"class":3866}," assert",[3856,14136,3871],{"class":3870},[3856,14138,14139],{"class":3874},"condition",[3856,14141,3878],{"class":3870},[3856,14143,8921],{"class":3881},[3856,14145,3764],{"class":3870},[3856,14147,14148],{"class":3874},"message",[3856,14150,14151],{"class":3870},"?: ",[3856,14153,3882],{"class":3881},[3856,14155,14156],{"class":3870},"): asserts ",[3856,14158,14139],{"class":3874},[3856,14160,3897],{"class":3870},[3856,14162,14163,14165,14168,14170],{"class":3858,"line":3900},[3856,14164,4047],{"class":4046},[3856,14166,14167],{"class":3870}," (!",[3856,14169,14139],{"class":3874},[3856,14171,4064],{"class":3870},[3856,14173,14174,14177,14179,14181,14183,14185,14187,14190],{"class":3858,"line":3907},[3856,14175,14176],{"class":4046},"    throw",[3856,14178,7351],{"class":3862},[3856,14180,7354],{"class":3866},[3856,14182,3871],{"class":3870},[3856,14184,14148],{"class":3874},[3856,14186,13301],{"class":3870},[3856,14188,14189],{"class":4060},"\"Assertion failed\"",[3856,14191,4896],{"class":3870},[3856,14193,14194],{"class":3858,"line":3913},[3856,14195,4141],{"class":3870},[3856,14197,14198],{"class":3858,"line":3919},[3856,14199,3961],{"class":3870},[3856,14201,14202],{"class":3858,"line":3946},[3856,14203,4153],{"emptyLinePlaceholder":4152},[3856,14205,14206,14208,14210,14212,14214,14216,14218,14220,14222,14224,14226],{"class":3858,"line":3952},[3856,14207,3863],{"class":3862},[3856,14209,3867],{"class":3866},[3856,14211,3871],{"class":3870},[3856,14213,3875],{"class":3874},[3856,14215,3878],{"class":3870},[3856,14217,3882],{"class":3881},[3856,14219,3885],{"class":3870},[3856,14221,5299],{"class":3881},[3856,14223,3891],{"class":3870},[3856,14225,3894],{"class":3881},[3856,14227,3897],{"class":3870},[3856,14229,14230,14233,14235,14237,14239,14241,14243,14246],{"class":3858,"line":3958},[3856,14231,14232],{"class":3866},"  assert",[3856,14234,3871],{"class":3870},[3856,14236,3875],{"class":3874},[3856,14238,6027],{"class":3870},[3856,14240,5299],{"class":3862},[3856,14242,3764],{"class":3870},[3856,14244,14245],{"class":4060},"\"Value must not be null\"",[3856,14247,4896],{"class":3870},[3856,14249,14250],{"class":3858,"line":4138},[3856,14251,3916],{"class":3870},[3856,14253,14254],{"class":3858,"line":4144},[3856,14255,14256],{"class":3903},"  \u002F\u002F Після assert TypeScript ЗНАЄ, що value не null\n",[3856,14258,14259,14261,14263,14265,14267,14269,14271,14273,14275],{"class":3858,"line":4149},[3856,14260,3922],{"class":3874},[3856,14262,3925],{"class":3870},[3856,14264,3928],{"class":3866},[3856,14266,3871],{"class":3870},[3856,14268,3875],{"class":3874},[3856,14270,3925],{"class":3870},[3856,14272,3937],{"class":3866},[3856,14274,3940],{"class":3870},[3856,14276,14277],{"class":3903},"\u002F\u002F OK: value: string\n",[3856,14279,14280],{"class":3858,"line":4156},[3856,14281,3961],{"class":3870},[3856,14283,14284],{"class":3858,"line":4173},[3856,14285,4153],{"emptyLinePlaceholder":4152},[3856,14287,14288,14290,14292,14294,14296],{"class":3858,"line":4288},[3856,14289,4159],{"class":3866},[3856,14291,3871],{"class":3870},[3856,14293,4164],{"class":4060},[3856,14295,4167],{"class":3870},[3856,14297,4962],{"class":3903},[3856,14299,14300,14302,14304,14306,14308],{"class":3858,"line":4293},[3856,14301,4159],{"class":3866},[3856,14303,3871],{"class":3870},[3856,14305,5299],{"class":3862},[3856,14307,4600],{"class":3870},[3856,14309,14310],{"class":3903},"\u002F\u002F Error: Value must not be null\n",[3843,14312,14313],{},[3793,14314,11162],{},[3847,14316,14318],{"className":3849,"code":14317,"language":3851,"meta":3852,"style":3852},"function assertCondition(condition: unknown): asserts condition {\n  if (!condition) {\n    throw new Error(\"Assertion failed\");\n  }\n}\n",[3761,14319,14320,14341,14351,14365,14369],{"__ignoreMap":3852},[3856,14321,14322,14324,14327,14329,14331,14333,14335,14337,14339],{"class":3858,"line":3859},[3856,14323,3863],{"class":3862},[3856,14325,14326],{"class":3866}," assertCondition",[3856,14328,3871],{"class":3870},[3856,14330,14139],{"class":3874},[3856,14332,3878],{"class":3870},[3856,14334,8921],{"class":3881},[3856,14336,14156],{"class":3870},[3856,14338,14139],{"class":3874},[3856,14340,3897],{"class":3870},[3856,14342,14343,14345,14347,14349],{"class":3858,"line":3900},[3856,14344,4047],{"class":4046},[3856,14346,14167],{"class":3870},[3856,14348,14139],{"class":3874},[3856,14350,4064],{"class":3870},[3856,14352,14353,14355,14357,14359,14361,14363],{"class":3858,"line":3907},[3856,14354,14176],{"class":4046},[3856,14356,7351],{"class":3862},[3856,14358,7354],{"class":3866},[3856,14360,3871],{"class":3870},[3856,14362,14189],{"class":4060},[3856,14364,4896],{"class":3870},[3856,14366,14367],{"class":3858,"line":3913},[3856,14368,4141],{"class":3870},[3856,14370,14371],{"class":3858,"line":3919},[3856,14372,3961],{"class":3870},[3746,14374,14375],{},[3749,14376,14377,14380,14381,14383],{},[3761,14378,14379],{},"asserts condition"," — це спеціальний тип повернення, що каже TypeScript: \"якщо функція не викинула помилку, то ",[3761,14382,14139],{}," — true\"",[3838,14385,14387],{"id":14386},"assertion-function-з-конкретним-типом","Assertion function з конкретним типом",[3843,14389,14390,14391,14394],{},"Assertion function може ",[3793,14392,14393],{},"звужувати"," тип параметра:",[3847,14396,14398],{"className":3849,"code":14397,"language":3851,"meta":3852,"style":3852},"function assertIsString(value: unknown): asserts value is string {\n  if (typeof value !== \"string\") {\n    throw new Error(`Expected string, got ${typeof value}`);\n  }\n}\n\nfunction processValue(value: unknown): void {\n  assertIsString(value);\n  \n  \u002F\u002F Після assertIsString TypeScript ЗНАЄ, що value — string\n  console.log(value.toUpperCase());  \u002F\u002F OK\n}\n\nprocessValue(\"hello\");  \u002F\u002F \"HELLO\"\nprocessValue(42);       \u002F\u002F Error: Expected string, got number\n",[3761,14399,14400,14425,14441,14466,14470,14474,14478,14498,14509,14513,14518,14538,14542,14546,14558],{"__ignoreMap":3852},[3856,14401,14402,14404,14407,14409,14411,14413,14415,14417,14419,14421,14423],{"class":3858,"line":3859},[3856,14403,3863],{"class":3862},[3856,14405,14406],{"class":3866}," assertIsString",[3856,14408,3871],{"class":3870},[3856,14410,3875],{"class":3874},[3856,14412,3878],{"class":3870},[3856,14414,8921],{"class":3881},[3856,14416,14156],{"class":3870},[3856,14418,3875],{"class":3874},[3856,14420,6399],{"class":3862},[3856,14422,6402],{"class":3881},[3856,14424,3897],{"class":3870},[3856,14426,14427,14429,14431,14433,14435,14437,14439],{"class":3858,"line":3900},[3856,14428,4047],{"class":4046},[3856,14430,3981],{"class":3870},[3856,14432,3763],{"class":3862},[3856,14434,4054],{"class":3874},[3856,14436,6027],{"class":3870},[3856,14438,4061],{"class":4060},[3856,14440,4064],{"class":3870},[3856,14442,14443,14445,14447,14449,14451,14454,14456,14458,14460,14462,14464],{"class":3858,"line":3907},[3856,14444,14176],{"class":4046},[3856,14446,7351],{"class":3862},[3856,14448,7354],{"class":3866},[3856,14450,3871],{"class":3870},[3856,14452,14453],{"class":4060},"`Expected string, got ",[3856,14455,5238],{"class":3862},[3856,14457,3763],{"class":3862},[3856,14459,4054],{"class":3874},[3856,14461,5249],{"class":3862},[3856,14463,5252],{"class":4060},[3856,14465,4896],{"class":3870},[3856,14467,14468],{"class":3858,"line":3913},[3856,14469,4141],{"class":3870},[3856,14471,14472],{"class":3858,"line":3919},[3856,14473,3961],{"class":3870},[3856,14475,14476],{"class":3858,"line":3946},[3856,14477,4153],{"emptyLinePlaceholder":4152},[3856,14479,14480,14482,14484,14486,14488,14490,14492,14494,14496],{"class":3858,"line":3952},[3856,14481,3863],{"class":3862},[3856,14483,3867],{"class":3866},[3856,14485,3871],{"class":3870},[3856,14487,3875],{"class":3874},[3856,14489,3878],{"class":3870},[3856,14491,8921],{"class":3881},[3856,14493,3891],{"class":3870},[3856,14495,3894],{"class":3881},[3856,14497,3897],{"class":3870},[3856,14499,14500,14503,14505,14507],{"class":3858,"line":3958},[3856,14501,14502],{"class":3866},"  assertIsString",[3856,14504,3871],{"class":3870},[3856,14506,3875],{"class":3874},[3856,14508,4896],{"class":3870},[3856,14510,14511],{"class":3858,"line":4138},[3856,14512,3916],{"class":3870},[3856,14514,14515],{"class":3858,"line":4144},[3856,14516,14517],{"class":3903},"  \u002F\u002F Після assertIsString TypeScript ЗНАЄ, що value — string\n",[3856,14519,14520,14522,14524,14526,14528,14530,14532,14534,14536],{"class":3858,"line":4149},[3856,14521,3922],{"class":3874},[3856,14523,3925],{"class":3870},[3856,14525,3928],{"class":3866},[3856,14527,3871],{"class":3870},[3856,14529,3875],{"class":3874},[3856,14531,3925],{"class":3870},[3856,14533,3937],{"class":3866},[3856,14535,3940],{"class":3870},[3856,14537,6666],{"class":3903},[3856,14539,14540],{"class":3858,"line":4156},[3856,14541,3961],{"class":3870},[3856,14543,14544],{"class":3858,"line":4173},[3856,14545,4153],{"emptyLinePlaceholder":4152},[3856,14547,14548,14550,14552,14554,14556],{"class":3858,"line":4288},[3856,14549,4159],{"class":3866},[3856,14551,3871],{"class":3870},[3856,14553,4164],{"class":4060},[3856,14555,4167],{"class":3870},[3856,14557,4962],{"class":3903},[3856,14559,14560,14562,14564,14566,14568],{"class":3858,"line":4293},[3856,14561,4159],{"class":3866},[3856,14563,3871],{"class":3870},[3856,14565,4180],{"class":4128},[3856,14567,4183],{"class":3870},[3856,14569,14570],{"class":3903},"\u002F\u002F Error: Expected string, got number\n",[3838,14572,14574],{"id":14573},"приклад-assert-для-nullundefined","Приклад: assert для null\u002Fundefined",[3847,14576,14578],{"className":3849,"code":14577,"language":3851,"meta":3852,"style":3852},"function assertNotNull\u003CT>(value: T | null | undefined, message?: string): asserts value is T {\n  if (value === null || value === undefined) {\n    throw new Error(message || \"Value is null or undefined\");\n  }\n}\n\nfunction getUser(id: number): { name: string } | null {\n  \u002F\u002F Імітація запиту до бази\n  if (id === 1) {\n    return { name: \"Alice\" };\n  }\n  return null;\n}\n\nfunction processUser(id: number): void {\n  let user = getUser(id);\n  \n  \u002F\u002F Тут user: { name: string } | null\n  \n  assertNotNull(user, `User with id ${id} not found`);\n  \n  \u002F\u002F Після assertNotNull TypeScript ЗНАЄ, що user не null\n  console.log(user.name.toUpperCase());  \u002F\u002F OK\n}\n\nprocessUser(1);  \u002F\u002F \"ALICE\"\nprocessUser(2);  \u002F\u002F Error: User with id 2 not found\n",[3761,14579,14580,14625,14647,14666,14670,14674,14678,14709,14714,14728,14740,14744,14752,14756,14760,14781,14797,14801,14806,14810,14835,14839,14844,14868,14872,14876,14890],{"__ignoreMap":3852},[3856,14581,14582,14584,14587,14589,14591,14593,14595,14597,14599,14601,14603,14605,14607,14609,14611,14613,14615,14617,14619,14621,14623],{"class":3858,"line":3859},[3856,14583,3863],{"class":3862},[3856,14585,14586],{"class":3866}," assertNotNull",[3856,14588,11906],{"class":3870},[3856,14590,11909],{"class":3881},[3856,14592,11912],{"class":3870},[3856,14594,3875],{"class":3874},[3856,14596,3878],{"class":3870},[3856,14598,11909],{"class":3881},[3856,14600,3885],{"class":3870},[3856,14602,5299],{"class":3881},[3856,14604,3885],{"class":3870},[3856,14606,5139],{"class":3881},[3856,14608,3764],{"class":3870},[3856,14610,14148],{"class":3874},[3856,14612,14151],{"class":3870},[3856,14614,3882],{"class":3881},[3856,14616,14156],{"class":3870},[3856,14618,3875],{"class":3874},[3856,14620,6399],{"class":3862},[3856,14622,11935],{"class":3881},[3856,14624,3897],{"class":3870},[3856,14626,14627,14629,14631,14633,14635,14637,14639,14641,14643,14645],{"class":3858,"line":3900},[3856,14628,4047],{"class":4046},[3856,14630,3981],{"class":3870},[3856,14632,3875],{"class":3874},[3856,14634,4057],{"class":3870},[3856,14636,5299],{"class":3862},[3856,14638,13301],{"class":3870},[3856,14640,3875],{"class":3874},[3856,14642,4057],{"class":3870},[3856,14644,5139],{"class":3862},[3856,14646,4064],{"class":3870},[3856,14648,14649,14651,14653,14655,14657,14659,14661,14664],{"class":3858,"line":3907},[3856,14650,14176],{"class":4046},[3856,14652,7351],{"class":3862},[3856,14654,7354],{"class":3866},[3856,14656,3871],{"class":3870},[3856,14658,14148],{"class":3874},[3856,14660,13301],{"class":3870},[3856,14662,14663],{"class":4060},"\"Value is null or undefined\"",[3856,14665,4896],{"class":3870},[3856,14667,14668],{"class":3858,"line":3913},[3856,14669,4141],{"class":3870},[3856,14671,14672],{"class":3858,"line":3919},[3856,14673,3961],{"class":3870},[3856,14675,14676],{"class":3858,"line":3946},[3856,14677,4153],{"emptyLinePlaceholder":4152},[3856,14679,14680,14682,14685,14687,14690,14692,14694,14697,14699,14701,14703,14705,14707],{"class":3858,"line":3952},[3856,14681,3863],{"class":3862},[3856,14683,14684],{"class":3866}," getUser",[3856,14686,3871],{"class":3870},[3856,14688,14689],{"class":3874},"id",[3856,14691,3878],{"class":3870},[3856,14693,3888],{"class":3881},[3856,14695,14696],{"class":3870},"): { ",[3856,14698,5805],{"class":3874},[3856,14700,3878],{"class":3870},[3856,14702,3882],{"class":3881},[3856,14704,13823],{"class":3870},[3856,14706,5299],{"class":3881},[3856,14708,3897],{"class":3870},[3856,14710,14711],{"class":3858,"line":3958},[3856,14712,14713],{"class":3903},"  \u002F\u002F Імітація запиту до бази\n",[3856,14715,14716,14718,14720,14722,14724,14726],{"class":3858,"line":4138},[3856,14717,4047],{"class":4046},[3856,14719,3981],{"class":3870},[3856,14721,14689],{"class":3874},[3856,14723,4057],{"class":3870},[3856,14725,5607],{"class":4128},[3856,14727,4064],{"class":3870},[3856,14729,14730,14732,14734,14736,14738],{"class":3858,"line":4144},[3856,14731,4840],{"class":4046},[3856,14733,10473],{"class":3870},[3856,14735,7429],{"class":3874},[3856,14737,7432],{"class":4060},[3856,14739,7443],{"class":3870},[3856,14741,14742],{"class":3858,"line":4149},[3856,14743,4141],{"class":3870},[3856,14745,14746,14748,14750],{"class":3858,"line":4156},[3856,14747,4914],{"class":4046},[3856,14749,4703],{"class":3862},[3856,14751,4931],{"class":3870},[3856,14753,14754],{"class":3858,"line":4173},[3856,14755,3961],{"class":3870},[3856,14757,14758],{"class":3858,"line":4288},[3856,14759,4153],{"emptyLinePlaceholder":4152},[3856,14761,14762,14764,14767,14769,14771,14773,14775,14777,14779],{"class":3858,"line":4293},[3856,14763,3863],{"class":3862},[3856,14765,14766],{"class":3866}," processUser",[3856,14768,3871],{"class":3870},[3856,14770,14689],{"class":3874},[3856,14772,3878],{"class":3870},[3856,14774,3888],{"class":3881},[3856,14776,3891],{"class":3870},[3856,14778,3894],{"class":3881},[3856,14780,3897],{"class":3870},[3856,14782,14783,14785,14787,14789,14791,14793,14795],{"class":3858,"line":4299},[3856,14784,12007],{"class":3862},[3856,14786,7423],{"class":3874},[3856,14788,6507],{"class":3870},[3856,14790,13657],{"class":3866},[3856,14792,3871],{"class":3870},[3856,14794,14689],{"class":3874},[3856,14796,4896],{"class":3870},[3856,14798,14799],{"class":3858,"line":4304},[3856,14800,3916],{"class":3870},[3856,14802,14803],{"class":3858,"line":4310},[3856,14804,14805],{"class":3903},"  \u002F\u002F Тут user: { name: string } | null\n",[3856,14807,14808],{"class":3858,"line":4316},[3856,14809,3916],{"class":3870},[3856,14811,14812,14815,14817,14819,14821,14824,14826,14828,14830,14833],{"class":3858,"line":4322},[3856,14813,14814],{"class":3866},"  assertNotNull",[3856,14816,3871],{"class":3870},[3856,14818,13694],{"class":3874},[3856,14820,3764],{"class":3870},[3856,14822,14823],{"class":4060},"`User with id ",[3856,14825,5238],{"class":3862},[3856,14827,14689],{"class":3874},[3856,14829,5249],{"class":3862},[3856,14831,14832],{"class":4060}," not found`",[3856,14834,4896],{"class":3870},[3856,14836,14837],{"class":3858,"line":4328},[3856,14838,3916],{"class":3870},[3856,14840,14841],{"class":3858,"line":4333},[3856,14842,14843],{"class":3903},"  \u002F\u002F Після assertNotNull TypeScript ЗНАЄ, що user не null\n",[3856,14845,14846,14848,14850,14852,14854,14856,14858,14860,14862,14864,14866],{"class":3858,"line":4338},[3856,14847,3922],{"class":3874},[3856,14849,3925],{"class":3870},[3856,14851,3928],{"class":3866},[3856,14853,3871],{"class":3870},[3856,14855,13694],{"class":3874},[3856,14857,3925],{"class":3870},[3856,14859,5805],{"class":3874},[3856,14861,3925],{"class":3870},[3856,14863,3937],{"class":3866},[3856,14865,3940],{"class":3870},[3856,14867,6666],{"class":3903},[3856,14869,14870],{"class":3858,"line":4343},[3856,14871,3961],{"class":3870},[3856,14873,14874],{"class":3858,"line":4349},[3856,14875,4153],{"emptyLinePlaceholder":4152},[3856,14877,14878,14881,14883,14885,14887],{"class":3858,"line":4354},[3856,14879,14880],{"class":3866},"processUser",[3856,14882,3871],{"class":3870},[3856,14884,5607],{"class":4128},[3856,14886,4167],{"class":3870},[3856,14888,14889],{"class":3903},"\u002F\u002F \"ALICE\"\n",[3856,14891,14892,14894,14896,14898,14900],{"class":3858,"line":4360},[3856,14893,14880],{"class":3866},[3856,14895,3871],{"class":3870},[3856,14897,4129],{"class":4128},[3856,14899,4167],{"class":3870},[3856,14901,14902],{"class":3903},"\u002F\u002F Error: User with id 2 not found\n",[3838,14904,14906],{"id":14905},"різниця-між-type-guard-та-assertion-function","Різниця між type guard та assertion function",[3843,14908,14909,14912],{},[3793,14910,14911],{},"Type guard"," повертає boolean та дозволяє обробити обидва випадки (true\u002Ffalse):",[3847,14914,14916],{"className":3849,"code":14915,"language":3851,"meta":3852,"style":3852},"function isString(value: unknown): value is string {\n  return typeof value === \"string\";\n}\n\nif (isString(value)) {\n  \u002F\u002F значення — string\n} else {\n  \u002F\u002F значення — не string\n}\n",[3761,14917,14918,14942,14956,14960,14964,14978,14983,14991,14996],{"__ignoreMap":3852},[3856,14919,14920,14922,14924,14926,14928,14930,14932,14934,14936,14938,14940],{"class":3858,"line":3859},[3856,14921,3863],{"class":3862},[3856,14923,11011],{"class":3866},[3856,14925,3871],{"class":3870},[3856,14927,3875],{"class":3874},[3856,14929,3878],{"class":3870},[3856,14931,8921],{"class":3881},[3856,14933,3891],{"class":3870},[3856,14935,3875],{"class":3874},[3856,14937,6399],{"class":3862},[3856,14939,6402],{"class":3881},[3856,14941,3897],{"class":3870},[3856,14943,14944,14946,14948,14950,14952,14954],{"class":3858,"line":3900},[3856,14945,4914],{"class":4046},[3856,14947,11036],{"class":3862},[3856,14949,4054],{"class":3874},[3856,14951,4057],{"class":3870},[3856,14953,4061],{"class":4060},[3856,14955,4931],{"class":3870},[3856,14957,14958],{"class":3858,"line":3907},[3856,14959,3961],{"class":3870},[3856,14961,14962],{"class":3858,"line":3913},[3856,14963,4153],{"emptyLinePlaceholder":4152},[3856,14965,14966,14968,14970,14972,14974,14976],{"class":3858,"line":3919},[3856,14967,4200],{"class":4046},[3856,14969,3981],{"class":3870},[3856,14971,11085],{"class":3866},[3856,14973,3871],{"class":3870},[3856,14975,3875],{"class":3874},[3856,14977,6531],{"class":3870},[3856,14979,14980],{"class":3858,"line":3946},[3856,14981,14982],{"class":3903},"  \u002F\u002F значення — string\n",[3856,14984,14985,14987,14989],{"class":3858,"line":3952},[3856,14986,12716],{"class":3870},[3856,14988,4099],{"class":4046},[3856,14990,3897],{"class":3870},[3856,14992,14993],{"class":3858,"line":3958},[3856,14994,14995],{"class":3903},"  \u002F\u002F значення — не string\n",[3856,14997,14998],{"class":3858,"line":4138},[3856,14999,3961],{"class":3870},[3843,15001,15002,15004,15005,4737],{},[3793,15003,14110],{}," викидає помилку і не повертає нічого. Використовується, коли невиконання умови — це ",[3793,15006,15007],{},"помилка програми",[3847,15009,15011],{"className":3849,"code":15010,"language":3851,"meta":3852,"style":3852},"function assertString(value: unknown): asserts value is string {\n  if (typeof value !== \"string\") {\n    throw new Error(\"Expected string\");\n  }\n}\n\nassertString(value);  \u002F\u002F якщо не string — програма зупиняється\n\u002F\u002F далі value гарантовано string\n",[3761,15012,15013,15038,15054,15069,15073,15077,15081,15095],{"__ignoreMap":3852},[3856,15014,15015,15017,15020,15022,15024,15026,15028,15030,15032,15034,15036],{"class":3858,"line":3859},[3856,15016,3863],{"class":3862},[3856,15018,15019],{"class":3866}," assertString",[3856,15021,3871],{"class":3870},[3856,15023,3875],{"class":3874},[3856,15025,3878],{"class":3870},[3856,15027,8921],{"class":3881},[3856,15029,14156],{"class":3870},[3856,15031,3875],{"class":3874},[3856,15033,6399],{"class":3862},[3856,15035,6402],{"class":3881},[3856,15037,3897],{"class":3870},[3856,15039,15040,15042,15044,15046,15048,15050,15052],{"class":3858,"line":3900},[3856,15041,4047],{"class":4046},[3856,15043,3981],{"class":3870},[3856,15045,3763],{"class":3862},[3856,15047,4054],{"class":3874},[3856,15049,6027],{"class":3870},[3856,15051,4061],{"class":4060},[3856,15053,4064],{"class":3870},[3856,15055,15056,15058,15060,15062,15064,15067],{"class":3858,"line":3907},[3856,15057,14176],{"class":4046},[3856,15059,7351],{"class":3862},[3856,15061,7354],{"class":3866},[3856,15063,3871],{"class":3870},[3856,15065,15066],{"class":4060},"\"Expected string\"",[3856,15068,4896],{"class":3870},[3856,15070,15071],{"class":3858,"line":3913},[3856,15072,4141],{"class":3870},[3856,15074,15075],{"class":3858,"line":3919},[3856,15076,3961],{"class":3870},[3856,15078,15079],{"class":3858,"line":3946},[3856,15080,4153],{"emptyLinePlaceholder":4152},[3856,15082,15083,15086,15088,15090,15092],{"class":3858,"line":3952},[3856,15084,15085],{"class":3866},"assertString",[3856,15087,3871],{"class":3870},[3856,15089,3875],{"class":3874},[3856,15091,4167],{"class":3870},[3856,15093,15094],{"class":3903},"\u002F\u002F якщо не string — програма зупиняється\n",[3856,15096,15097],{"class":3858,"line":3958},[3856,15098,15099],{"class":3903},"\u002F\u002F далі value гарантовано string\n",[6259,15101,15102,15109],{},[3843,15103,15104,15105,15108],{},"Використовуйте ",[3793,15106,15107],{},"type guards"," для очікуваних варіантів (валідація користувацьких даних, обробка різних форматів).",[3843,15110,15104,15111,15114],{},[3793,15112,15113],{},"assertion functions"," для інваріантів програми, які повинні завжди виконуватися (перевірка внутрішніх станів, налагодження).",[3830,15116],{},[3833,15118,15120],{"id":15119},"практичні-патерни-та-приклади","Практичні патерни та приклади",[3838,15122,15124],{"id":15123},"патерн-1-валідація-форми-з-discriminated-union","Патерн 1: Валідація форми з discriminated union",[3847,15126,15128],{"className":3849,"code":15127,"language":3851,"meta":3852,"style":3852},"type ValidationSuccess = {\n  status: \"success\";\n  data: { username: string; email: string };\n};\n\ntype ValidationError = {\n  status: \"error\";\n  errors: { field: string; message: string }[];\n};\n\ntype ValidationResult = ValidationSuccess | ValidationError;\n\nfunction validateForm(input: { username?: string; email?: string }): ValidationResult {\n  let errors: { field: string; message: string }[] = [];\n  \n  if (!input.username || input.username.length \u003C 3) {\n    errors.push({ field: \"username\", message: \"Username must be at least 3 characters\" });\n  }\n  \n  if (!input.email || !input.email.includes(\"@\")) {\n    errors.push({ field: \"email\", message: \"Invalid email format\" });\n  }\n  \n  if (errors.length > 0) {\n    return { status: \"error\", errors };\n  }\n  \n  return {\n    status: \"success\",\n    data: {\n      username: input.username!,  \u002F\u002F тут точно є значення\n      email: input.email!\n    }\n  };\n}\n\nfunction handleForm(input: { username?: string; email?: string }): void {\n  let result = validateForm(input);\n  \n  if (result.status === \"error\") {\n    \u002F\u002F Тут result: ValidationError\n    console.error(\"Validation failed:\");\n    result.errors.forEach(err => {\n      console.error(`  ${err.field}: ${err.message}`);\n    });\n  } else {\n    \u002F\u002F Тут result: ValidationSuccess\n    console.log(\"Form is valid!\");\n    console.log(`Username: ${result.data.username}`);\n    console.log(`Email: ${result.data.email}`);\n  }\n}\n\nhandleForm({ username: \"al\", email: \"invalid\" });\n\u002F\u002F Validation failed:\n\u002F\u002F   username: Username must be at least 3 characters\n\u002F\u002F   email: Invalid email format\n\nhandleForm({ username: \"alice\", email: \"alice@example.com\" });\n\u002F\u002F Form is valid!\n\u002F\u002F Username: alice\n\u002F\u002F Email: alice@example.com\n",[3761,15129,15130,15139,15149,15172,15176,15180,15189,15199,15224,15228,15232,15251,15255,15289,15315,15319,15350,15378,15382,15386,15419,15443,15447,15451,15471,15487,15491,15495,15501,15510,15517,15535,15549,15554,15559,15563,15567,15600,15618,15622,15640,15645,15660,15682,15722,15728,15737,15743,15759,15791,15822,15827,15832,15837,15860,15866,15872,15878,15883,15903,15909,15915],{"__ignoreMap":3852},[3856,15131,15132,15134,15137],{"class":3858,"line":3859},[3856,15133,9570],{"class":3862},[3856,15135,15136],{"class":3881}," ValidationSuccess",[3856,15138,9576],{"class":3870},[3856,15140,15141,15143,15145,15147],{"class":3858,"line":3900},[3856,15142,10327],{"class":3874},[3856,15144,3878],{"class":3870},[3856,15146,6768],{"class":4060},[3856,15148,4931],{"class":3870},[3856,15150,15151,15153,15155,15158,15160,15162,15164,15166,15168,15170],{"class":3858,"line":3907},[3856,15152,10338],{"class":3874},[3856,15154,7545],{"class":3870},[3856,15156,15157],{"class":3874},"username",[3856,15159,3878],{"class":3870},[3856,15161,3882],{"class":3881},[3856,15163,7556],{"class":3870},[3856,15165,7788],{"class":3874},[3856,15167,3878],{"class":3870},[3856,15169,3882],{"class":3881},[3856,15171,7443],{"class":3870},[3856,15173,15174],{"class":3858,"line":3913},[3856,15175,9607],{"class":3870},[3856,15177,15178],{"class":3858,"line":3919},[3856,15179,4153],{"emptyLinePlaceholder":4152},[3856,15181,15182,15184,15187],{"class":3858,"line":3946},[3856,15183,9570],{"class":3862},[3856,15185,15186],{"class":3881}," ValidationError",[3856,15188,9576],{"class":3870},[3856,15190,15191,15193,15195,15197],{"class":3858,"line":3952},[3856,15192,10327],{"class":3874},[3856,15194,3878],{"class":3870},[3856,15196,6773],{"class":4060},[3856,15198,4931],{"class":3870},[3856,15200,15201,15204,15206,15209,15211,15213,15215,15217,15219,15221],{"class":3858,"line":3958},[3856,15202,15203],{"class":3874},"  errors",[3856,15205,7545],{"class":3870},[3856,15207,15208],{"class":3874},"field",[3856,15210,3878],{"class":3870},[3856,15212,3882],{"class":3881},[3856,15214,7556],{"class":3870},[3856,15216,14148],{"class":3874},[3856,15218,3878],{"class":3870},[3856,15220,3882],{"class":3881},[3856,15222,15223],{"class":3870}," }[];\n",[3856,15225,15226],{"class":3858,"line":4138},[3856,15227,9607],{"class":3870},[3856,15229,15230],{"class":3858,"line":4144},[3856,15231,4153],{"emptyLinePlaceholder":4152},[3856,15233,15234,15236,15239,15241,15244,15246,15249],{"class":3858,"line":4149},[3856,15235,9570],{"class":3862},[3856,15237,15238],{"class":3881}," ValidationResult",[3856,15240,6507],{"class":3870},[3856,15242,15243],{"class":3881},"ValidationSuccess",[3856,15245,3885],{"class":3870},[3856,15247,15248],{"class":3881},"ValidationError",[3856,15250,4931],{"class":3870},[3856,15252,15253],{"class":3858,"line":4156},[3856,15254,4153],{"emptyLinePlaceholder":4152},[3856,15256,15257,15259,15262,15264,15266,15268,15270,15272,15274,15276,15278,15280,15282,15284,15287],{"class":3858,"line":4173},[3856,15258,3863],{"class":3862},[3856,15260,15261],{"class":3866}," validateForm",[3856,15263,3871],{"class":3870},[3856,15265,10906],{"class":3874},[3856,15267,7545],{"class":3870},[3856,15269,15157],{"class":3874},[3856,15271,14151],{"class":3870},[3856,15273,3882],{"class":3881},[3856,15275,7556],{"class":3870},[3856,15277,7788],{"class":3874},[3856,15279,14151],{"class":3870},[3856,15281,3882],{"class":3881},[3856,15283,7585],{"class":3870},[3856,15285,15286],{"class":3881},"ValidationResult",[3856,15288,3897],{"class":3870},[3856,15290,15291,15293,15296,15298,15300,15302,15304,15306,15308,15310,15312],{"class":3858,"line":4288},[3856,15292,12007],{"class":3862},[3856,15294,15295],{"class":3874}," errors",[3856,15297,7545],{"class":3870},[3856,15299,15208],{"class":3874},[3856,15301,3878],{"class":3870},[3856,15303,3882],{"class":3881},[3856,15305,7556],{"class":3870},[3856,15307,14148],{"class":3874},[3856,15309,3878],{"class":3870},[3856,15311,3882],{"class":3881},[3856,15313,15314],{"class":3870}," }[] = [];\n",[3856,15316,15317],{"class":3858,"line":4293},[3856,15318,3916],{"class":3870},[3856,15320,15321,15323,15325,15327,15329,15331,15333,15335,15337,15339,15341,15343,15346,15348],{"class":3858,"line":4299},[3856,15322,4047],{"class":4046},[3856,15324,14167],{"class":3870},[3856,15326,10906],{"class":3874},[3856,15328,3925],{"class":3870},[3856,15330,15157],{"class":3874},[3856,15332,13301],{"class":3870},[3856,15334,10906],{"class":3874},[3856,15336,3925],{"class":3870},[3856,15338,15157],{"class":3874},[3856,15340,3925],{"class":3870},[3856,15342,5246],{"class":3874},[3856,15344,15345],{"class":3870}," \u003C ",[3856,15347,9079],{"class":4128},[3856,15349,4064],{"class":3870},[3856,15351,15352,15355,15357,15360,15362,15365,15368,15370,15373,15376],{"class":3858,"line":4304},[3856,15353,15354],{"class":3874},"    errors",[3856,15356,3925],{"class":3870},[3856,15358,15359],{"class":3866},"push",[3856,15361,7700],{"class":3870},[3856,15363,15364],{"class":3874},"field:",[3856,15366,15367],{"class":4060}," \"username\"",[3856,15369,3764],{"class":3870},[3856,15371,15372],{"class":3874},"message:",[3856,15374,15375],{"class":4060}," \"Username must be at least 3 characters\"",[3856,15377,7966],{"class":3870},[3856,15379,15380],{"class":3858,"line":4310},[3856,15381,4141],{"class":3870},[3856,15383,15384],{"class":3858,"line":4316},[3856,15385,3916],{"class":3870},[3856,15387,15388,15390,15392,15394,15396,15398,15401,15403,15405,15407,15409,15412,15414,15417],{"class":3858,"line":4322},[3856,15389,4047],{"class":4046},[3856,15391,14167],{"class":3870},[3856,15393,10906],{"class":3874},[3856,15395,3925],{"class":3870},[3856,15397,7788],{"class":3874},[3856,15399,15400],{"class":3870}," || !",[3856,15402,10906],{"class":3874},[3856,15404,3925],{"class":3870},[3856,15406,7788],{"class":3874},[3856,15408,3925],{"class":3870},[3856,15410,15411],{"class":3866},"includes",[3856,15413,3871],{"class":3870},[3856,15415,15416],{"class":4060},"\"@\"",[3856,15418,6531],{"class":3870},[3856,15420,15421,15423,15425,15427,15429,15431,15434,15436,15438,15441],{"class":3858,"line":4328},[3856,15422,15354],{"class":3874},[3856,15424,3925],{"class":3870},[3856,15426,15359],{"class":3866},[3856,15428,7700],{"class":3870},[3856,15430,15364],{"class":3874},[3856,15432,15433],{"class":4060}," \"email\"",[3856,15435,3764],{"class":3870},[3856,15437,15372],{"class":3874},[3856,15439,15440],{"class":4060}," \"Invalid email format\"",[3856,15442,7966],{"class":3870},[3856,15444,15445],{"class":3858,"line":4333},[3856,15446,4141],{"class":3870},[3856,15448,15449],{"class":3858,"line":4338},[3856,15450,3916],{"class":3870},[3856,15452,15453,15455,15457,15460,15462,15464,15467,15469],{"class":3858,"line":4343},[3856,15454,4047],{"class":4046},[3856,15456,3981],{"class":3870},[3856,15458,15459],{"class":3874},"errors",[3856,15461,3925],{"class":3870},[3856,15463,5246],{"class":3874},[3856,15465,15466],{"class":3870}," > ",[3856,15468,5550],{"class":4128},[3856,15470,4064],{"class":3870},[3856,15472,15473,15475,15477,15479,15481,15483,15485],{"class":3858,"line":4349},[3856,15474,4840],{"class":4046},[3856,15476,10473],{"class":3870},[3856,15478,10476],{"class":3874},[3856,15480,10513],{"class":4060},[3856,15482,3764],{"class":3870},[3856,15484,15459],{"class":3874},[3856,15486,7443],{"class":3870},[3856,15488,15489],{"class":3858,"line":4354},[3856,15490,4141],{"class":3870},[3856,15492,15493],{"class":3858,"line":4360},[3856,15494,3916],{"class":3870},[3856,15496,15497,15499],{"class":3858,"line":4366},[3856,15498,4914],{"class":4046},[3856,15500,3897],{"class":3870},[3856,15502,15503,15506,15508],{"class":3858,"line":4372},[3856,15504,15505],{"class":3874},"    status:",[3856,15507,10479],{"class":4060},[3856,15509,12306],{"class":3870},[3856,15511,15512,15515],{"class":3858,"line":4378},[3856,15513,15514],{"class":3874},"    data:",[3856,15516,3897],{"class":3870},[3856,15518,15519,15522,15525,15527,15529,15532],{"class":3858,"line":4383},[3856,15520,15521],{"class":3874},"      username:",[3856,15523,15524],{"class":3874}," input",[3856,15526,3925],{"class":3870},[3856,15528,15157],{"class":3874},[3856,15530,15531],{"class":3870},"!,  ",[3856,15533,15534],{"class":3903},"\u002F\u002F тут точно є значення\n",[3856,15536,15537,15540,15542,15544,15546],{"class":3858,"line":4388},[3856,15538,15539],{"class":3874},"      email:",[3856,15541,15524],{"class":3874},[3856,15543,3925],{"class":3870},[3856,15545,7788],{"class":3874},[3856,15547,15548],{"class":3870},"!\n",[3856,15550,15551],{"class":3858,"line":4393},[3856,15552,15553],{"class":3870},"    }\n",[3856,15555,15556],{"class":3858,"line":4399},[3856,15557,15558],{"class":3870},"  };\n",[3856,15560,15561],{"class":3858,"line":4405},[3856,15562,3961],{"class":3870},[3856,15564,15565],{"class":3858,"line":4411},[3856,15566,4153],{"emptyLinePlaceholder":4152},[3856,15568,15569,15571,15574,15576,15578,15580,15582,15584,15586,15588,15590,15592,15594,15596,15598],{"class":3858,"line":4416},[3856,15570,3863],{"class":3862},[3856,15572,15573],{"class":3866}," handleForm",[3856,15575,3871],{"class":3870},[3856,15577,10906],{"class":3874},[3856,15579,7545],{"class":3870},[3856,15581,15157],{"class":3874},[3856,15583,14151],{"class":3870},[3856,15585,3882],{"class":3881},[3856,15587,7556],{"class":3870},[3856,15589,7788],{"class":3874},[3856,15591,14151],{"class":3870},[3856,15593,3882],{"class":3881},[3856,15595,7585],{"class":3870},[3856,15597,3894],{"class":3881},[3856,15599,3897],{"class":3870},[3856,15601,15602,15604,15607,15609,15612,15614,15616],{"class":3858,"line":4422},[3856,15603,12007],{"class":3862},[3856,15605,15606],{"class":3874}," result",[3856,15608,6507],{"class":3870},[3856,15610,15611],{"class":3866},"validateForm",[3856,15613,3871],{"class":3870},[3856,15615,10906],{"class":3874},[3856,15617,4896],{"class":3870},[3856,15619,15620],{"class":3858,"line":4428},[3856,15621,3916],{"class":3870},[3856,15623,15624,15626,15628,15630,15632,15634,15636,15638],{"class":3858,"line":4434},[3856,15625,4047],{"class":4046},[3856,15627,3981],{"class":3870},[3856,15629,10552],{"class":3874},[3856,15631,3925],{"class":3870},[3856,15633,6763],{"class":3874},[3856,15635,4057],{"class":3870},[3856,15637,6773],{"class":4060},[3856,15639,4064],{"class":3870},[3856,15641,15642],{"class":3858,"line":4440},[3856,15643,15644],{"class":3903},"    \u002F\u002F Тут result: ValidationError\n",[3856,15646,15647,15649,15651,15653,15655,15658],{"class":3858,"line":10254},[3856,15648,4074],{"class":3874},[3856,15650,3925],{"class":3870},[3856,15652,10500],{"class":3866},[3856,15654,3871],{"class":3870},[3856,15656,15657],{"class":4060},"\"Validation failed:\"",[3856,15659,4896],{"class":3870},[3856,15661,15662,15665,15667,15669,15671,15673,15675,15678,15680],{"class":3858,"line":10259},[3856,15663,15664],{"class":3874},"    result",[3856,15666,3925],{"class":3870},[3856,15668,15459],{"class":3874},[3856,15670,3925],{"class":3870},[3856,15672,12045],{"class":3866},[3856,15674,3871],{"class":3870},[3856,15676,15677],{"class":3874},"err",[3856,15679,11307],{"class":3862},[3856,15681,3897],{"class":3870},[3856,15683,15685,15687,15689,15691,15693,15696,15698,15700,15702,15704,15706,15708,15710,15712,15714,15716,15718,15720],{"class":3858,"line":15684},44,[3856,15686,7210],{"class":3874},[3856,15688,3925],{"class":3870},[3856,15690,10500],{"class":3866},[3856,15692,3871],{"class":3870},[3856,15694,15695],{"class":4060},"`  ",[3856,15697,5238],{"class":3862},[3856,15699,15677],{"class":3874},[3856,15701,3925],{"class":5243},[3856,15703,15208],{"class":3874},[3856,15705,5249],{"class":3862},[3856,15707,3878],{"class":4060},[3856,15709,5238],{"class":3862},[3856,15711,15677],{"class":3874},[3856,15713,3925],{"class":5243},[3856,15715,14148],{"class":3874},[3856,15717,5249],{"class":3862},[3856,15719,5252],{"class":4060},[3856,15721,4896],{"class":3870},[3856,15723,15725],{"class":3858,"line":15724},45,[3856,15726,15727],{"class":3870},"    });\n",[3856,15729,15731,15733,15735],{"class":3858,"line":15730},46,[3856,15732,4096],{"class":3870},[3856,15734,4099],{"class":4046},[3856,15736,3897],{"class":3870},[3856,15738,15740],{"class":3858,"line":15739},47,[3856,15741,15742],{"class":3903},"    \u002F\u002F Тут result: ValidationSuccess\n",[3856,15744,15746,15748,15750,15752,15754,15757],{"class":3858,"line":15745},48,[3856,15747,4074],{"class":3874},[3856,15749,3925],{"class":3870},[3856,15751,3928],{"class":3866},[3856,15753,3871],{"class":3870},[3856,15755,15756],{"class":4060},"\"Form is valid!\"",[3856,15758,4896],{"class":3870},[3856,15760,15762,15764,15766,15768,15770,15773,15775,15777,15779,15781,15783,15785,15787,15789],{"class":3858,"line":15761},49,[3856,15763,4074],{"class":3874},[3856,15765,3925],{"class":3870},[3856,15767,3928],{"class":3866},[3856,15769,3871],{"class":3870},[3856,15771,15772],{"class":4060},"`Username: ",[3856,15774,5238],{"class":3862},[3856,15776,10552],{"class":3874},[3856,15778,3925],{"class":5243},[3856,15780,8916],{"class":3874},[3856,15782,3925],{"class":5243},[3856,15784,15157],{"class":3874},[3856,15786,5249],{"class":3862},[3856,15788,5252],{"class":4060},[3856,15790,4896],{"class":3870},[3856,15792,15794,15796,15798,15800,15802,15804,15806,15808,15810,15812,15814,15816,15818,15820],{"class":3858,"line":15793},50,[3856,15795,4074],{"class":3874},[3856,15797,3925],{"class":3870},[3856,15799,3928],{"class":3866},[3856,15801,3871],{"class":3870},[3856,15803,7878],{"class":4060},[3856,15805,5238],{"class":3862},[3856,15807,10552],{"class":3874},[3856,15809,3925],{"class":5243},[3856,15811,8916],{"class":3874},[3856,15813,3925],{"class":5243},[3856,15815,7788],{"class":3874},[3856,15817,5249],{"class":3862},[3856,15819,5252],{"class":4060},[3856,15821,4896],{"class":3870},[3856,15823,15825],{"class":3858,"line":15824},51,[3856,15826,4141],{"class":3870},[3856,15828,15830],{"class":3858,"line":15829},52,[3856,15831,3961],{"class":3870},[3856,15833,15835],{"class":3858,"line":15834},53,[3856,15836,4153],{"emptyLinePlaceholder":4152},[3856,15838,15840,15843,15845,15848,15851,15853,15855,15858],{"class":3858,"line":15839},54,[3856,15841,15842],{"class":3866},"handleForm",[3856,15844,7700],{"class":3870},[3856,15846,15847],{"class":3874},"username:",[3856,15849,15850],{"class":4060}," \"al\"",[3856,15852,3764],{"class":3870},[3856,15854,7960],{"class":3874},[3856,15856,15857],{"class":4060}," \"invalid\"",[3856,15859,7966],{"class":3870},[3856,15861,15863],{"class":3858,"line":15862},55,[3856,15864,15865],{"class":3903},"\u002F\u002F Validation failed:\n",[3856,15867,15869],{"class":3858,"line":15868},56,[3856,15870,15871],{"class":3903},"\u002F\u002F   username: Username must be at least 3 characters\n",[3856,15873,15875],{"class":3858,"line":15874},57,[3856,15876,15877],{"class":3903},"\u002F\u002F   email: Invalid email format\n",[3856,15879,15881],{"class":3858,"line":15880},58,[3856,15882,4153],{"emptyLinePlaceholder":4152},[3856,15884,15886,15888,15890,15892,15895,15897,15899,15901],{"class":3858,"line":15885},59,[3856,15887,15842],{"class":3866},[3856,15889,7700],{"class":3870},[3856,15891,15847],{"class":3874},[3856,15893,15894],{"class":4060}," \"alice\"",[3856,15896,3764],{"class":3870},[3856,15898,7960],{"class":3874},[3856,15900,7963],{"class":4060},[3856,15902,7966],{"class":3870},[3856,15904,15906],{"class":3858,"line":15905},60,[3856,15907,15908],{"class":3903},"\u002F\u002F Form is valid!\n",[3856,15910,15912],{"class":3858,"line":15911},61,[3856,15913,15914],{"class":3903},"\u002F\u002F Username: alice\n",[3856,15916,15918],{"class":3858,"line":15917},62,[3856,15919,7976],{"class":3903},[3838,15921,15923],{"id":15922},"патерн-2-парсинг-json-з-type-guard","Патерн 2: Парсинг JSON з type guard",[3847,15925,15927],{"className":3849,"code":15926,"language":3851,"meta":3852,"style":3852},"function isObject(value: unknown): value is { [key: string]: unknown } {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasStringProperty(obj: { [key: string]: unknown }, key: string): boolean {\n  return key in obj && typeof obj[key] === \"string\";\n}\n\nfunction hasNumberProperty(obj: { [key: string]: unknown }, key: string): boolean {\n  return key in obj && typeof obj[key] === \"number\";\n}\n\nfunction parseUser(json: string): { name: string; age: number } | null {\n  try {\n    let parsed: unknown = JSON.parse(json);\n    \n    if (!isObject(parsed)) {\n      return null;\n    }\n    \n    if (!hasStringProperty(parsed, \"name\") || !hasNumberProperty(parsed, \"age\")) {\n      return null;\n    }\n    \n    \u002F\u002F Після всіх перевірок безпечно повертаємо об'єкт\n    return {\n      name: parsed.name as string,\n      age: parsed.age as number\n    };\n  } catch {\n    return null;\n  }\n}\n\nlet user1 = parseUser('{\"name\": \"Alice\", \"age\": 28}');\nconsole.log(user1);  \u002F\u002F { name: \"Alice\", age: 28 }\n\nlet user2 = parseUser('{\"name\": \"Bob\"}');\nconsole.log(user2);  \u002F\u002F null (відсутнє поле age)\n\nlet user3 = parseUser('invalid json');\nconsole.log(user3);  \u002F\u002F null (помилка парсингу)\n",[3761,15928,15929,15965,16000,16004,16008,16047,16075,16079,16083,16120,16146,16150,16154,16191,16197,16222,16226,16243,16251,16255,16259,16293,16301,16305,16309,16314,16320,16337,16353,16358,16366,16374,16378,16382,16386,16405,16423,16427,16445,16463,16467,16484],{"__ignoreMap":3852},[3856,15930,15931,15933,15936,15938,15940,15942,15944,15946,15948,15950,15953,15955,15957,15959,15961,15963],{"class":3858,"line":3859},[3856,15932,3863],{"class":3862},[3856,15934,15935],{"class":3866}," isObject",[3856,15937,3871],{"class":3870},[3856,15939,3875],{"class":3874},[3856,15941,3878],{"class":3870},[3856,15943,8921],{"class":3881},[3856,15945,3891],{"class":3870},[3856,15947,3875],{"class":3874},[3856,15949,6399],{"class":3862},[3856,15951,15952],{"class":3870}," { [",[3856,15954,8927],{"class":3874},[3856,15956,3878],{"class":3870},[3856,15958,3882],{"class":3874},[3856,15960,8934],{"class":3870},[3856,15962,8921],{"class":3874},[3856,15964,11598],{"class":3870},[3856,15966,15967,15969,15971,15973,15975,15977,15979,15981,15983,15985,15988,15990,15992,15994,15996,15998],{"class":3858,"line":3900},[3856,15968,4914],{"class":4046},[3856,15970,11036],{"class":3862},[3856,15972,4054],{"class":3874},[3856,15974,4057],{"class":3870},[3856,15976,4748],{"class":4060},[3856,15978,6032],{"class":3870},[3856,15980,3875],{"class":3874},[3856,15982,6027],{"class":3870},[3856,15984,5299],{"class":3862},[3856,15986,15987],{"class":3870}," && !",[3856,15989,9180],{"class":3874},[3856,15991,3925],{"class":3870},[3856,15993,9185],{"class":3866},[3856,15995,3871],{"class":3870},[3856,15997,3875],{"class":3874},[3856,15999,4896],{"class":3870},[3856,16001,16002],{"class":3858,"line":3907},[3856,16003,3961],{"class":3870},[3856,16005,16006],{"class":3858,"line":3913},[3856,16007,4153],{"emptyLinePlaceholder":4152},[3856,16009,16010,16012,16015,16017,16019,16022,16024,16026,16028,16030,16032,16035,16037,16039,16041,16043,16045],{"class":3858,"line":3919},[3856,16011,3863],{"class":3862},[3856,16013,16014],{"class":3866}," hasStringProperty",[3856,16016,3871],{"class":3870},[3856,16018,8043],{"class":3874},[3856,16020,16021],{"class":3870},": { [",[3856,16023,8927],{"class":3874},[3856,16025,3878],{"class":3870},[3856,16027,3882],{"class":3881},[3856,16029,8934],{"class":3870},[3856,16031,8921],{"class":3881},[3856,16033,16034],{"class":3870}," }, ",[3856,16036,8927],{"class":3874},[3856,16038,3878],{"class":3870},[3856,16040,3882],{"class":3881},[3856,16042,3891],{"class":3870},[3856,16044,4808],{"class":3881},[3856,16046,3897],{"class":3870},[3856,16048,16049,16051,16054,16056,16058,16060,16062,16064,16066,16068,16071,16073],{"class":3858,"line":3946},[3856,16050,4914],{"class":4046},[3856,16052,16053],{"class":3874}," key",[3856,16055,7463],{"class":3862},[3856,16057,8079],{"class":3874},[3856,16059,6032],{"class":3870},[3856,16061,3763],{"class":3862},[3856,16063,8079],{"class":3874},[3856,16065,10840],{"class":3870},[3856,16067,8927],{"class":3874},[3856,16069,16070],{"class":3870},"] === ",[3856,16072,4061],{"class":4060},[3856,16074,4931],{"class":3870},[3856,16076,16077],{"class":3858,"line":3952},[3856,16078,3961],{"class":3870},[3856,16080,16081],{"class":3858,"line":3958},[3856,16082,4153],{"emptyLinePlaceholder":4152},[3856,16084,16085,16087,16090,16092,16094,16096,16098,16100,16102,16104,16106,16108,16110,16112,16114,16116,16118],{"class":3858,"line":4138},[3856,16086,3863],{"class":3862},[3856,16088,16089],{"class":3866}," hasNumberProperty",[3856,16091,3871],{"class":3870},[3856,16093,8043],{"class":3874},[3856,16095,16021],{"class":3870},[3856,16097,8927],{"class":3874},[3856,16099,3878],{"class":3870},[3856,16101,3882],{"class":3881},[3856,16103,8934],{"class":3870},[3856,16105,8921],{"class":3881},[3856,16107,16034],{"class":3870},[3856,16109,8927],{"class":3874},[3856,16111,3878],{"class":3870},[3856,16113,3882],{"class":3881},[3856,16115,3891],{"class":3870},[3856,16117,4808],{"class":3881},[3856,16119,3897],{"class":3870},[3856,16121,16122,16124,16126,16128,16130,16132,16134,16136,16138,16140,16142,16144],{"class":3858,"line":4144},[3856,16123,4914],{"class":4046},[3856,16125,16053],{"class":3874},[3856,16127,7463],{"class":3862},[3856,16129,8079],{"class":3874},[3856,16131,6032],{"class":3870},[3856,16133,3763],{"class":3862},[3856,16135,8079],{"class":3874},[3856,16137,10840],{"class":3870},[3856,16139,8927],{"class":3874},[3856,16141,16070],{"class":3870},[3856,16143,4872],{"class":4060},[3856,16145,4931],{"class":3870},[3856,16147,16148],{"class":3858,"line":4149},[3856,16149,3961],{"class":3870},[3856,16151,16152],{"class":3858,"line":4156},[3856,16153,4153],{"emptyLinePlaceholder":4152},[3856,16155,16156,16158,16161,16163,16165,16167,16169,16171,16173,16175,16177,16179,16181,16183,16185,16187,16189],{"class":3858,"line":4173},[3856,16157,3863],{"class":3862},[3856,16159,16160],{"class":3866}," parseUser",[3856,16162,3871],{"class":3870},[3856,16164,10424],{"class":3874},[3856,16166,3878],{"class":3870},[3856,16168,3882],{"class":3881},[3856,16170,14696],{"class":3870},[3856,16172,5805],{"class":3874},[3856,16174,3878],{"class":3870},[3856,16176,3882],{"class":3881},[3856,16178,7556],{"class":3870},[3856,16180,11591],{"class":3874},[3856,16182,3878],{"class":3870},[3856,16184,3888],{"class":3881},[3856,16186,13823],{"class":3870},[3856,16188,5299],{"class":3881},[3856,16190,3897],{"class":3870},[3856,16192,16193,16195],{"class":3858,"line":4288},[3856,16194,10440],{"class":4046},[3856,16196,3897],{"class":3870},[3856,16198,16199,16201,16204,16206,16208,16210,16212,16214,16216,16218,16220],{"class":3858,"line":4293},[3856,16200,10447],{"class":3862},[3856,16202,16203],{"class":3874}," parsed",[3856,16205,3878],{"class":3870},[3856,16207,8921],{"class":3881},[3856,16209,6507],{"class":3870},[3856,16211,10455],{"class":7331},[3856,16213,3925],{"class":3870},[3856,16215,10460],{"class":3866},[3856,16217,3871],{"class":3870},[3856,16219,10424],{"class":3874},[3856,16221,4896],{"class":3870},[3856,16223,16224],{"class":3858,"line":4299},[3856,16225,7233],{"class":3870},[3856,16227,16228,16231,16233,16236,16238,16241],{"class":3858,"line":4304},[3856,16229,16230],{"class":4046},"    if",[3856,16232,14167],{"class":3870},[3856,16234,16235],{"class":3866},"isObject",[3856,16237,3871],{"class":3870},[3856,16239,16240],{"class":3874},"parsed",[3856,16242,6531],{"class":3870},[3856,16244,16245,16247,16249],{"class":3858,"line":4310},[3856,16246,9806],{"class":4046},[3856,16248,4703],{"class":3862},[3856,16250,4931],{"class":3870},[3856,16252,16253],{"class":3858,"line":4316},[3856,16254,15553],{"class":3870},[3856,16256,16257],{"class":3858,"line":4322},[3856,16258,7233],{"class":3870},[3856,16260,16261,16263,16265,16268,16270,16272,16274,16276,16279,16282,16284,16286,16288,16291],{"class":3858,"line":4328},[3856,16262,16230],{"class":4046},[3856,16264,14167],{"class":3870},[3856,16266,16267],{"class":3866},"hasStringProperty",[3856,16269,3871],{"class":3870},[3856,16271,16240],{"class":3874},[3856,16273,3764],{"class":3870},[3856,16275,7460],{"class":4060},[3856,16277,16278],{"class":3870},") || !",[3856,16280,16281],{"class":3866},"hasNumberProperty",[3856,16283,3871],{"class":3870},[3856,16285,16240],{"class":3874},[3856,16287,3764],{"class":3870},[3856,16289,16290],{"class":4060},"\"age\"",[3856,16292,6531],{"class":3870},[3856,16294,16295,16297,16299],{"class":3858,"line":4333},[3856,16296,9806],{"class":4046},[3856,16298,4703],{"class":3862},[3856,16300,4931],{"class":3870},[3856,16302,16303],{"class":3858,"line":4338},[3856,16304,15553],{"class":3870},[3856,16306,16307],{"class":3858,"line":4343},[3856,16308,7233],{"class":3870},[3856,16310,16311],{"class":3858,"line":4349},[3856,16312,16313],{"class":3903},"    \u002F\u002F Після всіх перевірок безпечно повертаємо об'єкт\n",[3856,16315,16316,16318],{"class":3858,"line":4354},[3856,16317,4840],{"class":4046},[3856,16319,3897],{"class":3870},[3856,16321,16322,16325,16327,16329,16331,16333,16335],{"class":3858,"line":4360},[3856,16323,16324],{"class":3874},"      name:",[3856,16326,16203],{"class":3874},[3856,16328,3925],{"class":3870},[3856,16330,5805],{"class":3874},[3856,16332,11652],{"class":4046},[3856,16334,6402],{"class":3881},[3856,16336,12306],{"class":3870},[3856,16338,16339,16342,16344,16346,16348,16350],{"class":3858,"line":4366},[3856,16340,16341],{"class":3874},"      age:",[3856,16343,16203],{"class":3874},[3856,16345,3925],{"class":3870},[3856,16347,11591],{"class":3874},[3856,16349,11652],{"class":4046},[3856,16351,16352],{"class":3881}," number\n",[3856,16354,16355],{"class":3858,"line":4372},[3856,16356,16357],{"class":3870},"    };\n",[3856,16359,16360,16362,16364],{"class":3858,"line":4378},[3856,16361,4096],{"class":3870},[3856,16363,10495],{"class":4046},[3856,16365,3897],{"class":3870},[3856,16367,16368,16370,16372],{"class":3858,"line":4383},[3856,16369,4840],{"class":4046},[3856,16371,4703],{"class":3862},[3856,16373,4931],{"class":3870},[3856,16375,16376],{"class":3858,"line":4388},[3856,16377,4141],{"class":3870},[3856,16379,16380],{"class":3858,"line":4393},[3856,16381,3961],{"class":3870},[3856,16383,16384],{"class":3858,"line":4399},[3856,16385,4153],{"emptyLinePlaceholder":4152},[3856,16387,16388,16390,16393,16395,16398,16400,16403],{"class":3858,"line":4405},[3856,16389,6494],{"class":3862},[3856,16391,16392],{"class":3874}," user1",[3856,16394,6507],{"class":3870},[3856,16396,16397],{"class":3866},"parseUser",[3856,16399,3871],{"class":3870},[3856,16401,16402],{"class":4060},"'{\"name\": \"Alice\", \"age\": 28}'",[3856,16404,4896],{"class":3870},[3856,16406,16407,16409,16411,16413,16415,16418,16420],{"class":3858,"line":4411},[3856,16408,4524],{"class":3874},[3856,16410,3925],{"class":3870},[3856,16412,3928],{"class":3866},[3856,16414,3871],{"class":3870},[3856,16416,16417],{"class":3874},"user1",[3856,16419,4167],{"class":3870},[3856,16421,16422],{"class":3903},"\u002F\u002F { name: \"Alice\", age: 28 }\n",[3856,16424,16425],{"class":3858,"line":4416},[3856,16426,4153],{"emptyLinePlaceholder":4152},[3856,16428,16429,16431,16434,16436,16438,16440,16443],{"class":3858,"line":4422},[3856,16430,6494],{"class":3862},[3856,16432,16433],{"class":3874}," user2",[3856,16435,6507],{"class":3870},[3856,16437,16397],{"class":3866},[3856,16439,3871],{"class":3870},[3856,16441,16442],{"class":4060},"'{\"name\": \"Bob\"}'",[3856,16444,4896],{"class":3870},[3856,16446,16447,16449,16451,16453,16455,16458,16460],{"class":3858,"line":4428},[3856,16448,4524],{"class":3874},[3856,16450,3925],{"class":3870},[3856,16452,3928],{"class":3866},[3856,16454,3871],{"class":3870},[3856,16456,16457],{"class":3874},"user2",[3856,16459,4167],{"class":3870},[3856,16461,16462],{"class":3903},"\u002F\u002F null (відсутнє поле age)\n",[3856,16464,16465],{"class":3858,"line":4434},[3856,16466,4153],{"emptyLinePlaceholder":4152},[3856,16468,16469,16471,16474,16476,16478,16480,16482],{"class":3858,"line":4440},[3856,16470,6494],{"class":3862},[3856,16472,16473],{"class":3874}," user3",[3856,16475,6507],{"class":3870},[3856,16477,16397],{"class":3866},[3856,16479,3871],{"class":3870},[3856,16481,10719],{"class":4060},[3856,16483,4896],{"class":3870},[3856,16485,16486,16488,16490,16492,16494,16497,16499],{"class":3858,"line":10254},[3856,16487,4524],{"class":3874},[3856,16489,3925],{"class":3870},[3856,16491,3928],{"class":3866},[3856,16493,3871],{"class":3870},[3856,16495,16496],{"class":3874},"user3",[3856,16498,4167],{"class":3870},[3856,16500,16501],{"class":3903},"\u002F\u002F null (помилка парсингу)\n",[3838,16503,16505],{"id":16504},"патерн-3-фільтрація-масиву-з-type-guard","Патерн 3: Фільтрація масиву з type guard",[3847,16507,16509],{"className":3849,"code":16508,"language":3851,"meta":3852,"style":3852},"function isDefined\u003CT>(value: T | null | undefined): value is T {\n  return value !== null && value !== undefined;\n}\n\nfunction processUsers(users: ({ name: string; email?: string } | null)[]): void {\n  \u002F\u002F Відфільтрувати null значення\n  let validUsers = users.filter(isDefined);\n  \n  \u002F\u002F Тут validUsers: { name: string; email?: string }[]\n  \n  \u002F\u002F Відфільтрувати користувачів з email\n  let usersWithEmail = validUsers.filter(user => user.email !== undefined);\n  \n  \u002F\u002F Відправити email всім\n  usersWithEmail.forEach(user => {\n    console.log(`Sending email to ${user.name} at ${user.email}`);\n  });\n}\n\nprocessUsers([\n  { name: \"Alice\", email: \"alice@example.com\" },\n  null,\n  { name: \"Bob\" },\n  { name: \"Charlie\", email: \"charlie@example.com\" }\n]);\n\u002F\u002F Sending email to Alice at alice@example.com\n\u002F\u002F Sending email to Charlie at charlie@example.com\n",[3761,16510,16511,16548,16568,16572,16576,16614,16619,16641,16645,16650,16654,16659,16693,16697,16702,16719,16759,16763,16767,16771,16779,16797,16804,16814,16831,16835,16840],{"__ignoreMap":3852},[3856,16512,16513,16515,16518,16520,16522,16524,16526,16528,16530,16532,16534,16536,16538,16540,16542,16544,16546],{"class":3858,"line":3859},[3856,16514,3863],{"class":3862},[3856,16516,16517],{"class":3866}," isDefined",[3856,16519,11906],{"class":3870},[3856,16521,11909],{"class":3881},[3856,16523,11912],{"class":3870},[3856,16525,3875],{"class":3874},[3856,16527,3878],{"class":3870},[3856,16529,11909],{"class":3881},[3856,16531,3885],{"class":3870},[3856,16533,5299],{"class":3881},[3856,16535,3885],{"class":3870},[3856,16537,5139],{"class":3881},[3856,16539,3891],{"class":3870},[3856,16541,3875],{"class":3874},[3856,16543,6399],{"class":3862},[3856,16545,11935],{"class":3881},[3856,16547,3897],{"class":3870},[3856,16549,16550,16552,16554,16556,16558,16560,16562,16564,16566],{"class":3858,"line":3900},[3856,16551,4914],{"class":4046},[3856,16553,4054],{"class":3874},[3856,16555,6027],{"class":3870},[3856,16557,5299],{"class":3862},[3856,16559,6032],{"class":3870},[3856,16561,3875],{"class":3874},[3856,16563,6027],{"class":3870},[3856,16565,5139],{"class":3862},[3856,16567,4931],{"class":3870},[3856,16569,16570],{"class":3858,"line":3907},[3856,16571,3961],{"class":3870},[3856,16573,16574],{"class":3858,"line":3913},[3856,16575,4153],{"emptyLinePlaceholder":4152},[3856,16577,16578,16580,16583,16585,16587,16590,16592,16594,16596,16598,16600,16602,16604,16606,16608,16610,16612],{"class":3858,"line":3919},[3856,16579,3863],{"class":3862},[3856,16581,16582],{"class":3866}," processUsers",[3856,16584,3871],{"class":3870},[3856,16586,13912],{"class":3874},[3856,16588,16589],{"class":3870},": ({ ",[3856,16591,5805],{"class":3874},[3856,16593,3878],{"class":3870},[3856,16595,3882],{"class":3881},[3856,16597,7556],{"class":3870},[3856,16599,7788],{"class":3874},[3856,16601,14151],{"class":3870},[3856,16603,3882],{"class":3881},[3856,16605,13823],{"class":3870},[3856,16607,5299],{"class":3881},[3856,16609,11993],{"class":3870},[3856,16611,3894],{"class":3881},[3856,16613,3897],{"class":3870},[3856,16615,16616],{"class":3858,"line":3946},[3856,16617,16618],{"class":3903},"  \u002F\u002F Відфільтрувати null значення\n",[3856,16620,16621,16623,16626,16628,16630,16632,16634,16636,16639],{"class":3858,"line":3952},[3856,16622,12007],{"class":3862},[3856,16624,16625],{"class":3874}," validUsers",[3856,16627,6507],{"class":3870},[3856,16629,13912],{"class":3874},[3856,16631,3925],{"class":3870},[3856,16633,12019],{"class":3866},[3856,16635,3871],{"class":3870},[3856,16637,16638],{"class":3874},"isDefined",[3856,16640,4896],{"class":3870},[3856,16642,16643],{"class":3858,"line":3958},[3856,16644,3916],{"class":3870},[3856,16646,16647],{"class":3858,"line":4138},[3856,16648,16649],{"class":3903},"  \u002F\u002F Тут validUsers: { name: string; email?: string }[]\n",[3856,16651,16652],{"class":3858,"line":4144},[3856,16653,3916],{"class":3870},[3856,16655,16656],{"class":3858,"line":4149},[3856,16657,16658],{"class":3903},"  \u002F\u002F Відфільтрувати користувачів з email\n",[3856,16660,16661,16663,16666,16668,16671,16673,16675,16677,16679,16681,16683,16685,16687,16689,16691],{"class":3858,"line":4156},[3856,16662,12007],{"class":3862},[3856,16664,16665],{"class":3874}," usersWithEmail",[3856,16667,6507],{"class":3870},[3856,16669,16670],{"class":3874},"validUsers",[3856,16672,3925],{"class":3870},[3856,16674,12019],{"class":3866},[3856,16676,3871],{"class":3870},[3856,16678,13694],{"class":3874},[3856,16680,11307],{"class":3862},[3856,16682,7423],{"class":3874},[3856,16684,3925],{"class":3870},[3856,16686,7788],{"class":3874},[3856,16688,6027],{"class":3870},[3856,16690,5139],{"class":3862},[3856,16692,4896],{"class":3870},[3856,16694,16695],{"class":3858,"line":4173},[3856,16696,3916],{"class":3870},[3856,16698,16699],{"class":3858,"line":4288},[3856,16700,16701],{"class":3903},"  \u002F\u002F Відправити email всім\n",[3856,16703,16704,16707,16709,16711,16713,16715,16717],{"class":3858,"line":4293},[3856,16705,16706],{"class":3874},"  usersWithEmail",[3856,16708,3925],{"class":3870},[3856,16710,12045],{"class":3866},[3856,16712,3871],{"class":3870},[3856,16714,13694],{"class":3874},[3856,16716,11307],{"class":3862},[3856,16718,3897],{"class":3870},[3856,16720,16721,16723,16725,16727,16729,16732,16734,16736,16738,16740,16742,16745,16747,16749,16751,16753,16755,16757],{"class":3858,"line":4299},[3856,16722,4074],{"class":3874},[3856,16724,3925],{"class":3870},[3856,16726,3928],{"class":3866},[3856,16728,3871],{"class":3870},[3856,16730,16731],{"class":4060},"`Sending email to ",[3856,16733,5238],{"class":3862},[3856,16735,13694],{"class":3874},[3856,16737,3925],{"class":5243},[3856,16739,5805],{"class":3874},[3856,16741,5249],{"class":3862},[3856,16743,16744],{"class":4060}," at ",[3856,16746,5238],{"class":3862},[3856,16748,13694],{"class":3874},[3856,16750,3925],{"class":5243},[3856,16752,7788],{"class":3874},[3856,16754,5249],{"class":3862},[3856,16756,5252],{"class":4060},[3856,16758,4896],{"class":3870},[3856,16760,16761],{"class":3858,"line":4304},[3856,16762,12079],{"class":3870},[3856,16764,16765],{"class":3858,"line":4310},[3856,16766,3961],{"class":3870},[3856,16768,16769],{"class":3858,"line":4316},[3856,16770,4153],{"emptyLinePlaceholder":4152},[3856,16772,16773,16776],{"class":3858,"line":4322},[3856,16774,16775],{"class":3866},"processUsers",[3856,16777,16778],{"class":3870},"([\n",[3856,16780,16781,16784,16786,16788,16790,16792,16794],{"class":3858,"line":4328},[3856,16782,16783],{"class":3870},"  { ",[3856,16785,7429],{"class":3874},[3856,16787,7432],{"class":4060},[3856,16789,3764],{"class":3870},[3856,16791,7960],{"class":3874},[3856,16793,7963],{"class":4060},[3856,16795,16796],{"class":3870}," },\n",[3856,16798,16799,16802],{"class":3858,"line":4333},[3856,16800,16801],{"class":3862},"  null",[3856,16803,12306],{"class":3870},[3856,16805,16806,16808,16810,16812],{"class":3858,"line":4338},[3856,16807,16783],{"class":3870},[3856,16809,7429],{"class":3874},[3856,16811,7991],{"class":4060},[3856,16813,16796],{"class":3870},[3856,16815,16816,16818,16820,16822,16824,16826,16829],{"class":3858,"line":4343},[3856,16817,16783],{"class":3870},[3856,16819,7429],{"class":3874},[3856,16821,11876],{"class":4060},[3856,16823,3764],{"class":3870},[3856,16825,7960],{"class":3874},[3856,16827,16828],{"class":4060}," \"charlie@example.com\"",[3856,16830,9359],{"class":3870},[3856,16832,16833],{"class":3858,"line":4349},[3856,16834,12117],{"class":3870},[3856,16836,16837],{"class":3858,"line":4354},[3856,16838,16839],{"class":3903},"\u002F\u002F Sending email to Alice at alice@example.com\n",[3856,16841,16842],{"class":3858,"line":4360},[3856,16843,16844],{"class":3903},"\u002F\u002F Sending email to Charlie at charlie@example.com\n",[3830,16846],{},[3833,16848,16850],{"id":16849},"підсумок","Підсумок",[3843,16852,16853],{},"У цьому розділі ви опанували механізми звуження типів у TypeScript:",[3843,16855,16856],{},[3793,16857,16858],{},"Концепція Type Narrowing:",[3746,16860,16861,16864,16867],{},[3749,16862,16863],{},"Звуження типів — це процес уточнення типу з ширшого до вужчого.",[3749,16865,16866],{},"TypeScript відстежує потік виконання коду (control flow analysis).",[3749,16868,16869],{},"Після перевірок TypeScript дозволяє використовувати специфічні властивості звужених типів.",[3843,16871,16872],{},[3793,16873,16874],{},"Техніки Type Guards:",[3746,16876,16877,16885,16894,16909,16918],{},[3749,16878,16879,16881,16882,9032],{},[3793,16880,3763],{}," — перевірка примітивних типів (",[3761,16883,16884],{},"typeof x === \"string\"",[3749,16886,16887,16890,16891,3925],{},[3793,16888,16889],{},"Truthiness"," — виключення falsy значень через ",[3761,16892,16893],{},"if (value)",[3749,16895,16896,16899,16900,3764,16902,3764,16904,3764,16906,3925],{},[3793,16897,16898],{},"Equality"," — перевірка через ",[3761,16901,6349],{},[3761,16903,6578],{},[3761,16905,6345],{},[3761,16907,16908],{},"!=",[3749,16910,16911,16914,16915,9032],{},[3793,16912,16913],{},"in оператор"," — перевірка наявності властивості (",[3761,16916,16917],{},"\"prop\" in obj",[3749,16919,16920,16922,16923,9032],{},[3793,16921,3767],{}," — перевірка на клас або конструктор (",[3761,16924,16925],{},"value instanceof Date",[3843,16927,16928],{},[3793,16929,16930],{},"Discriminated Unions:",[3746,16932,16933,16936,16939,16942],{},[3749,16934,16935],{},"Найпотужніший патерн для моделювання варіативних даних.",[3749,16937,16938],{},"Кожен варіант має спільну властивість-дискримінатор з унікальним літеральним значенням.",[3749,16940,16941],{},"TypeScript точно звужує тип на основі дискримінатора.",[3749,16943,16944,16945,16947],{},"Exhaustiveness checking через ",[3761,16946,7337],{}," гарантує обробку всіх варіантів.",[3843,16949,16950],{},[3793,16951,16952],{},"Custom Type Guards:",[3746,16954,16955,16962,16968],{},[3749,16956,16957,16958,16961],{},"Функції з type predicate (",[3761,16959,16960],{},"value is Type",") для складних перевірок.",[3749,16963,16964,16965,16967],{},"Assertion functions (",[3761,16966,14379],{},") для інваріантів програми.",[3749,16969,16970],{},"Ви відповідаєте за коректність логіки перевірки.",[3843,16972,16973],{},[3793,16974,3807],{},[3746,16976,16977,16980,16983],{},[3749,16978,16979],{},"TypeScript відстежує, які типи були виключені у попередніх перевірках.",[3749,16981,16982],{},"Early return ефективно звужує типи.",[3749,16984,16985,16986,16988,16989,16991],{},"Optional chaining (",[3761,16987,13612],{},") та nullish coalescing (",[3761,16990,13323],{},") для безпечної роботи з nullable значеннями.",[3843,16993,16994],{},[3793,16995,16996],{},"Ключові рекомендації:",[3746,16998,16999,17002,17005,17008],{},[3749,17000,17001],{},"Використовуйте discriminated unions для складних union types.",[3749,17003,17004],{},"Пишіть custom type guards для багаторазових перевірок.",[3749,17006,17007],{},"Завжди обробляйте всі варіанти union type (exhaustiveness checking).",[3749,17009,17010],{},"Довіряйте control flow analysis TypeScript — він розумніший, ніж здається.",[17012,17013,17014,17078,17295,17560,17702,17953],"accordion",{},[17015,17016,17019,17038,17041,17050],"accordion-item",{"icon":17017,"label":17018},"i-lucide-help-circle","❓ Чому typeof null повертає 'object'?",[3843,17020,17021,17022,17024,17025,17028,17029,17031,17032,17034,17035,17037],{},"Це ",[3793,17023,4752],{}," JavaScript з 1995 року. У першій реалізації JavaScript значення зберігалися як 32-бітові слова: перші біти позначали тип, а решта — дані. Об'єкти мали тег ",[3761,17026,17027],{},"000",", а ",[3761,17030,5299],{}," був представлений як NULL pointer (всі біти 0), тому ",[3761,17033,3763],{}," плутав ",[3761,17036,5299],{}," з об'єктом.",[3843,17039,17040],{},"Помилку не можна виправити через зворотну сумісність — це зламало б мільйони сайтів.",[3843,17042,17043,17046,17047,17049],{},[3793,17044,17045],{},"Рішення:"," Завжди перевіряйте ",[3761,17048,5299],{}," через strict equality:",[3847,17051,17053],{"className":3849,"code":17052,"language":3851,"meta":3852,"style":3852},"if (value === null) {\n  \u002F\u002F коректна перевірка\n}\n",[3761,17054,17055,17069,17074],{"__ignoreMap":3852},[3856,17056,17057,17059,17061,17063,17065,17067],{"class":3858,"line":3859},[3856,17058,4200],{"class":4046},[3856,17060,3981],{"class":3870},[3856,17062,3875],{"class":3874},[3856,17064,4057],{"class":3870},[3856,17066,5299],{"class":3862},[3856,17068,4064],{"class":3870},[3856,17070,17071],{"class":3858,"line":3900},[3856,17072,17073],{"class":3903},"  \u002F\u002F коректна перевірка\n",[3856,17075,17076],{"class":3858,"line":3907},[3856,17077,3961],{"class":3870},[17015,17079,17081,17092,17182,17194,17279],{"icon":17017,"label":17080},"❓ Чим відрізняється || від ?? (nullish coalescing)?",[3843,17082,17083,17087,17088,17091],{},[3793,17084,6263,17085],{},[3761,17086,13475],{}," повертає правий операнд для ",[3793,17089,17090],{},"будь-якого falsy"," значення:",[3847,17093,17095],{"className":3849,"code":17094,"language":3851,"meta":3852,"style":3852},"console.log(0 || 10);           \u002F\u002F 10\nconsole.log(\"\" || \"default\");   \u002F\u002F \"default\"\nconsole.log(false || true);     \u002F\u002F true\nconsole.log(null || \"fallback\");\u002F\u002F \"fallback\"\n",[3761,17096,17097,17119,17139,17159],{"__ignoreMap":3852},[3856,17098,17099,17101,17103,17105,17107,17109,17111,17113,17116],{"class":3858,"line":3859},[3856,17100,4524],{"class":3874},[3856,17102,3925],{"class":3870},[3856,17104,3928],{"class":3866},[3856,17106,3871],{"class":3870},[3856,17108,5550],{"class":4128},[3856,17110,13301],{"class":3870},[3856,17112,13528],{"class":4128},[3856,17114,17115],{"class":3870},");           ",[3856,17117,17118],{"class":3903},"\u002F\u002F 10\n",[3856,17120,17121,17123,17125,17127,17129,17131,17133,17135,17137],{"class":3858,"line":3900},[3856,17122,4524],{"class":3874},[3856,17124,3925],{"class":3870},[3856,17126,3928],{"class":3866},[3856,17128,3871],{"class":3870},[3856,17130,5568],{"class":4060},[3856,17132,13301],{"class":3870},[3856,17134,13304],{"class":4060},[3856,17136,5949],{"class":3870},[3856,17138,13427],{"class":3903},[3856,17140,17141,17143,17145,17147,17149,17151,17153,17155,17157],{"class":3858,"line":3907},[3856,17142,4524],{"class":3874},[3856,17144,3925],{"class":3870},[3856,17146,3928],{"class":3866},[3856,17148,3871],{"class":3870},[3856,17150,3827],{"class":3862},[3856,17152,13301],{"class":3870},[3856,17154,3823],{"class":3862},[3856,17156,4600],{"class":3870},[3856,17158,7470],{"class":3903},[3856,17160,17161,17163,17165,17167,17169,17171,17173,17176,17179],{"class":3858,"line":3913},[3856,17162,4524],{"class":3874},[3856,17164,3925],{"class":3870},[3856,17166,3928],{"class":3866},[3856,17168,3871],{"class":3870},[3856,17170,5299],{"class":3862},[3856,17172,13301],{"class":3870},[3856,17174,17175],{"class":4060},"\"fallback\"",[3856,17177,17178],{"class":3870},");",[3856,17180,17181],{"class":3903},"\u002F\u002F \"fallback\"\n",[3843,17183,17184,13499,17188,9743,17190,5786,17192,4737],{},[3793,17185,6263,17186],{},[3761,17187,13323],{},[3793,17189,13502],{},[3761,17191,5299],{},[3761,17193,5139],{},[3847,17195,17197],{"className":3849,"code":17196,"language":3851,"meta":3852,"style":3852},"console.log(0 ?? 10);           \u002F\u002F 0 (0 — не null\u002Fundefined)\nconsole.log(\"\" ?? \"default\");   \u002F\u002F \"\" (порожній рядок — не null\u002Fundefined)\nconsole.log(false ?? true);     \u002F\u002F false\nconsole.log(null ?? \"fallback\");\u002F\u002F \"fallback\"\n",[3761,17198,17199,17219,17239,17259],{"__ignoreMap":3852},[3856,17200,17201,17203,17205,17207,17209,17211,17213,17215,17217],{"class":3858,"line":3859},[3856,17202,4524],{"class":3874},[3856,17204,3925],{"class":3870},[3856,17206,3928],{"class":3866},[3856,17208,3871],{"class":3870},[3856,17210,5550],{"class":4128},[3856,17212,13371],{"class":3870},[3856,17214,13528],{"class":4128},[3856,17216,17115],{"class":3870},[3856,17218,13554],{"class":3903},[3856,17220,17221,17223,17225,17227,17229,17231,17233,17235,17237],{"class":3858,"line":3900},[3856,17222,4524],{"class":3874},[3856,17224,3925],{"class":3870},[3856,17226,3928],{"class":3866},[3856,17228,3871],{"class":3870},[3856,17230,5568],{"class":4060},[3856,17232,13371],{"class":3870},[3856,17234,13304],{"class":4060},[3856,17236,5949],{"class":3870},[3856,17238,13600],{"class":3903},[3856,17240,17241,17243,17245,17247,17249,17251,17253,17255,17257],{"class":3858,"line":3907},[3856,17242,4524],{"class":3874},[3856,17244,3925],{"class":3870},[3856,17246,3928],{"class":3866},[3856,17248,3871],{"class":3870},[3856,17250,3827],{"class":3862},[3856,17252,13371],{"class":3870},[3856,17254,3823],{"class":3862},[3856,17256,4600],{"class":3870},[3856,17258,7492],{"class":3903},[3856,17260,17261,17263,17265,17267,17269,17271,17273,17275,17277],{"class":3858,"line":3913},[3856,17262,4524],{"class":3874},[3856,17264,3925],{"class":3870},[3856,17266,3928],{"class":3866},[3856,17268,3871],{"class":3870},[3856,17270,5299],{"class":3862},[3856,17272,13371],{"class":3870},[3856,17274,17175],{"class":4060},[3856,17276,17178],{"class":3870},[3856,17278,17181],{"class":3903},[3843,17280,15104,17281,17283,17284,5975,17286,17288,17289,3764,17291,3764,17293,9032],{},[3761,17282,13323],{},", коли хочете замінити лише ",[3761,17285,5299],{},[3761,17287,5139],{},", зберігаючи інші falsy значення (",[3761,17290,5550],{},[3761,17292,5568],{},[3761,17294,3827],{},[17015,17296,17298,17304,17512,17526],{"icon":17017,"label":17297},"❓ Що таке exhaustiveness checking?",[3843,17299,17300,17303],{},[3793,17301,17302],{},"Exhaustiveness checking"," — це техніка, що гарантує обробку всіх варіантів union type:",[3847,17305,17307],{"className":3849,"code":17306,"language":3851,"meta":3852,"style":3852},"type Status = \"success\" | \"error\" | \"pending\";\n\nfunction handleStatus(status: Status): void {\n  switch (status) {\n    case \"success\":\n      console.log(\"Success\");\n      break;\n    case \"error\":\n      console.log(\"Error\");\n      break;\n    case \"pending\":\n      console.log(\"Pending\");\n      break;\n    default:\n      \u002F\u002F Якщо всі варіанти оброблені, status тут має тип never\n      const exhaustiveCheck: never = status;\n      throw new Error(`Unhandled status: ${exhaustiveCheck}`);\n  }\n}\n",[3761,17308,17309,17330,17334,17356,17366,17374,17389,17395,17403,17418,17424,17433,17448,17454,17460,17465,17481,17504,17508],{"__ignoreMap":3852},[3856,17310,17311,17313,17316,17318,17320,17322,17324,17326,17328],{"class":3858,"line":3859},[3856,17312,9570],{"class":3862},[3856,17314,17315],{"class":3881}," Status",[3856,17317,6507],{"class":3870},[3856,17319,6768],{"class":4060},[3856,17321,3885],{"class":3870},[3856,17323,6773],{"class":4060},[3856,17325,3885],{"class":3870},[3856,17327,6778],{"class":4060},[3856,17329,4931],{"class":3870},[3856,17331,17332],{"class":3858,"line":3900},[3856,17333,4153],{"emptyLinePlaceholder":4152},[3856,17335,17336,17338,17341,17343,17345,17347,17350,17352,17354],{"class":3858,"line":3907},[3856,17337,3863],{"class":3862},[3856,17339,17340],{"class":3866}," handleStatus",[3856,17342,3871],{"class":3870},[3856,17344,6763],{"class":3874},[3856,17346,3878],{"class":3870},[3856,17348,17349],{"class":3881},"Status",[3856,17351,3891],{"class":3870},[3856,17353,3894],{"class":3881},[3856,17355,3897],{"class":3870},[3856,17357,17358,17360,17362,17364],{"class":3858,"line":3913},[3856,17359,7183],{"class":4046},[3856,17361,3981],{"class":3870},[3856,17363,6763],{"class":3874},[3856,17365,4064],{"class":3870},[3856,17367,17368,17370,17372],{"class":3858,"line":3919},[3856,17369,7194],{"class":4046},[3856,17371,10479],{"class":4060},[3856,17373,7200],{"class":3870},[3856,17375,17376,17378,17380,17382,17384,17387],{"class":3858,"line":3946},[3856,17377,7210],{"class":3874},[3856,17379,3925],{"class":3870},[3856,17381,3928],{"class":3866},[3856,17383,3871],{"class":3870},[3856,17385,17386],{"class":4060},"\"Success\"",[3856,17388,4896],{"class":3870},[3856,17390,17391,17393],{"class":3858,"line":3952},[3856,17392,7226],{"class":4046},[3856,17394,4931],{"class":3870},[3856,17396,17397,17399,17401],{"class":3858,"line":3958},[3856,17398,7194],{"class":4046},[3856,17400,10513],{"class":4060},[3856,17402,7200],{"class":3870},[3856,17404,17405,17407,17409,17411,17413,17416],{"class":3858,"line":4138},[3856,17406,7210],{"class":3874},[3856,17408,3925],{"class":3870},[3856,17410,3928],{"class":3866},[3856,17412,3871],{"class":3870},[3856,17414,17415],{"class":4060},"\"Error\"",[3856,17417,4896],{"class":3870},[3856,17419,17420,17422],{"class":3858,"line":4144},[3856,17421,7226],{"class":4046},[3856,17423,4931],{"class":3870},[3856,17425,17426,17428,17431],{"class":3858,"line":4149},[3856,17427,7194],{"class":4046},[3856,17429,17430],{"class":4060}," \"pending\"",[3856,17432,7200],{"class":3870},[3856,17434,17435,17437,17439,17441,17443,17446],{"class":3858,"line":4156},[3856,17436,7210],{"class":3874},[3856,17438,3925],{"class":3870},[3856,17440,3928],{"class":3866},[3856,17442,3871],{"class":3870},[3856,17444,17445],{"class":4060},"\"Pending\"",[3856,17447,4896],{"class":3870},[3856,17449,17450,17452],{"class":3858,"line":4173},[3856,17451,7226],{"class":4046},[3856,17453,4931],{"class":3870},[3856,17455,17456,17458],{"class":3858,"line":4288},[3856,17457,7316],{"class":4046},[3856,17459,7200],{"class":3870},[3856,17461,17462],{"class":3858,"line":4293},[3856,17463,17464],{"class":3903},"      \u002F\u002F Якщо всі варіанти оброблені, status тут має тип never\n",[3856,17466,17467,17469,17471,17473,17475,17477,17479],{"class":3858,"line":4299},[3856,17468,7328],{"class":3862},[3856,17470,7332],{"class":7331},[3856,17472,3878],{"class":3870},[3856,17474,7337],{"class":3881},[3856,17476,6507],{"class":3870},[3856,17478,6763],{"class":3874},[3856,17480,4931],{"class":3870},[3856,17482,17483,17485,17487,17489,17491,17494,17496,17498,17500,17502],{"class":3858,"line":4304},[3856,17484,7348],{"class":4046},[3856,17486,7351],{"class":3862},[3856,17488,7354],{"class":3866},[3856,17490,3871],{"class":3870},[3856,17492,17493],{"class":4060},"`Unhandled status: ",[3856,17495,5238],{"class":3862},[3856,17497,7364],{"class":3874},[3856,17499,5249],{"class":3862},[3856,17501,5252],{"class":4060},[3856,17503,4896],{"class":3870},[3856,17505,17506],{"class":3858,"line":4310},[3856,17507,4141],{"class":3870},[3856,17509,17510],{"class":3858,"line":4316},[3856,17511,3961],{"class":3870},[3843,17513,17514,17515,17518,17519,17521,17522,7394,17524,4737],{},"Якщо ви додасте новий варіант (",[3761,17516,17517],{},"\"loading\"",") до ",[3761,17520,17349],{},", але забудете обробити його у ",[3761,17523,7139],{},[3761,17525,7390],{},[3847,17527,17529],{"className":3849,"code":17528,"language":3851,"meta":3852,"style":3852},"type Status = \"success\" | \"error\" | \"pending\" | \"loading\";\n\u002F\u002F Error: Type 'string' is not assignable to type 'never'\n",[3761,17530,17531,17555],{"__ignoreMap":3852},[3856,17532,17533,17535,17537,17539,17541,17543,17545,17547,17549,17551,17553],{"class":3858,"line":3859},[3856,17534,9570],{"class":3862},[3856,17536,17315],{"class":3881},[3856,17538,6507],{"class":3870},[3856,17540,6768],{"class":4060},[3856,17542,3885],{"class":3870},[3856,17544,6773],{"class":4060},[3856,17546,3885],{"class":3870},[3856,17548,6778],{"class":4060},[3856,17550,3885],{"class":3870},[3856,17552,17517],{"class":4060},[3856,17554,4931],{"class":3870},[3856,17556,17557],{"class":3858,"line":3900},[3856,17558,17559],{"class":3903},"\u002F\u002F Error: Type 'string' is not assignable to type 'never'\n",[17015,17561,17563,17569,17693],{"icon":17017,"label":17562},"❓ Чи може type guard помилитися?",[3843,17564,17565,17566,17568],{},"Так! TypeScript ",[3793,17567,11238],{}," вашим type guards. Якщо ви напишете неправильну логіку, TypeScript не виявить помилку:",[3847,17570,17572],{"className":3849,"code":17571,"language":3851,"meta":3852,"style":3852},"function isBrokenNumber(value: unknown): value is number {\n  return typeof value === \"string\";  \u002F\u002F ❌ Помилка: перевіряє string, каже number!\n}\n\nlet x: unknown = \"hello\";\n\nif (isBrokenNumber(x)) {\n  \u002F\u002F TypeScript думає, що x — number\n  console.log(x.toFixed(2));  \u002F\u002F Runtime Error!\n}\n",[3761,17573,17574,17599,17616,17620,17624,17640,17644,17659,17664,17689],{"__ignoreMap":3852},[3856,17575,17576,17578,17581,17583,17585,17587,17589,17591,17593,17595,17597],{"class":3858,"line":3859},[3856,17577,3863],{"class":3862},[3856,17579,17580],{"class":3866}," isBrokenNumber",[3856,17582,3871],{"class":3870},[3856,17584,3875],{"class":3874},[3856,17586,3878],{"class":3870},[3856,17588,8921],{"class":3881},[3856,17590,3891],{"class":3870},[3856,17592,3875],{"class":3874},[3856,17594,6399],{"class":3862},[3856,17596,11272],{"class":3881},[3856,17598,3897],{"class":3870},[3856,17600,17601,17603,17605,17607,17609,17611,17613],{"class":3858,"line":3900},[3856,17602,4914],{"class":4046},[3856,17604,11036],{"class":3862},[3856,17606,4054],{"class":3874},[3856,17608,4057],{"class":3870},[3856,17610,4061],{"class":4060},[3856,17612,6478],{"class":3870},[3856,17614,17615],{"class":3903},"\u002F\u002F ❌ Помилка: перевіряє string, каже number!\n",[3856,17617,17618],{"class":3858,"line":3907},[3856,17619,3961],{"class":3870},[3856,17621,17622],{"class":3858,"line":3913},[3856,17623,4153],{"emptyLinePlaceholder":4152},[3856,17625,17626,17628,17630,17632,17634,17636,17638],{"class":3858,"line":3919},[3856,17627,6494],{"class":3862},[3856,17629,5053],{"class":3874},[3856,17631,3878],{"class":3870},[3856,17633,8921],{"class":3881},[3856,17635,6507],{"class":3870},[3856,17637,4164],{"class":4060},[3856,17639,4931],{"class":3870},[3856,17641,17642],{"class":3858,"line":3946},[3856,17643,4153],{"emptyLinePlaceholder":4152},[3856,17645,17646,17648,17650,17653,17655,17657],{"class":3858,"line":3952},[3856,17647,4200],{"class":4046},[3856,17649,3981],{"class":3870},[3856,17651,17652],{"class":3866},"isBrokenNumber",[3856,17654,3871],{"class":3870},[3856,17656,5028],{"class":3874},[3856,17658,6531],{"class":3870},[3856,17660,17661],{"class":3858,"line":3958},[3856,17662,17663],{"class":3903},"  \u002F\u002F TypeScript думає, що x — number\n",[3856,17665,17666,17668,17670,17672,17674,17676,17678,17680,17682,17684,17686],{"class":3858,"line":4138},[3856,17667,3922],{"class":3874},[3856,17669,3925],{"class":3870},[3856,17671,3928],{"class":3866},[3856,17673,3871],{"class":3870},[3856,17675,5028],{"class":3874},[3856,17677,3925],{"class":3870},[3856,17679,4123],{"class":3866},[3856,17681,3871],{"class":3870},[3856,17683,4129],{"class":4128},[3856,17685,4626],{"class":3870},[3856,17687,17688],{"class":3903},"\u002F\u002F Runtime Error!\n",[3856,17690,17691],{"class":3858,"line":4144},[3856,17692,3961],{"class":3870},[3843,17694,17695,17698,17699,17701],{},[3793,17696,17697],{},"Правило:"," Завжди переконуйтеся, що логіка перевірки ",[3793,17700,12267],{}," відповідає типу у type predicate.",[17015,17703,17705,17710,17718,17747,17761,17767],{"icon":17017,"label":17704},"❓ Навіщо потрібні discriminated unions, якщо є оператор in?",[3843,17706,6263,17707,17709],{},[3761,17708,3770],{}," працює, але має недоліки:",[4456,17711,17712],{},[3749,17713,17714,17717],{},[3793,17715,17716],{},"Неоднозначність:"," Об'єкт може мати властивості з кількох варіантів:",[3847,17719,17721],{"className":3849,"code":17720,"language":3851,"meta":3852,"style":3852},"let shape = { radius: 5, side: 4 };  \u002F\u002F це Circle чи Square?\n",[3761,17722,17723],{"__ignoreMap":3852},[3856,17724,17725,17727,17729,17731,17733,17735,17737,17739,17741,17744],{"class":3858,"line":3859},[3856,17726,6494],{"class":3862},[3856,17728,7603],{"class":3874},[3856,17730,7426],{"class":3870},[3856,17732,7711],{"class":3874},[3856,17734,7714],{"class":4128},[3856,17736,3764],{"class":3870},[3856,17738,7744],{"class":3874},[3856,17740,7747],{"class":4128},[3856,17742,17743],{"class":3870}," };  ",[3856,17745,17746],{"class":3903},"\u002F\u002F це Circle чи Square?\n",[4456,17748,17749,17755],{"start":3900},[3749,17750,17751,17754],{},[3793,17752,17753],{},"Громіздкість:"," Багато перевірок для складних union types.",[3749,17756,17757,17760],{},[3793,17758,17759],{},"Немає exhaustiveness checking:"," TypeScript не попередить, якщо ви забули обробити варіант.",[3843,17762,17763,17766],{},[3793,17764,17765],{},"Discriminated unions"," вирішують ці проблеми:",[3847,17768,17770],{"className":3849,"code":17769,"language":3851,"meta":3852,"style":3852},"type Shape =\n  | { kind: \"circle\"; radius: number }\n  | { kind: \"square\"; side: number };\n\nfunction area(shape: Shape): number {\n  switch (shape.kind) {  \u002F\u002F одна перевірка\n    case \"circle\":\n      return Math.PI * shape.radius ** 2;\n    case \"square\":\n      return shape.side ** 2;\n    default:\n      const exhaustiveCheck: never = shape;  \u002F\u002F гарантія повноти\n  }\n}\n",[3761,17771,17772,17781,17802,17822,17826,17847,17864,17872,17896,17904,17920,17926,17945,17949],{"__ignoreMap":3852},[3856,17773,17774,17776,17778],{"class":3858,"line":3859},[3856,17775,9570],{"class":3862},[3856,17777,9710],{"class":3881},[3856,17779,17780],{"class":3870}," =\n",[3856,17782,17783,17786,17788,17790,17792,17794,17796,17798,17800],{"class":3858,"line":3900},[3856,17784,17785],{"class":3870},"  | { ",[3856,17787,7548],{"class":3874},[3856,17789,3878],{"class":3870},[3856,17791,7553],{"class":4060},[3856,17793,7556],{"class":3870},[3856,17795,7559],{"class":3874},[3856,17797,3878],{"class":3870},[3856,17799,3888],{"class":3881},[3856,17801,9359],{"class":3870},[3856,17803,17804,17806,17808,17810,17812,17814,17816,17818,17820],{"class":3858,"line":3907},[3856,17805,17785],{"class":3870},[3856,17807,7548],{"class":3874},[3856,17809,3878],{"class":3870},[3856,17811,7573],{"class":4060},[3856,17813,7556],{"class":3870},[3856,17815,7578],{"class":3874},[3856,17817,3878],{"class":3870},[3856,17819,3888],{"class":3881},[3856,17821,7443],{"class":3870},[3856,17823,17824],{"class":3858,"line":3913},[3856,17825,4153],{"emptyLinePlaceholder":4152},[3856,17827,17828,17830,17833,17835,17837,17839,17841,17843,17845],{"class":3858,"line":3919},[3856,17829,3863],{"class":3862},[3856,17831,17832],{"class":3866}," area",[3856,17834,3871],{"class":3870},[3856,17836,7542],{"class":3874},[3856,17838,3878],{"class":3870},[3856,17840,9768],{"class":3881},[3856,17842,3891],{"class":3870},[3856,17844,3888],{"class":3881},[3856,17846,3897],{"class":3870},[3856,17848,17849,17851,17853,17855,17857,17859,17861],{"class":3858,"line":3946},[3856,17850,7183],{"class":4046},[3856,17852,3981],{"class":3870},[3856,17854,7542],{"class":3874},[3856,17856,3925],{"class":3870},[3856,17858,7548],{"class":3874},[3856,17860,5347],{"class":3870},[3856,17862,17863],{"class":3903},"\u002F\u002F одна перевірка\n",[3856,17865,17866,17868,17870],{"class":3858,"line":3952},[3856,17867,7194],{"class":4046},[3856,17869,7706],{"class":4060},[3856,17871,7200],{"class":3870},[3856,17873,17874,17876,17878,17880,17882,17884,17886,17888,17890,17892,17894],{"class":3858,"line":3958},[3856,17875,9806],{"class":4046},[3856,17877,7622],{"class":3874},[3856,17879,3925],{"class":3870},[3856,17881,7627],{"class":7331},[3856,17883,7630],{"class":3870},[3856,17885,7542],{"class":3874},[3856,17887,3925],{"class":3870},[3856,17889,7559],{"class":3874},[3856,17891,7639],{"class":3870},[3856,17893,4129],{"class":4128},[3856,17895,4931],{"class":3870},[3856,17897,17898,17900,17902],{"class":3858,"line":4138},[3856,17899,7194],{"class":4046},[3856,17901,7739],{"class":4060},[3856,17903,7200],{"class":3870},[3856,17905,17906,17908,17910,17912,17914,17916,17918],{"class":3858,"line":4144},[3856,17907,9806],{"class":4046},[3856,17909,7603],{"class":3874},[3856,17911,3925],{"class":3870},[3856,17913,7578],{"class":3874},[3856,17915,7639],{"class":3870},[3856,17917,4129],{"class":4128},[3856,17919,4931],{"class":3870},[3856,17921,17922,17924],{"class":3858,"line":4149},[3856,17923,7316],{"class":4046},[3856,17925,7200],{"class":3870},[3856,17927,17928,17930,17932,17934,17936,17938,17940,17942],{"class":3858,"line":4156},[3856,17929,7328],{"class":3862},[3856,17931,7332],{"class":7331},[3856,17933,3878],{"class":3870},[3856,17935,7337],{"class":3881},[3856,17937,6507],{"class":3870},[3856,17939,7542],{"class":3874},[3856,17941,6478],{"class":3870},[3856,17943,17944],{"class":3903},"\u002F\u002F гарантія повноти\n",[3856,17946,17947],{"class":3858,"line":4173},[3856,17948,4141],{"class":3870},[3856,17950,17951],{"class":3858,"line":4288},[3856,17952,3961],{"class":3870},[17015,17954,17956,17961,17966,18014,18019,18067,18072,18128],{"icon":17017,"label":17955},"❓ Як працює optional chaining (?.) з масивами та функціями?",[3843,17957,17958,17960],{},[3793,17959,13609],{}," працює не лише для властивостей об'єктів:",[3843,17962,17963],{},[3793,17964,17965],{},"З масивами:",[3847,17967,17968],{"className":3849,"code":13871,"language":3851,"meta":3852,"style":3852},[3761,17969,17970,17990,17994,18010],{"__ignoreMap":3852},[3856,17971,17972,17974,17976,17978,17980,17982,17984,17986,17988],{"class":3858,"line":3859},[3856,17973,6494],{"class":3862},[3856,17975,13880],{"class":3874},[3856,17977,3878],{"class":3870},[3856,17979,3882],{"class":3881},[3856,17981,13887],{"class":3870},[3856,17983,5299],{"class":3881},[3856,17985,6507],{"class":3870},[3856,17987,13894],{"class":3866},[3856,17989,4849],{"class":3870},[3856,17991,17992],{"class":3858,"line":3900},[3856,17993,4153],{"emptyLinePlaceholder":4152},[3856,17995,17996,17998,18000,18002,18004,18006,18008],{"class":3858,"line":3907},[3856,17997,6494],{"class":3862},[3856,17999,13907],{"class":3874},[3856,18001,6507],{"class":3870},[3856,18003,13912],{"class":3874},[3856,18005,13915],{"class":3870},[3856,18007,5550],{"class":4128},[3856,18009,12499],{"class":3870},[3856,18011,18012],{"class":3858,"line":3913},[3856,18013,13924],{"class":3903},[3843,18015,18016],{},[3793,18017,18018],{},"З функціями:",[3847,18020,18022],{"className":3849,"code":18021,"language":3851,"meta":3852,"style":3852},"let callback: (() => void) | undefined = getCallback();\n\ncallback?.();\n\u002F\u002F Викличе функцію лише якщо вона не undefined\n",[3761,18023,18024,18051,18055,18062],{"__ignoreMap":3852},[3856,18025,18026,18028,18031,18034,18036,18039,18042,18044,18046,18049],{"class":3858,"line":3859},[3856,18027,6494],{"class":3862},[3856,18029,18030],{"class":3874}," callback",[3856,18032,18033],{"class":3870},": (() ",[3856,18035,11398],{"class":3862},[3856,18037,18038],{"class":3881}," void",[3856,18040,18041],{"class":3870},") | ",[3856,18043,5139],{"class":3881},[3856,18045,6507],{"class":3870},[3856,18047,18048],{"class":3866},"getCallback",[3856,18050,4849],{"class":3870},[3856,18052,18053],{"class":3858,"line":3900},[3856,18054,4153],{"emptyLinePlaceholder":4152},[3856,18056,18057,18060],{"class":3858,"line":3907},[3856,18058,18059],{"class":3866},"callback",[3856,18061,13858],{"class":3870},[3856,18063,18064],{"class":3858,"line":3913},[3856,18065,18066],{"class":3903},"\u002F\u002F Викличе функцію лише якщо вона не undefined\n",[3843,18068,18069],{},[3793,18070,18071],{},"Ланцюжок:",[3847,18073,18075],{"className":3849,"code":18074,"language":3851,"meta":3852,"style":3852},"let user: { getName?: () => string } | null = getUser();\n\nlet name = user?.getName?.();\n\u002F\u002F Перевіряє: user не null? getName існує? Викликає getName()\n",[3761,18076,18077,18103,18107,18123],{"__ignoreMap":3852},[3856,18078,18079,18081,18083,18085,18087,18089,18091,18093,18095,18097,18099,18101],{"class":3858,"line":3859},[3856,18080,6494],{"class":3862},[3856,18082,7423],{"class":3874},[3856,18084,7545],{"class":3870},[3856,18086,13813],{"class":3866},[3856,18088,13816],{"class":3870},[3856,18090,11398],{"class":3862},[3856,18092,6402],{"class":3881},[3856,18094,13823],{"class":3870},[3856,18096,5299],{"class":3881},[3856,18098,6507],{"class":3870},[3856,18100,13657],{"class":3866},[3856,18102,4849],{"class":3870},[3856,18104,18105],{"class":3858,"line":3900},[3856,18106,4153],{"emptyLinePlaceholder":4152},[3856,18108,18109,18111,18113,18115,18117,18119,18121],{"class":3858,"line":3907},[3856,18110,6494],{"class":3862},[3856,18112,13847],{"class":3874},[3856,18114,6507],{"class":3870},[3856,18116,13694],{"class":3874},[3856,18118,13612],{"class":3870},[3856,18120,13813],{"class":3866},[3856,18122,13858],{"class":3870},[3856,18124,18125],{"class":3858,"line":3913},[3856,18126,18127],{"class":3903},"\u002F\u002F Перевіряє: user не null? getName існує? Викликає getName()\n",[3843,18129,18130,18131,18133,18134,3925],{},"Результат завжди може бути ",[3761,18132,5139],{},", тому тип буде ",[3761,18135,18136],{},"T | undefined",[18138,18139,18140],"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 .spJ8K, html code.shiki .spJ8K{--shiki-light:#008000;--shiki-default:#6A9955;--shiki-dark:#6A9955}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 .s8xlr, html code.shiki .s8xlr{--shiki-light:#AF00DB;--shiki-default:#C586C0;--shiki-dark:#C586C0}html pre.shiki code .sbdoH, html code.shiki .sbdoH{--shiki-light:#A31515;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .sJj4R, html code.shiki .sJj4R{--shiki-light:#098658;--shiki-default:#B5CEA8;--shiki-dark:#B5CEA8}html pre.shiki code .sD7JJ, html code.shiki .sD7JJ{--shiki-light:#000000FF;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .s-QsJ, html code.shiki .s-QsJ{--shiki-light:#0070C1;--shiki-default:#4FC1FF;--shiki-dark:#4FC1FF}html pre.shiki code .shsrj, html code.shiki .shsrj{--shiki-light:#811F3F;--shiki-default:#D16969;--shiki-dark:#D16969}html pre.shiki code .siofk, html code.shiki .siofk{--shiki-light:#EE0000;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .sAV2Q, html code.shiki .sAV2Q{--shiki-light:#D16969;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .sYsli, html code.shiki .sYsli{--shiki-light:#000000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .sjcCO, html code.shiki .sjcCO{--shiki-light:#EE0000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .s5IvJ, html code.shiki .s5IvJ{--shiki-light:#000000;--shiki-default:#C8C8C8;--shiki-dark:#C8C8C8}",{"title":3852,"searchDepth":3900,"depth":3900,"links":18142},[18143,18148,18154,18159,18164,18169,18174,18181,18189,18195,18201,18206],{"id":3835,"depth":3900,"text":3836,"children":18144},[18145,18146,18147],{"id":3840,"depth":3907,"text":3841},{"id":3993,"depth":3907,"text":3994},{"id":4446,"depth":3907,"text":4447},{"id":4501,"depth":3900,"text":4502,"children":18149},[18150,18151,18152,18153],{"id":4505,"depth":3907,"text":4506},{"id":4772,"depth":3907,"text":4773},{"id":5130,"depth":3907,"text":5131},{"id":5465,"depth":3907,"text":5466},{"id":5506,"depth":3900,"text":5507,"children":18155},[18156,18157,18158],{"id":5510,"depth":3907,"text":5511},{"id":5779,"depth":3907,"text":5780},{"id":6353,"depth":3907,"text":6354},{"id":6563,"depth":3900,"text":6564,"children":18160},[18161,18162,18163],{"id":6567,"depth":3907,"text":6568},{"id":6896,"depth":3907,"text":6897},{"id":7133,"depth":3907,"text":7134},{"id":7401,"depth":3900,"text":7402,"children":18165},[18166,18167,18168],{"id":7405,"depth":3907,"text":7406},{"id":7518,"depth":3907,"text":7519},{"id":8014,"depth":3907,"text":8015},{"id":8241,"depth":3900,"text":8242,"children":18170},[18171,18172,18173],{"id":8245,"depth":3907,"text":8246},{"id":8515,"depth":3907,"text":8516},{"id":8892,"depth":3907,"text":8893},{"id":9313,"depth":3900,"text":9314,"children":18175},[18176,18177,18178,18179,18180],{"id":9317,"depth":3907,"text":9318},{"id":9530,"depth":3907,"text":9531},{"id":10264,"depth":3907,"text":10265},{"id":10304,"depth":3907,"text":10305},{"id":10738,"depth":3907,"text":10739},{"id":10783,"depth":3900,"text":10784,"children":18182},[18183,18184,18185,18186,18187,18188],{"id":10787,"depth":3907,"text":10788},{"id":10981,"depth":3907,"text":10982},{"id":11242,"depth":3907,"text":11243},{"id":11550,"depth":3907,"text":11551},{"id":11890,"depth":3907,"text":11891},{"id":12271,"depth":3907,"text":12272},{"id":12744,"depth":3900,"text":12745,"children":18190},[18191,18192,18193,18194],{"id":12748,"depth":3907,"text":12749},{"id":12961,"depth":3907,"text":12962},{"id":13188,"depth":3907,"text":13189},{"id":13603,"depth":3907,"text":13604},{"id":14100,"depth":3900,"text":14101,"children":18196},[18197,18198,18199,18200],{"id":14104,"depth":3907,"text":14105},{"id":14386,"depth":3907,"text":14387},{"id":14573,"depth":3907,"text":14574},{"id":14905,"depth":3907,"text":14906},{"id":15119,"depth":3900,"text":15120,"children":18202},[18203,18204,18205],{"id":15123,"depth":3907,"text":15124},{"id":15922,"depth":3907,"text":15923},{"id":16504,"depth":3907,"text":16505},{"id":16849,"depth":3900,"text":16850},"Глибокий розбір механізмів звуження типів у TypeScript: type guards, typeof, instanceof, truthiness, equality checks та control flow analysis","md",null,{},{"title":3635,"description":18207},"tNuMgOSPEjCwQQukGRsmq41tPb4GEk3vfbxtpoIcx6s",[18214,18216],{"title":3631,"path":3632,"stem":3633,"description":18215,"children":-1},"Глибокий розбір union типів, intersection типів та літеральних типів у TypeScript: комбінування типів, звуження та практичне застосування",{"title":3639,"path":3640,"stem":3641,"description":18217,"children":-1},"Глибокий розбір типізації функцій у TypeScript: параметри, повернення значень, опціональні параметри, rest parameters, перевантаження функцій та callback типізація",1788081920633]