[{"data":1,"prerenderedAt":6140},["ShallowReactive",2],{"navigation_docs":3,"-tu-hoc-typescript-advanced-types":420,"-tu-hoc-typescript-advanced-types-surround":6135},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":6128,"extension":6129,"links":6130,"meta":6131,"navigation":6132,"path":303,"seo":6133,"stem":304,"__hash__":6134},"docs\u002F2.tu-hoc\u002F2.typescript\u002F3.advanced-types.md","Advanced types — Generic, Conditional, Mapped, Utility",{"type":424,"value":425,"toc":6091},"minimark",[426,431,871,878,1235,1276,1280,1412,1419,1661,1676,1684,2086,2094,2098,2391,2395,2668,2671,2758,2762,2932,3265,3426,3433,3734,3738,4146,4179,4183,4333,4337,4342,4494,4498,4627,4631,4921,4925,4936,4940,5013,5017,5060,5064,5147,5151,5216,5220,5256,5437,5441,5542,5546,5612,5616,5622,5673,5676,5728,5732,5858,5864,5928,5932,6047,6080,6087],[427,428,430],"h2",{"id":429},"_1-generic-cốt-lõi","1. Generic — cốt lõi",[432,433,438],"pre",{"className":434,"code":435,"language":436,"meta":437,"style":437},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","function identity\u003CT>(x: T): T {\n  return x;\n}\n\nidentity\u003Cnumber>(42);\nidentity(\"hello\");                   \u002F\u002F type inferred\n\n\u002F\u002F Generic function với nhiều param\nfunction pair\u003CA, B>(a: A, b: B): [A, B] {\n  return [a, b];\n}\n\n\u002F\u002F Generic class\nclass Box\u003CT> {\n  constructor(public value: T) {}\n  map\u003CU>(fn: (x: T) => U): Box\u003CU> {\n    return new Box(fn(this.value));\n  }\n}\n\n\u002F\u002F Generic interface\ninterface Repo\u003CT> {\n  findById(id: number): T | undefined;\n  add(item: T): void;\n}\n","typescript","",[439,440,441,483,497,503,510,536,561,566,572,627,646,651,656,662,679,702,749,777,783,788,793,799,816,844,866],"code",{"__ignoreMap":437},[442,443,446,450,454,458,462,465,469,472,475,478,480],"span",{"class":444,"line":445},"line",1,[442,447,449],{"class":448},"spNyl","function",[442,451,453],{"class":452},"s2Zo4"," identity",[442,455,457],{"class":456},"sMK4o","\u003C",[442,459,461],{"class":460},"sBMFI","T",[442,463,464],{"class":456},">(",[442,466,468],{"class":467},"sHdIc","x",[442,470,471],{"class":456},":",[442,473,474],{"class":460}," T",[442,476,477],{"class":456},"):",[442,479,474],{"class":460},[442,481,482],{"class":456}," {\n",[442,484,486,490,494],{"class":444,"line":485},2,[442,487,489],{"class":488},"s7zQu","  return",[442,491,493],{"class":492},"sTEyZ"," x",[442,495,496],{"class":456},";\n",[442,498,500],{"class":444,"line":499},3,[442,501,502],{"class":456},"}\n",[442,504,506],{"class":444,"line":505},4,[442,507,509],{"emptyLinePlaceholder":508},true,"\n",[442,511,513,516,518,521,524,527,531,534],{"class":444,"line":512},5,[442,514,515],{"class":452},"identity",[442,517,457],{"class":456},[442,519,520],{"class":460},"number",[442,522,523],{"class":456},">",[442,525,526],{"class":492},"(",[442,528,530],{"class":529},"sbssI","42",[442,532,533],{"class":492},")",[442,535,496],{"class":456},[442,537,539,541,543,546,550,552,554,557],{"class":444,"line":538},6,[442,540,515],{"class":452},[442,542,526],{"class":492},[442,544,545],{"class":456},"\"",[442,547,549],{"class":548},"sfazB","hello",[442,551,545],{"class":456},[442,553,533],{"class":492},[442,555,556],{"class":456},";",[442,558,560],{"class":559},"sHwdD","                   \u002F\u002F type inferred\n",[442,562,564],{"class":444,"line":563},7,[442,565,509],{"emptyLinePlaceholder":508},[442,567,569],{"class":444,"line":568},8,[442,570,571],{"class":559},"\u002F\u002F Generic function với nhiều param\n",[442,573,575,577,580,582,585,588,591,593,596,598,601,603,606,608,610,612,615,617,619,621,624],{"class":444,"line":574},9,[442,576,449],{"class":448},[442,578,579],{"class":452}," pair",[442,581,457],{"class":456},[442,583,584],{"class":460},"A",[442,586,587],{"class":456},",",[442,589,590],{"class":460}," B",[442,592,464],{"class":456},[442,594,595],{"class":467},"a",[442,597,471],{"class":456},[442,599,600],{"class":460}," A",[442,602,587],{"class":456},[442,604,605],{"class":467}," b",[442,607,471],{"class":456},[442,609,590],{"class":460},[442,611,477],{"class":456},[442,613,614],{"class":492}," [",[442,616,584],{"class":460},[442,618,587],{"class":456},[442,620,590],{"class":460},[442,622,623],{"class":492},"] ",[442,625,626],{"class":456},"{\n",[442,628,630,632,635,637,639,641,644],{"class":444,"line":629},10,[442,631,489],{"class":488},[442,633,614],{"class":634},"swJcz",[442,636,595],{"class":492},[442,638,587],{"class":456},[442,640,605],{"class":492},[442,642,643],{"class":634},"]",[442,645,496],{"class":456},[442,647,649],{"class":444,"line":648},11,[442,650,502],{"class":456},[442,652,654],{"class":444,"line":653},12,[442,655,509],{"emptyLinePlaceholder":508},[442,657,659],{"class":444,"line":658},13,[442,660,661],{"class":559},"\u002F\u002F Generic class\n",[442,663,665,668,671,673,675,677],{"class":444,"line":664},14,[442,666,667],{"class":448},"class",[442,669,670],{"class":460}," Box",[442,672,457],{"class":456},[442,674,461],{"class":460},[442,676,523],{"class":456},[442,678,482],{"class":456},[442,680,682,685,687,690,693,695,697,699],{"class":444,"line":681},15,[442,683,684],{"class":448},"  constructor",[442,686,526],{"class":456},[442,688,689],{"class":448},"public",[442,691,692],{"class":467}," value",[442,694,471],{"class":456},[442,696,474],{"class":460},[442,698,533],{"class":456},[442,700,701],{"class":456}," {}\n",[442,703,705,708,710,713,715,718,720,723,725,727,729,731,734,737,739,741,743,745,747],{"class":444,"line":704},16,[442,706,707],{"class":634},"  map",[442,709,457],{"class":456},[442,711,712],{"class":460},"U",[442,714,464],{"class":456},[442,716,717],{"class":452},"fn",[442,719,471],{"class":456},[442,721,722],{"class":456}," (",[442,724,468],{"class":467},[442,726,471],{"class":456},[442,728,474],{"class":460},[442,730,533],{"class":456},[442,732,733],{"class":448}," =>",[442,735,736],{"class":460}," U",[442,738,477],{"class":456},[442,740,670],{"class":460},[442,742,457],{"class":456},[442,744,712],{"class":460},[442,746,523],{"class":456},[442,748,482],{"class":456},[442,750,752,755,758,760,762,764,766,769,772,775],{"class":444,"line":751},17,[442,753,754],{"class":488},"    return",[442,756,757],{"class":456}," new",[442,759,670],{"class":452},[442,761,526],{"class":634},[442,763,717],{"class":452},[442,765,526],{"class":634},[442,767,768],{"class":456},"this.",[442,770,771],{"class":492},"value",[442,773,774],{"class":634},"))",[442,776,496],{"class":456},[442,778,780],{"class":444,"line":779},18,[442,781,782],{"class":456},"  }\n",[442,784,786],{"class":444,"line":785},19,[442,787,502],{"class":456},[442,789,791],{"class":444,"line":790},20,[442,792,509],{"emptyLinePlaceholder":508},[442,794,796],{"class":444,"line":795},21,[442,797,798],{"class":559},"\u002F\u002F Generic interface\n",[442,800,802,805,808,810,812,814],{"class":444,"line":801},22,[442,803,804],{"class":448},"interface",[442,806,807],{"class":460}," Repo",[442,809,457],{"class":456},[442,811,461],{"class":460},[442,813,523],{"class":456},[442,815,482],{"class":456},[442,817,819,822,824,827,829,832,834,836,839,842],{"class":444,"line":818},23,[442,820,821],{"class":634},"  findById",[442,823,526],{"class":456},[442,825,826],{"class":467},"id",[442,828,471],{"class":456},[442,830,831],{"class":460}," number",[442,833,477],{"class":456},[442,835,474],{"class":460},[442,837,838],{"class":456}," |",[442,840,841],{"class":460}," undefined",[442,843,496],{"class":456},[442,845,847,850,852,855,857,859,861,864],{"class":444,"line":846},24,[442,848,849],{"class":634},"  add",[442,851,526],{"class":456},[442,853,854],{"class":467},"item",[442,856,471],{"class":456},[442,858,474],{"class":460},[442,860,477],{"class":456},[442,862,863],{"class":460}," void",[442,865,496],{"class":456},[442,867,869],{"class":444,"line":868},25,[442,870,502],{"class":456},[427,872,874,875],{"id":873},"_2-generic-constraint-extends","2. Generic constraint — ",[439,876,877],{},"extends",[432,879,881],{"className":434,"code":880,"language":436,"meta":437,"style":437},"\u002F\u002F T phải có property \"length\"\nfunction longest\u003CT extends { length: number }>(a: T, b: T): T {\n  return a.length >= b.length ? a : b;\n}\n\nlongest(\"foo\", \"bars\");              \u002F\u002F OK — string có length\nlongest([1, 2], [1, 2, 3]);          \u002F\u002F OK — array có length\nlongest(1, 2);                       \u002F\u002F ❌ — number không có length\n\n\u002F\u002F keyof constraint — key của object\nfunction get\u003CT, K extends keyof T>(obj: T, key: K): T[K] {\n  return obj[key];\n}\nconst user = { id: 1, name: \"Alice\" };\nget(user, \"name\");                   \u002F\u002F string\nget(user, \"age\");                    \u002F\u002F ❌ — \"age\" không phải key của user\n",[439,882,883,888,935,969,973,977,1008,1048,1067,1071,1076,1131,1147,1151,1189,1213],{"__ignoreMap":437},[442,884,885],{"class":444,"line":445},[442,886,887],{"class":559},"\u002F\u002F T phải có property \"length\"\n",[442,889,890,892,895,897,899,902,905,908,910,912,915,917,919,921,923,925,927,929,931,933],{"class":444,"line":485},[442,891,449],{"class":448},[442,893,894],{"class":452}," longest",[442,896,457],{"class":456},[442,898,461],{"class":460},[442,900,901],{"class":448}," extends",[442,903,904],{"class":456}," {",[442,906,907],{"class":634}," length",[442,909,471],{"class":456},[442,911,831],{"class":460},[442,913,914],{"class":456}," }>(",[442,916,595],{"class":467},[442,918,471],{"class":456},[442,920,474],{"class":460},[442,922,587],{"class":456},[442,924,605],{"class":467},[442,926,471],{"class":456},[442,928,474],{"class":460},[442,930,477],{"class":456},[442,932,474],{"class":460},[442,934,482],{"class":456},[442,936,937,939,942,945,948,951,953,955,957,960,962,965,967],{"class":444,"line":499},[442,938,489],{"class":488},[442,940,941],{"class":492}," a",[442,943,944],{"class":456},".",[442,946,947],{"class":492},"length",[442,949,950],{"class":456}," >=",[442,952,605],{"class":492},[442,954,944],{"class":456},[442,956,947],{"class":492},[442,958,959],{"class":456}," ?",[442,961,941],{"class":492},[442,963,964],{"class":456}," :",[442,966,605],{"class":492},[442,968,496],{"class":456},[442,970,971],{"class":444,"line":505},[442,972,502],{"class":456},[442,974,975],{"class":444,"line":512},[442,976,509],{"emptyLinePlaceholder":508},[442,978,979,982,984,986,989,991,993,996,999,1001,1003,1005],{"class":444,"line":538},[442,980,981],{"class":452},"longest",[442,983,526],{"class":492},[442,985,545],{"class":456},[442,987,988],{"class":548},"foo",[442,990,545],{"class":456},[442,992,587],{"class":456},[442,994,995],{"class":456}," \"",[442,997,998],{"class":548},"bars",[442,1000,545],{"class":456},[442,1002,533],{"class":492},[442,1004,556],{"class":456},[442,1006,1007],{"class":559},"              \u002F\u002F OK — string có length\n",[442,1009,1010,1012,1015,1018,1020,1023,1025,1027,1029,1031,1033,1035,1037,1040,1043,1045],{"class":444,"line":563},[442,1011,981],{"class":452},[442,1013,1014],{"class":492},"([",[442,1016,1017],{"class":529},"1",[442,1019,587],{"class":456},[442,1021,1022],{"class":529}," 2",[442,1024,643],{"class":492},[442,1026,587],{"class":456},[442,1028,614],{"class":492},[442,1030,1017],{"class":529},[442,1032,587],{"class":456},[442,1034,1022],{"class":529},[442,1036,587],{"class":456},[442,1038,1039],{"class":529}," 3",[442,1041,1042],{"class":492},"])",[442,1044,556],{"class":456},[442,1046,1047],{"class":559},"          \u002F\u002F OK — array có length\n",[442,1049,1050,1052,1054,1056,1058,1060,1062,1064],{"class":444,"line":568},[442,1051,981],{"class":452},[442,1053,526],{"class":492},[442,1055,1017],{"class":529},[442,1057,587],{"class":456},[442,1059,1022],{"class":529},[442,1061,533],{"class":492},[442,1063,556],{"class":456},[442,1065,1066],{"class":559},"                       \u002F\u002F ❌ — number không có length\n",[442,1068,1069],{"class":444,"line":574},[442,1070,509],{"emptyLinePlaceholder":508},[442,1072,1073],{"class":444,"line":629},[442,1074,1075],{"class":559},"\u002F\u002F keyof constraint — key của object\n",[442,1077,1078,1080,1083,1085,1087,1089,1092,1094,1097,1099,1101,1104,1106,1108,1110,1113,1115,1117,1119,1121,1124,1127,1129],{"class":444,"line":648},[442,1079,449],{"class":448},[442,1081,1082],{"class":452}," get",[442,1084,457],{"class":456},[442,1086,461],{"class":460},[442,1088,587],{"class":456},[442,1090,1091],{"class":460}," K",[442,1093,901],{"class":448},[442,1095,1096],{"class":456}," keyof",[442,1098,474],{"class":460},[442,1100,464],{"class":456},[442,1102,1103],{"class":467},"obj",[442,1105,471],{"class":456},[442,1107,474],{"class":460},[442,1109,587],{"class":456},[442,1111,1112],{"class":467}," key",[442,1114,471],{"class":456},[442,1116,1091],{"class":460},[442,1118,477],{"class":456},[442,1120,474],{"class":460},[442,1122,1123],{"class":492},"[",[442,1125,1126],{"class":460},"K",[442,1128,623],{"class":492},[442,1130,626],{"class":456},[442,1132,1133,1135,1138,1140,1143,1145],{"class":444,"line":653},[442,1134,489],{"class":488},[442,1136,1137],{"class":492}," obj",[442,1139,1123],{"class":634},[442,1141,1142],{"class":492},"key",[442,1144,643],{"class":634},[442,1146,496],{"class":456},[442,1148,1149],{"class":444,"line":658},[442,1150,502],{"class":456},[442,1152,1153,1156,1159,1162,1164,1167,1169,1172,1174,1177,1179,1181,1184,1186],{"class":444,"line":664},[442,1154,1155],{"class":448},"const",[442,1157,1158],{"class":492}," user ",[442,1160,1161],{"class":456},"=",[442,1163,904],{"class":456},[442,1165,1166],{"class":634}," id",[442,1168,471],{"class":456},[442,1170,1171],{"class":529}," 1",[442,1173,587],{"class":456},[442,1175,1176],{"class":634}," name",[442,1178,471],{"class":456},[442,1180,995],{"class":456},[442,1182,1183],{"class":548},"Alice",[442,1185,545],{"class":456},[442,1187,1188],{"class":456}," };\n",[442,1190,1191,1194,1197,1199,1201,1204,1206,1208,1210],{"class":444,"line":681},[442,1192,1193],{"class":452},"get",[442,1195,1196],{"class":492},"(user",[442,1198,587],{"class":456},[442,1200,995],{"class":456},[442,1202,1203],{"class":548},"name",[442,1205,545],{"class":456},[442,1207,533],{"class":492},[442,1209,556],{"class":456},[442,1211,1212],{"class":559},"                   \u002F\u002F string\n",[442,1214,1215,1217,1219,1221,1223,1226,1228,1230,1232],{"class":444,"line":704},[442,1216,1193],{"class":452},[442,1218,1196],{"class":492},[442,1220,587],{"class":456},[442,1222,995],{"class":456},[442,1224,1225],{"class":548},"age",[442,1227,545],{"class":456},[442,1229,533],{"class":492},[442,1231,556],{"class":456},[442,1233,1234],{"class":559},"                    \u002F\u002F ❌ — \"age\" không phải key của user\n",[1236,1237,1240,1256],"callout",{"color":1238,"icon":1239},"warning","i-lucide-star",[1241,1242,1243,1244,1248,1249],"p",{},"⭐ ",[1245,1246,1247],"strong",{},"Câu PV cực hay:"," ",[1250,1251,545,1252,1255],"em",{},[439,1253,1254],{},"keyof T"," là gì?\"",[1257,1258,1259],"blockquote",{},[1241,1260,545,1261,1263,1264,1267,1268,1271,1272,1275],{},[439,1262,1254],{}," trả về ",[1245,1265,1266],{},"union các key của T"," dưới dạng string literal type. Ví dụ ",[439,1269,1270],{},"keyof { id: number; name: string }"," = ",[439,1273,1274],{},"\"id\" | \"name\"",". Dùng để type-safe access property qua tên key — phổ biến với pattern get\u002Fset theo path.\"",[427,1277,1279],{"id":1278},"_3-generic-default","3. Generic default",[432,1281,1283],{"className":434,"code":1282,"language":436,"meta":437,"style":437},"interface ApiResponse\u003CTData = unknown, TError = Error> {\n  data: TData;\n  error?: TError;\n}\n\nconst r1: ApiResponse = { data: \"x\" };           \u002F\u002F TData = unknown\nconst r2: ApiResponse\u003CUser> = { data: {...} };\n",[439,1284,1285,1317,1329,1341,1345,1349,1381],{"__ignoreMap":437},[442,1286,1287,1289,1292,1294,1297,1300,1303,1305,1308,1310,1313,1315],{"class":444,"line":445},[442,1288,804],{"class":448},[442,1290,1291],{"class":460}," ApiResponse",[442,1293,457],{"class":456},[442,1295,1296],{"class":460},"TData",[442,1298,1299],{"class":456}," =",[442,1301,1302],{"class":460}," unknown",[442,1304,587],{"class":456},[442,1306,1307],{"class":460}," TError",[442,1309,1299],{"class":456},[442,1311,1312],{"class":460}," Error",[442,1314,523],{"class":456},[442,1316,482],{"class":456},[442,1318,1319,1322,1324,1327],{"class":444,"line":485},[442,1320,1321],{"class":634},"  data",[442,1323,471],{"class":456},[442,1325,1326],{"class":460}," TData",[442,1328,496],{"class":456},[442,1330,1331,1334,1337,1339],{"class":444,"line":499},[442,1332,1333],{"class":634},"  error",[442,1335,1336],{"class":456},"?:",[442,1338,1307],{"class":460},[442,1340,496],{"class":456},[442,1342,1343],{"class":444,"line":505},[442,1344,502],{"class":456},[442,1346,1347],{"class":444,"line":512},[442,1348,509],{"emptyLinePlaceholder":508},[442,1350,1351,1353,1356,1358,1360,1362,1364,1367,1369,1371,1373,1375,1378],{"class":444,"line":538},[442,1352,1155],{"class":448},[442,1354,1355],{"class":492}," r1",[442,1357,471],{"class":456},[442,1359,1291],{"class":460},[442,1361,1299],{"class":456},[442,1363,904],{"class":456},[442,1365,1366],{"class":634}," data",[442,1368,471],{"class":456},[442,1370,995],{"class":456},[442,1372,468],{"class":548},[442,1374,545],{"class":456},[442,1376,1377],{"class":456}," };",[442,1379,1380],{"class":559},"           \u002F\u002F TData = unknown\n",[442,1382,1383,1385,1388,1390,1392,1394,1397,1399,1401,1403,1405,1407,1410],{"class":444,"line":563},[442,1384,1155],{"class":448},[442,1386,1387],{"class":492}," r2",[442,1389,471],{"class":456},[442,1391,1291],{"class":460},[442,1393,457],{"class":456},[442,1395,1396],{"class":460},"User",[442,1398,523],{"class":456},[442,1400,1299],{"class":456},[442,1402,904],{"class":456},[442,1404,1366],{"class":634},[442,1406,471],{"class":456},[442,1408,1409],{"class":456}," {...}",[442,1411,1188],{"class":456},[427,1413,1415,1416],{"id":1414},"_4-conditional-types-t-extends-u-x-y","4. Conditional types — ",[439,1417,1418],{},"T extends U ? X : Y",[432,1420,1422],{"className":434,"code":1421,"language":436,"meta":437,"style":437},"\u002F\u002F Cơ bản\ntype IsString\u003CT> = T extends string ? \"yes\" : \"no\";\ntype A = IsString\u003C\"hello\">;          \u002F\u002F \"yes\"\ntype B = IsString\u003C42>;               \u002F\u002F \"no\"\n\n\u002F\u002F Distributive — apply cho từng union member\ntype ToArray\u003CT> = T extends any ? T[] : never;\ntype C = ToArray\u003Cstring | number>;   \u002F\u002F string[] | number[]  (không phải (string|number)[])\n\n\u002F\u002F Non-distributive — wrap trong tuple\ntype ToArrayBox\u003CT> = [T] extends [any] ? T[] : never;\ntype D = ToArrayBox\u003Cstring | number>; \u002F\u002F (string | number)[]\n",[439,1423,1424,1429,1472,1496,1515,1519,1524,1560,1585,1589,1594,1637],{"__ignoreMap":437},[442,1425,1426],{"class":444,"line":445},[442,1427,1428],{"class":559},"\u002F\u002F Cơ bản\n",[442,1430,1431,1434,1437,1439,1441,1443,1445,1447,1449,1452,1454,1456,1459,1461,1463,1465,1468,1470],{"class":444,"line":485},[442,1432,1433],{"class":448},"type",[442,1435,1436],{"class":460}," IsString",[442,1438,457],{"class":456},[442,1440,461],{"class":460},[442,1442,523],{"class":456},[442,1444,1299],{"class":456},[442,1446,474],{"class":460},[442,1448,901],{"class":448},[442,1450,1451],{"class":460}," string",[442,1453,959],{"class":456},[442,1455,995],{"class":456},[442,1457,1458],{"class":548},"yes",[442,1460,545],{"class":456},[442,1462,964],{"class":456},[442,1464,995],{"class":456},[442,1466,1467],{"class":548},"no",[442,1469,545],{"class":456},[442,1471,496],{"class":456},[442,1473,1474,1476,1478,1480,1482,1484,1486,1488,1490,1493],{"class":444,"line":499},[442,1475,1433],{"class":448},[442,1477,600],{"class":460},[442,1479,1299],{"class":456},[442,1481,1436],{"class":460},[442,1483,457],{"class":456},[442,1485,545],{"class":456},[442,1487,549],{"class":548},[442,1489,545],{"class":456},[442,1491,1492],{"class":456},">;",[442,1494,1495],{"class":559},"          \u002F\u002F \"yes\"\n",[442,1497,1498,1500,1502,1504,1506,1508,1510,1512],{"class":444,"line":505},[442,1499,1433],{"class":448},[442,1501,590],{"class":460},[442,1503,1299],{"class":456},[442,1505,1436],{"class":460},[442,1507,457],{"class":456},[442,1509,530],{"class":529},[442,1511,1492],{"class":456},[442,1513,1514],{"class":559},"               \u002F\u002F \"no\"\n",[442,1516,1517],{"class":444,"line":512},[442,1518,509],{"emptyLinePlaceholder":508},[442,1520,1521],{"class":444,"line":538},[442,1522,1523],{"class":559},"\u002F\u002F Distributive — apply cho từng union member\n",[442,1525,1526,1528,1531,1533,1535,1537,1539,1541,1543,1546,1548,1550,1553,1555,1558],{"class":444,"line":563},[442,1527,1433],{"class":448},[442,1529,1530],{"class":460}," ToArray",[442,1532,457],{"class":456},[442,1534,461],{"class":460},[442,1536,523],{"class":456},[442,1538,1299],{"class":456},[442,1540,474],{"class":460},[442,1542,901],{"class":448},[442,1544,1545],{"class":460}," any",[442,1547,959],{"class":456},[442,1549,474],{"class":460},[442,1551,1552],{"class":492},"[] ",[442,1554,471],{"class":456},[442,1556,1557],{"class":460}," never",[442,1559,496],{"class":456},[442,1561,1562,1564,1567,1569,1571,1573,1576,1578,1580,1582],{"class":444,"line":568},[442,1563,1433],{"class":448},[442,1565,1566],{"class":460}," C",[442,1568,1299],{"class":456},[442,1570,1530],{"class":460},[442,1572,457],{"class":456},[442,1574,1575],{"class":460},"string",[442,1577,838],{"class":456},[442,1579,831],{"class":460},[442,1581,1492],{"class":456},[442,1583,1584],{"class":559},"   \u002F\u002F string[] | number[]  (không phải (string|number)[])\n",[442,1586,1587],{"class":444,"line":574},[442,1588,509],{"emptyLinePlaceholder":508},[442,1590,1591],{"class":444,"line":629},[442,1592,1593],{"class":559},"\u002F\u002F Non-distributive — wrap trong tuple\n",[442,1595,1596,1598,1601,1603,1605,1607,1609,1611,1613,1615,1617,1619,1622,1624,1627,1629,1631,1633,1635],{"class":444,"line":648},[442,1597,1433],{"class":448},[442,1599,1600],{"class":460}," ToArrayBox",[442,1602,457],{"class":456},[442,1604,461],{"class":460},[442,1606,523],{"class":456},[442,1608,1299],{"class":456},[442,1610,614],{"class":492},[442,1612,461],{"class":460},[442,1614,623],{"class":492},[442,1616,877],{"class":448},[442,1618,614],{"class":492},[442,1620,1621],{"class":460},"any",[442,1623,623],{"class":492},[442,1625,1626],{"class":456},"?",[442,1628,474],{"class":460},[442,1630,1552],{"class":492},[442,1632,471],{"class":456},[442,1634,1557],{"class":460},[442,1636,496],{"class":456},[442,1638,1639,1641,1644,1646,1648,1650,1652,1654,1656,1658],{"class":444,"line":653},[442,1640,1433],{"class":448},[442,1642,1643],{"class":460}," D",[442,1645,1299],{"class":456},[442,1647,1600],{"class":460},[442,1649,457],{"class":456},[442,1651,1575],{"class":460},[442,1653,838],{"class":456},[442,1655,831],{"class":460},[442,1657,1492],{"class":456},[442,1659,1660],{"class":559}," \u002F\u002F (string | number)[]\n",[1236,1662,1665,1668,1669,1672,1673,1675],{"color":1663,"icon":1664},"primary","i-lucide-info",[1245,1666,1667],{},"Tại sao conditional với generic naked phân phối qua union?"," Vì TS coi ",[439,1670,1671],{},"T extends X ? ... : ..."," với ",[439,1674,461],{}," \"naked\" là distributive — chạy cho từng member rồi gộp.",[427,1677,1679,1680,1683],{"id":1678},"_5-infer-đặt-biến-type-trong-conditional","5. ",[439,1681,1682],{},"infer"," — đặt biến type trong conditional",[432,1685,1687],{"className":434,"code":1686,"language":436,"meta":437,"style":437},"\u002F\u002F Lấy return type của function\ntype ReturnTypeOf\u003CF> = F extends (...args: any) => infer R ? R : never;\n\ntype T1 = ReturnTypeOf\u003C() => string>;          \u002F\u002F string\ntype T2 = ReturnTypeOf\u003Ctypeof Math.random>;    \u002F\u002F number\n\n\u002F\u002F Lấy parameter type\ntype ParamsOf\u003CF> = F extends (...args: infer P) => any ? P : never;\ntype T3 = ParamsOf\u003C(a: number, b: string) => void>;   \u002F\u002F [number, string]\n\n\u002F\u002F Unbox Promise\ntype UnwrapPromise\u003CT> = T extends Promise\u003Cinfer U> ? U : T;\ntype T4 = UnwrapPromise\u003CPromise\u003Cstring>>;      \u002F\u002F string\ntype T5 = UnwrapPromise\u003Cnumber>;               \u002F\u002F number\n\n\u002F\u002F Unbox Array\ntype Element\u003CT> = T extends (infer E)[] ? E : never;\ntype T6 = Element\u003Cnumber[]>;                   \u002F\u002F number\ntype T7 = Element\u003C[string, number]>;           \u002F\u002F string | number\n",[439,1688,1689,1694,1745,1749,1772,1799,1803,1808,1854,1893,1897,1902,1941,1967,1987,1991,1996,2035,2058],{"__ignoreMap":437},[442,1690,1691],{"class":444,"line":445},[442,1692,1693],{"class":559},"\u002F\u002F Lấy return type của function\n",[442,1695,1696,1698,1701,1703,1706,1708,1710,1713,1715,1718,1721,1723,1725,1727,1729,1732,1735,1737,1739,1741,1743],{"class":444,"line":485},[442,1697,1433],{"class":448},[442,1699,1700],{"class":460}," ReturnTypeOf",[442,1702,457],{"class":456},[442,1704,1705],{"class":460},"F",[442,1707,523],{"class":456},[442,1709,1299],{"class":456},[442,1711,1712],{"class":460}," F",[442,1714,901],{"class":448},[442,1716,1717],{"class":456}," (...",[442,1719,1720],{"class":467},"args",[442,1722,471],{"class":456},[442,1724,1545],{"class":460},[442,1726,533],{"class":456},[442,1728,733],{"class":448},[442,1730,1731],{"class":456}," infer",[442,1733,1734],{"class":460}," R",[442,1736,959],{"class":456},[442,1738,1734],{"class":460},[442,1740,964],{"class":456},[442,1742,1557],{"class":460},[442,1744,496],{"class":456},[442,1746,1747],{"class":444,"line":499},[442,1748,509],{"emptyLinePlaceholder":508},[442,1750,1751,1753,1756,1758,1760,1763,1765,1767,1769],{"class":444,"line":505},[442,1752,1433],{"class":448},[442,1754,1755],{"class":460}," T1",[442,1757,1299],{"class":456},[442,1759,1700],{"class":460},[442,1761,1762],{"class":456},"\u003C()",[442,1764,733],{"class":448},[442,1766,1451],{"class":460},[442,1768,1492],{"class":456},[442,1770,1771],{"class":559},"          \u002F\u002F string\n",[442,1773,1774,1776,1779,1781,1783,1786,1789,1791,1794,1796],{"class":444,"line":512},[442,1775,1433],{"class":448},[442,1777,1778],{"class":460}," T2",[442,1780,1299],{"class":456},[442,1782,1700],{"class":460},[442,1784,1785],{"class":456},"\u003Ctypeof",[442,1787,1788],{"class":492}," Math",[442,1790,944],{"class":456},[442,1792,1793],{"class":492},"random",[442,1795,1492],{"class":456},[442,1797,1798],{"class":559},"    \u002F\u002F number\n",[442,1800,1801],{"class":444,"line":538},[442,1802,509],{"emptyLinePlaceholder":508},[442,1804,1805],{"class":444,"line":563},[442,1806,1807],{"class":559},"\u002F\u002F Lấy parameter type\n",[442,1809,1810,1812,1815,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1838,1840,1842,1844,1846,1848,1850,1852],{"class":444,"line":568},[442,1811,1433],{"class":448},[442,1813,1814],{"class":460}," ParamsOf",[442,1816,457],{"class":456},[442,1818,1705],{"class":460},[442,1820,523],{"class":456},[442,1822,1299],{"class":456},[442,1824,1712],{"class":460},[442,1826,901],{"class":448},[442,1828,1717],{"class":456},[442,1830,1720],{"class":467},[442,1832,471],{"class":456},[442,1834,1731],{"class":456},[442,1836,1837],{"class":460}," P",[442,1839,533],{"class":456},[442,1841,733],{"class":448},[442,1843,1545],{"class":460},[442,1845,959],{"class":456},[442,1847,1837],{"class":460},[442,1849,964],{"class":456},[442,1851,1557],{"class":460},[442,1853,496],{"class":456},[442,1855,1856,1858,1861,1863,1865,1868,1870,1872,1874,1876,1878,1880,1882,1884,1886,1888,1890],{"class":444,"line":574},[442,1857,1433],{"class":448},[442,1859,1860],{"class":460}," T3",[442,1862,1299],{"class":456},[442,1864,1814],{"class":460},[442,1866,1867],{"class":456},"\u003C(",[442,1869,595],{"class":467},[442,1871,471],{"class":456},[442,1873,831],{"class":460},[442,1875,587],{"class":456},[442,1877,605],{"class":467},[442,1879,471],{"class":456},[442,1881,1451],{"class":460},[442,1883,533],{"class":456},[442,1885,733],{"class":448},[442,1887,863],{"class":460},[442,1889,1492],{"class":456},[442,1891,1892],{"class":559},"   \u002F\u002F [number, string]\n",[442,1894,1895],{"class":444,"line":629},[442,1896,509],{"emptyLinePlaceholder":508},[442,1898,1899],{"class":444,"line":648},[442,1900,1901],{"class":559},"\u002F\u002F Unbox Promise\n",[442,1903,1904,1906,1909,1911,1913,1915,1917,1919,1921,1924,1927,1929,1931,1933,1935,1937,1939],{"class":444,"line":653},[442,1905,1433],{"class":448},[442,1907,1908],{"class":460}," UnwrapPromise",[442,1910,457],{"class":456},[442,1912,461],{"class":460},[442,1914,523],{"class":456},[442,1916,1299],{"class":456},[442,1918,474],{"class":460},[442,1920,901],{"class":448},[442,1922,1923],{"class":460}," Promise",[442,1925,1926],{"class":456},"\u003Cinfer",[442,1928,736],{"class":460},[442,1930,523],{"class":456},[442,1932,959],{"class":456},[442,1934,736],{"class":460},[442,1936,964],{"class":456},[442,1938,474],{"class":460},[442,1940,496],{"class":456},[442,1942,1943,1945,1948,1950,1952,1954,1957,1959,1961,1964],{"class":444,"line":658},[442,1944,1433],{"class":448},[442,1946,1947],{"class":460}," T4",[442,1949,1299],{"class":456},[442,1951,1908],{"class":460},[442,1953,457],{"class":456},[442,1955,1956],{"class":460},"Promise",[442,1958,457],{"class":456},[442,1960,1575],{"class":460},[442,1962,1963],{"class":456},">>;",[442,1965,1966],{"class":559},"      \u002F\u002F string\n",[442,1968,1969,1971,1974,1976,1978,1980,1982,1984],{"class":444,"line":664},[442,1970,1433],{"class":448},[442,1972,1973],{"class":460}," T5",[442,1975,1299],{"class":456},[442,1977,1908],{"class":460},[442,1979,457],{"class":456},[442,1981,520],{"class":460},[442,1983,1492],{"class":456},[442,1985,1986],{"class":559},"               \u002F\u002F number\n",[442,1988,1989],{"class":444,"line":681},[442,1990,509],{"emptyLinePlaceholder":508},[442,1992,1993],{"class":444,"line":704},[442,1994,1995],{"class":559},"\u002F\u002F Unbox Array\n",[442,1997,1998,2000,2003,2005,2007,2009,2011,2013,2015,2017,2019,2022,2025,2027,2029,2031,2033],{"class":444,"line":751},[442,1999,1433],{"class":448},[442,2001,2002],{"class":460}," Element",[442,2004,457],{"class":456},[442,2006,461],{"class":460},[442,2008,523],{"class":456},[442,2010,1299],{"class":456},[442,2012,474],{"class":460},[442,2014,901],{"class":448},[442,2016,722],{"class":492},[442,2018,1682],{"class":456},[442,2020,2021],{"class":460}," E",[442,2023,2024],{"class":492},")[] ",[442,2026,1626],{"class":456},[442,2028,2021],{"class":460},[442,2030,964],{"class":456},[442,2032,1557],{"class":460},[442,2034,496],{"class":456},[442,2036,2037,2039,2042,2044,2046,2048,2050,2053,2055],{"class":444,"line":779},[442,2038,1433],{"class":448},[442,2040,2041],{"class":460}," T6",[442,2043,1299],{"class":456},[442,2045,2002],{"class":460},[442,2047,457],{"class":456},[442,2049,520],{"class":460},[442,2051,2052],{"class":492},"[]",[442,2054,1492],{"class":456},[442,2056,2057],{"class":559},"                   \u002F\u002F number\n",[442,2059,2060,2062,2065,2067,2069,2071,2073,2075,2077,2079,2081,2083],{"class":444,"line":785},[442,2061,1433],{"class":448},[442,2063,2064],{"class":460}," T7",[442,2066,1299],{"class":456},[442,2068,2002],{"class":460},[442,2070,457],{"class":456},[442,2072,1123],{"class":492},[442,2074,1575],{"class":460},[442,2076,587],{"class":456},[442,2078,831],{"class":460},[442,2080,643],{"class":492},[442,2082,1492],{"class":456},[442,2084,2085],{"class":559},"           \u002F\u002F string | number\n",[1236,2087,1243,2088,2093],{"color":1663,"icon":1239},[1245,2089,2090,2092],{},[439,2091,1682],{}," cực hay trong PV junior\u002Fsenior."," Khi hiểu được pattern này → bạn đọc được mọi utility type built-in.",[427,2095,2097],{"id":2096},"_6-mapped-types-biến-đổi-shape","6. Mapped types — biến đổi shape",[432,2099,2101],{"className":434,"code":2100,"language":436,"meta":437,"style":437},"\u002F\u002F Cơ bản — map qua key\ntype Readonly\u003CT> = { readonly [K in keyof T]: T[K] };\ntype Partial\u003CT> = { [K in keyof T]?: T[K] };\ntype Required\u003CT> = { [K in keyof T]-?: T[K] };          \u002F\u002F remove ?\ntype Mutable\u003CT> = { -readonly [K in keyof T]: T[K] };   \u002F\u002F remove readonly\n\n\u002F\u002F Key remapping (TS 4.1+) — `as`\ntype Getters\u003CT> = {\n  [K in keyof T as `get${Capitalize\u003Cstring & K>}`]: () => T[K];\n};\n\u002F\u002F Getters\u003C{ name: string; age: number }>\n\u002F\u002F = { getName: () => string; getAge: () => number }\n",[439,2102,2103,2108,2154,2195,2241,2291,2295,2300,2317,2377,2381,2386],{"__ignoreMap":437},[442,2104,2105],{"class":444,"line":445},[442,2106,2107],{"class":559},"\u002F\u002F Cơ bản — map qua key\n",[442,2109,2110,2112,2115,2117,2119,2121,2123,2125,2128,2130,2132,2135,2137,2139,2141,2143,2145,2147,2149,2151],{"class":444,"line":485},[442,2111,1433],{"class":448},[442,2113,2114],{"class":460}," Readonly",[442,2116,457],{"class":456},[442,2118,461],{"class":460},[442,2120,523],{"class":456},[442,2122,1299],{"class":456},[442,2124,904],{"class":456},[442,2126,2127],{"class":448}," readonly",[442,2129,614],{"class":492},[442,2131,1126],{"class":460},[442,2133,2134],{"class":456}," in",[442,2136,1096],{"class":456},[442,2138,474],{"class":460},[442,2140,643],{"class":492},[442,2142,471],{"class":456},[442,2144,474],{"class":460},[442,2146,1123],{"class":492},[442,2148,1126],{"class":460},[442,2150,623],{"class":492},[442,2152,2153],{"class":456},"};\n",[442,2155,2156,2158,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181,2183,2185,2187,2189,2191,2193],{"class":444,"line":499},[442,2157,1433],{"class":448},[442,2159,2160],{"class":460}," Partial",[442,2162,457],{"class":456},[442,2164,461],{"class":460},[442,2166,523],{"class":456},[442,2168,1299],{"class":456},[442,2170,904],{"class":456},[442,2172,614],{"class":492},[442,2174,1126],{"class":460},[442,2176,2134],{"class":456},[442,2178,1096],{"class":456},[442,2180,474],{"class":460},[442,2182,643],{"class":492},[442,2184,1336],{"class":456},[442,2186,474],{"class":460},[442,2188,1123],{"class":492},[442,2190,1126],{"class":460},[442,2192,623],{"class":492},[442,2194,2153],{"class":456},[442,2196,2197,2199,2202,2204,2206,2208,2210,2212,2214,2216,2218,2220,2222,2224,2227,2229,2231,2233,2235,2238],{"class":444,"line":505},[442,2198,1433],{"class":448},[442,2200,2201],{"class":460}," Required",[442,2203,457],{"class":456},[442,2205,461],{"class":460},[442,2207,523],{"class":456},[442,2209,1299],{"class":456},[442,2211,904],{"class":456},[442,2213,614],{"class":492},[442,2215,1126],{"class":460},[442,2217,2134],{"class":456},[442,2219,1096],{"class":456},[442,2221,474],{"class":460},[442,2223,643],{"class":492},[442,2225,2226],{"class":456},"-?:",[442,2228,474],{"class":460},[442,2230,1123],{"class":492},[442,2232,1126],{"class":460},[442,2234,623],{"class":492},[442,2236,2237],{"class":456},"};",[442,2239,2240],{"class":559},"          \u002F\u002F remove ?\n",[442,2242,2243,2245,2248,2250,2252,2254,2256,2258,2261,2264,2266,2268,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288],{"class":444,"line":512},[442,2244,1433],{"class":448},[442,2246,2247],{"class":460}," Mutable",[442,2249,457],{"class":456},[442,2251,461],{"class":460},[442,2253,523],{"class":456},[442,2255,1299],{"class":456},[442,2257,904],{"class":456},[442,2259,2260],{"class":456}," -",[442,2262,2263],{"class":448},"readonly",[442,2265,614],{"class":492},[442,2267,1126],{"class":460},[442,2269,2134],{"class":456},[442,2271,1096],{"class":456},[442,2273,474],{"class":460},[442,2275,643],{"class":492},[442,2277,471],{"class":456},[442,2279,474],{"class":460},[442,2281,1123],{"class":492},[442,2283,1126],{"class":460},[442,2285,623],{"class":492},[442,2287,2237],{"class":456},[442,2289,2290],{"class":559},"   \u002F\u002F remove readonly\n",[442,2292,2293],{"class":444,"line":538},[442,2294,509],{"emptyLinePlaceholder":508},[442,2296,2297],{"class":444,"line":563},[442,2298,2299],{"class":559},"\u002F\u002F Key remapping (TS 4.1+) — `as`\n",[442,2301,2302,2304,2307,2309,2311,2313,2315],{"class":444,"line":568},[442,2303,1433],{"class":448},[442,2305,2306],{"class":460}," Getters",[442,2308,457],{"class":456},[442,2310,461],{"class":460},[442,2312,523],{"class":456},[442,2314,1299],{"class":456},[442,2316,482],{"class":456},[442,2318,2319,2322,2324,2326,2328,2330,2333,2336,2338,2341,2344,2346,2348,2351,2353,2355,2358,2360,2362,2365,2367,2369,2371,2373,2375],{"class":444,"line":574},[442,2320,2321],{"class":492},"  [",[442,2323,1126],{"class":460},[442,2325,2134],{"class":456},[442,2327,1096],{"class":456},[442,2329,474],{"class":460},[442,2331,2332],{"class":488}," as",[442,2334,2335],{"class":456}," `",[442,2337,1193],{"class":548},[442,2339,2340],{"class":456},"${",[442,2342,2343],{"class":460},"Capitalize",[442,2345,457],{"class":456},[442,2347,1575],{"class":460},[442,2349,2350],{"class":456}," &",[442,2352,1091],{"class":460},[442,2354,523],{"class":456},[442,2356,2357],{"class":456},"}`",[442,2359,643],{"class":492},[442,2361,471],{"class":456},[442,2363,2364],{"class":456}," ()",[442,2366,733],{"class":448},[442,2368,474],{"class":460},[442,2370,1123],{"class":492},[442,2372,1126],{"class":460},[442,2374,643],{"class":492},[442,2376,496],{"class":456},[442,2378,2379],{"class":444,"line":629},[442,2380,2153],{"class":456},[442,2382,2383],{"class":444,"line":648},[442,2384,2385],{"class":559},"\u002F\u002F Getters\u003C{ name: string; age: number }>\n",[442,2387,2388],{"class":444,"line":653},[442,2389,2390],{"class":559},"\u002F\u002F = { getName: () => string; getAge: () => number }\n",[427,2392,2394],{"id":2393},"_7-template-literal-types","7. Template literal types",[432,2396,2398],{"className":434,"code":2397,"language":436,"meta":437,"style":437},"type Greeting = `Hello, ${string}!`;\nconst g1: Greeting = \"Hello, world!\";       \u002F\u002F OK\nconst g2: Greeting = \"Bye\";                 \u002F\u002F ❌\n\n\u002F\u002F Combine union\ntype Color = \"red\" | \"blue\";\ntype Size = \"small\" | \"large\";\ntype Variant = `${Color}-${Size}`;\n\u002F\u002F \"red-small\" | \"red-large\" | \"blue-small\" | \"blue-large\"\n\n\u002F\u002F Tách string\ntype SplitFirst\u003CS extends string> =\n  S extends `${infer Head}\u002F${infer Tail}` ? Head : never;\ntype T = SplitFirst\u003C\"users\u002F123\u002Fprofile\">;   \u002F\u002F \"users\"\n",[439,2399,2400,2429,2454,2479,2483,2488,2515,2542,2571,2576,2580,2585,2606,2644],{"__ignoreMap":437},[442,2401,2402,2404,2407,2409,2411,2414,2416,2418,2421,2424,2427],{"class":444,"line":445},[442,2403,1433],{"class":448},[442,2405,2406],{"class":460}," Greeting",[442,2408,1299],{"class":456},[442,2410,2335],{"class":456},[442,2412,2413],{"class":548},"Hello, ",[442,2415,2340],{"class":456},[442,2417,1575],{"class":460},[442,2419,2420],{"class":456},"}",[442,2422,2423],{"class":548},"!",[442,2425,2426],{"class":456},"`",[442,2428,496],{"class":456},[442,2430,2431,2433,2436,2438,2440,2442,2444,2447,2449,2451],{"class":444,"line":485},[442,2432,1155],{"class":448},[442,2434,2435],{"class":492}," g1",[442,2437,471],{"class":456},[442,2439,2406],{"class":460},[442,2441,1299],{"class":456},[442,2443,995],{"class":456},[442,2445,2446],{"class":548},"Hello, world!",[442,2448,545],{"class":456},[442,2450,556],{"class":456},[442,2452,2453],{"class":559},"       \u002F\u002F OK\n",[442,2455,2456,2458,2461,2463,2465,2467,2469,2472,2474,2476],{"class":444,"line":499},[442,2457,1155],{"class":448},[442,2459,2460],{"class":492}," g2",[442,2462,471],{"class":456},[442,2464,2406],{"class":460},[442,2466,1299],{"class":456},[442,2468,995],{"class":456},[442,2470,2471],{"class":548},"Bye",[442,2473,545],{"class":456},[442,2475,556],{"class":456},[442,2477,2478],{"class":559},"                 \u002F\u002F ❌\n",[442,2480,2481],{"class":444,"line":505},[442,2482,509],{"emptyLinePlaceholder":508},[442,2484,2485],{"class":444,"line":512},[442,2486,2487],{"class":559},"\u002F\u002F Combine union\n",[442,2489,2490,2492,2495,2497,2499,2502,2504,2506,2508,2511,2513],{"class":444,"line":538},[442,2491,1433],{"class":448},[442,2493,2494],{"class":460}," Color",[442,2496,1299],{"class":456},[442,2498,995],{"class":456},[442,2500,2501],{"class":548},"red",[442,2503,545],{"class":456},[442,2505,838],{"class":456},[442,2507,995],{"class":456},[442,2509,2510],{"class":548},"blue",[442,2512,545],{"class":456},[442,2514,496],{"class":456},[442,2516,2517,2519,2522,2524,2526,2529,2531,2533,2535,2538,2540],{"class":444,"line":563},[442,2518,1433],{"class":448},[442,2520,2521],{"class":460}," Size",[442,2523,1299],{"class":456},[442,2525,995],{"class":456},[442,2527,2528],{"class":548},"small",[442,2530,545],{"class":456},[442,2532,838],{"class":456},[442,2534,995],{"class":456},[442,2536,2537],{"class":548},"large",[442,2539,545],{"class":456},[442,2541,496],{"class":456},[442,2543,2544,2546,2549,2551,2554,2557,2559,2562,2564,2567,2569],{"class":444,"line":568},[442,2545,1433],{"class":448},[442,2547,2548],{"class":460}," Variant",[442,2550,1299],{"class":456},[442,2552,2553],{"class":456}," `${",[442,2555,2556],{"class":460},"Color",[442,2558,2420],{"class":456},[442,2560,2561],{"class":548},"-",[442,2563,2340],{"class":456},[442,2565,2566],{"class":460},"Size",[442,2568,2357],{"class":456},[442,2570,496],{"class":456},[442,2572,2573],{"class":444,"line":574},[442,2574,2575],{"class":559},"\u002F\u002F \"red-small\" | \"red-large\" | \"blue-small\" | \"blue-large\"\n",[442,2577,2578],{"class":444,"line":629},[442,2579,509],{"emptyLinePlaceholder":508},[442,2581,2582],{"class":444,"line":648},[442,2583,2584],{"class":559},"\u002F\u002F Tách string\n",[442,2586,2587,2589,2592,2594,2597,2599,2601,2603],{"class":444,"line":653},[442,2588,1433],{"class":448},[442,2590,2591],{"class":460}," SplitFirst",[442,2593,457],{"class":456},[442,2595,2596],{"class":460},"S",[442,2598,901],{"class":448},[442,2600,1451],{"class":460},[442,2602,523],{"class":456},[442,2604,2605],{"class":456}," =\n",[442,2607,2608,2611,2613,2615,2617,2620,2622,2625,2627,2629,2632,2634,2636,2638,2640,2642],{"class":444,"line":658},[442,2609,2610],{"class":460},"  S",[442,2612,901],{"class":448},[442,2614,2553],{"class":456},[442,2616,1682],{"class":456},[442,2618,2619],{"class":460}," Head",[442,2621,2420],{"class":456},[442,2623,2624],{"class":548},"\u002F",[442,2626,2340],{"class":456},[442,2628,1682],{"class":456},[442,2630,2631],{"class":460}," Tail",[442,2633,2357],{"class":456},[442,2635,959],{"class":456},[442,2637,2619],{"class":460},[442,2639,964],{"class":456},[442,2641,1557],{"class":460},[442,2643,496],{"class":456},[442,2645,2646,2648,2650,2652,2654,2656,2658,2661,2663,2665],{"class":444,"line":664},[442,2647,1433],{"class":448},[442,2649,474],{"class":460},[442,2651,1299],{"class":456},[442,2653,2591],{"class":460},[442,2655,457],{"class":456},[442,2657,545],{"class":456},[442,2659,2660],{"class":548},"users\u002F123\u002Fprofile",[442,2662,545],{"class":456},[442,2664,1492],{"class":456},[442,2666,2667],{"class":559},"   \u002F\u002F \"users\"\n",[1236,2669,2670],{"color":1663,"icon":268},"Template literal type + infer cho phép parse string lúc compile — type-safe API path, SQL builder, etc. Power user feature.",[1236,2672,2673,2685],{"color":1663,"icon":1664},[1241,2674,1243,2675,2678,2679,2681,2682,471],{},[1245,2676,2677],{},"TS 7.0 fix Unicode:"," Template literal type với ",[439,2680,1682],{}," giờ xử lý đúng ",[1245,2683,2684],{},"emoji \u002F surrogate pairs",[432,2686,2688],{"className":434,"code":2687,"language":436,"meta":437,"style":437},"type HeadTail\u003CS> = S extends `${infer Head}${infer Tail}` ? [Head, Tail] : never;\n\n\u002F\u002F TS 7.0: HeadTail\u003C\"👋🌍\"> => [\"👋\", \"🌍\"] — đúng!\n\u002F\u002F TS cũ:     HeadTail\u003C\"👋🌍\"> => [\"\\uD83D\", \"\\uDC4B🌍\"] — sai do surrogate pairs\n",[439,2689,2690,2744,2748,2753],{"__ignoreMap":437},[442,2691,2692,2694,2697,2699,2701,2703,2705,2708,2710,2712,2714,2716,2719,2721,2723,2725,2727,2729,2732,2734,2736,2738,2740,2742],{"class":444,"line":445},[442,2693,1433],{"class":448},[442,2695,2696],{"class":460}," HeadTail",[442,2698,457],{"class":456},[442,2700,2596],{"class":460},[442,2702,523],{"class":456},[442,2704,1299],{"class":456},[442,2706,2707],{"class":460}," S",[442,2709,901],{"class":448},[442,2711,2553],{"class":456},[442,2713,1682],{"class":456},[442,2715,2619],{"class":460},[442,2717,2718],{"class":456},"}${",[442,2720,1682],{"class":456},[442,2722,2631],{"class":460},[442,2724,2357],{"class":456},[442,2726,959],{"class":456},[442,2728,614],{"class":492},[442,2730,2731],{"class":460},"Head",[442,2733,587],{"class":456},[442,2735,2631],{"class":460},[442,2737,623],{"class":492},[442,2739,471],{"class":456},[442,2741,1557],{"class":460},[442,2743,496],{"class":456},[442,2745,2746],{"class":444,"line":485},[442,2747,509],{"emptyLinePlaceholder":508},[442,2749,2750],{"class":444,"line":499},[442,2751,2752],{"class":559},"\u002F\u002F TS 7.0: HeadTail\u003C\"👋🌍\"> => [\"👋\", \"🌍\"] — đúng!\n",[442,2754,2755],{"class":444,"line":505},[442,2756,2757],{"class":559},"\u002F\u002F TS cũ:     HeadTail\u003C\"👋🌍\"> => [\"\\uD83D\", \"\\uDC4B🌍\"] — sai do surrogate pairs\n",[427,2759,2761],{"id":2760},"_8-utility-types-built-in-phải-thuộc","8. Utility types built-in (phải thuộc)",[2763,2764,2765,2778],"table",{},[2766,2767,2768],"thead",{},[2769,2770,2771,2775],"tr",{},[2772,2773,2774],"th",{},"Utility",[2772,2776,2777],{},"Tác dụng",[2779,2780,2781,2792,2802,2812,2822,2832,2842,2852,2862,2872,2882,2892,2902,2912],"tbody",{},[2769,2782,2783,2789],{},[2784,2785,2786],"td",{},[439,2787,2788],{},"Partial\u003CT>",[2784,2790,2791],{},"Mọi field thành optional",[2769,2793,2794,2799],{},[2784,2795,2796],{},[439,2797,2798],{},"Required\u003CT>",[2784,2800,2801],{},"Mọi field thành bắt buộc",[2769,2803,2804,2809],{},[2784,2805,2806],{},[439,2807,2808],{},"Readonly\u003CT>",[2784,2810,2811],{},"Mọi field thành readonly",[2769,2813,2814,2819],{},[2784,2815,2816],{},[439,2817,2818],{},"Pick\u003CT, K>",[2784,2820,2821],{},"Chọn subset key K",[2769,2823,2824,2829],{},[2784,2825,2826],{},[439,2827,2828],{},"Omit\u003CT, K>",[2784,2830,2831],{},"Bỏ subset key K",[2769,2833,2834,2839],{},[2784,2835,2836],{},[439,2837,2838],{},"Record\u003CK, V>",[2784,2840,2841],{},"Object với key K, value V",[2769,2843,2844,2849],{},[2784,2845,2846],{},[439,2847,2848],{},"Exclude\u003CT, U>",[2784,2850,2851],{},"T loại U (cho union)",[2769,2853,2854,2859],{},[2784,2855,2856],{},[439,2857,2858],{},"Extract\u003CT, U>",[2784,2860,2861],{},"T giao U",[2769,2863,2864,2869],{},[2784,2865,2866],{},[439,2867,2868],{},"NonNullable\u003CT>",[2784,2870,2871],{},"T loại null\u002Fundefined",[2769,2873,2874,2879],{},[2784,2875,2876],{},[439,2877,2878],{},"ReturnType\u003CF>",[2784,2880,2881],{},"Return type của function F",[2769,2883,2884,2889],{},[2784,2885,2886],{},[439,2887,2888],{},"Parameters\u003CF>",[2784,2890,2891],{},"Tuple parameter của F",[2769,2893,2894,2899],{},[2784,2895,2896],{},[439,2897,2898],{},"Awaited\u003CT>",[2784,2900,2901],{},"Unbox Promise lồng nhau",[2769,2903,2904,2909],{},[2784,2905,2906],{},[439,2907,2908],{},"InstanceType\u003CC>",[2784,2910,2911],{},"Instance của constructor class",[2769,2913,2914,2929],{},[2784,2915,2916,2919,2920,2919,2923,2919,2926],{},[439,2917,2918],{},"Uppercase\u003CS>"," \u002F ",[439,2921,2922],{},"Lowercase\u003CS>",[439,2924,2925],{},"Capitalize\u003CS>",[439,2927,2928],{},"Uncapitalize\u003CS>",[2784,2930,2931],{},"Biến đổi string literal",[432,2933,2935],{"className":434,"code":2934,"language":436,"meta":437,"style":437},"interface User { id: number; name: string; age: number; }\n\ntype UserPreview = Pick\u003CUser, \"id\" | \"name\">;      \u002F\u002F { id; name }\ntype UserNoAge = Omit\u003CUser, \"age\">;                \u002F\u002F { id; name }\ntype UserPartial = Partial\u003CUser>;                  \u002F\u002F tất cả optional\ntype UserName = User[\"name\"];                      \u002F\u002F string  (lookup type)\ntype UserKeys = keyof User;                        \u002F\u002F \"id\" | \"name\" | \"age\"\n\ntype Status = \"active\" | \"inactive\" | \"deleted\";\ntype Live = Exclude\u003CStatus, \"deleted\">;            \u002F\u002F \"active\" | \"inactive\"\ntype Dead = Extract\u003CStatus, \"deleted\">;            \u002F\u002F \"deleted\"\n\nasync function fetch(): Promise\u003CUser> { ... }\ntype R = Awaited\u003CReturnType\u003Ctypeof fetch>>;        \u002F\u002F User\n",[439,2936,2937,2974,2978,3015,3044,3064,3090,3108,3112,3148,3178,3207,3211,3240],{"__ignoreMap":437},[442,2938,2939,2941,2944,2946,2948,2950,2952,2954,2956,2958,2960,2962,2965,2967,2969,2971],{"class":444,"line":445},[442,2940,804],{"class":448},[442,2942,2943],{"class":460}," User",[442,2945,904],{"class":456},[442,2947,1166],{"class":634},[442,2949,471],{"class":456},[442,2951,831],{"class":460},[442,2953,556],{"class":456},[442,2955,1176],{"class":634},[442,2957,471],{"class":456},[442,2959,1451],{"class":460},[442,2961,556],{"class":456},[442,2963,2964],{"class":634}," age",[442,2966,471],{"class":456},[442,2968,831],{"class":460},[442,2970,556],{"class":456},[442,2972,2973],{"class":456}," }\n",[442,2975,2976],{"class":444,"line":485},[442,2977,509],{"emptyLinePlaceholder":508},[442,2979,2980,2982,2985,2987,2990,2992,2994,2996,2998,3000,3002,3004,3006,3008,3010,3012],{"class":444,"line":499},[442,2981,1433],{"class":448},[442,2983,2984],{"class":460}," UserPreview",[442,2986,1299],{"class":456},[442,2988,2989],{"class":460}," Pick",[442,2991,457],{"class":456},[442,2993,1396],{"class":460},[442,2995,587],{"class":456},[442,2997,995],{"class":456},[442,2999,826],{"class":548},[442,3001,545],{"class":456},[442,3003,838],{"class":456},[442,3005,995],{"class":456},[442,3007,1203],{"class":548},[442,3009,545],{"class":456},[442,3011,1492],{"class":456},[442,3013,3014],{"class":559},"      \u002F\u002F { id; name }\n",[442,3016,3017,3019,3022,3024,3027,3029,3031,3033,3035,3037,3039,3041],{"class":444,"line":505},[442,3018,1433],{"class":448},[442,3020,3021],{"class":460}," UserNoAge",[442,3023,1299],{"class":456},[442,3025,3026],{"class":460}," Omit",[442,3028,457],{"class":456},[442,3030,1396],{"class":460},[442,3032,587],{"class":456},[442,3034,995],{"class":456},[442,3036,1225],{"class":548},[442,3038,545],{"class":456},[442,3040,1492],{"class":456},[442,3042,3043],{"class":559},"                \u002F\u002F { id; name }\n",[442,3045,3046,3048,3051,3053,3055,3057,3059,3061],{"class":444,"line":512},[442,3047,1433],{"class":448},[442,3049,3050],{"class":460}," UserPartial",[442,3052,1299],{"class":456},[442,3054,2160],{"class":460},[442,3056,457],{"class":456},[442,3058,1396],{"class":460},[442,3060,1492],{"class":456},[442,3062,3063],{"class":559},"                  \u002F\u002F tất cả optional\n",[442,3065,3066,3068,3071,3073,3075,3077,3079,3081,3083,3085,3087],{"class":444,"line":538},[442,3067,1433],{"class":448},[442,3069,3070],{"class":460}," UserName",[442,3072,1299],{"class":456},[442,3074,2943],{"class":460},[442,3076,1123],{"class":492},[442,3078,545],{"class":456},[442,3080,1203],{"class":548},[442,3082,545],{"class":456},[442,3084,643],{"class":492},[442,3086,556],{"class":456},[442,3088,3089],{"class":559},"                      \u002F\u002F string  (lookup type)\n",[442,3091,3092,3094,3097,3099,3101,3103,3105],{"class":444,"line":563},[442,3093,1433],{"class":448},[442,3095,3096],{"class":460}," UserKeys",[442,3098,1299],{"class":456},[442,3100,1096],{"class":456},[442,3102,2943],{"class":460},[442,3104,556],{"class":456},[442,3106,3107],{"class":559},"                        \u002F\u002F \"id\" | \"name\" | \"age\"\n",[442,3109,3110],{"class":444,"line":568},[442,3111,509],{"emptyLinePlaceholder":508},[442,3113,3114,3116,3119,3121,3123,3126,3128,3130,3132,3135,3137,3139,3141,3144,3146],{"class":444,"line":574},[442,3115,1433],{"class":448},[442,3117,3118],{"class":460}," Status",[442,3120,1299],{"class":456},[442,3122,995],{"class":456},[442,3124,3125],{"class":548},"active",[442,3127,545],{"class":456},[442,3129,838],{"class":456},[442,3131,995],{"class":456},[442,3133,3134],{"class":548},"inactive",[442,3136,545],{"class":456},[442,3138,838],{"class":456},[442,3140,995],{"class":456},[442,3142,3143],{"class":548},"deleted",[442,3145,545],{"class":456},[442,3147,496],{"class":456},[442,3149,3150,3152,3155,3157,3160,3162,3165,3167,3169,3171,3173,3175],{"class":444,"line":629},[442,3151,1433],{"class":448},[442,3153,3154],{"class":460}," Live",[442,3156,1299],{"class":456},[442,3158,3159],{"class":460}," Exclude",[442,3161,457],{"class":456},[442,3163,3164],{"class":460},"Status",[442,3166,587],{"class":456},[442,3168,995],{"class":456},[442,3170,3143],{"class":548},[442,3172,545],{"class":456},[442,3174,1492],{"class":456},[442,3176,3177],{"class":559},"            \u002F\u002F \"active\" | \"inactive\"\n",[442,3179,3180,3182,3185,3187,3190,3192,3194,3196,3198,3200,3202,3204],{"class":444,"line":648},[442,3181,1433],{"class":448},[442,3183,3184],{"class":460}," Dead",[442,3186,1299],{"class":456},[442,3188,3189],{"class":460}," Extract",[442,3191,457],{"class":456},[442,3193,3164],{"class":460},[442,3195,587],{"class":456},[442,3197,995],{"class":456},[442,3199,3143],{"class":548},[442,3201,545],{"class":456},[442,3203,1492],{"class":456},[442,3205,3206],{"class":559},"            \u002F\u002F \"deleted\"\n",[442,3208,3209],{"class":444,"line":653},[442,3210,509],{"emptyLinePlaceholder":508},[442,3212,3213,3216,3219,3222,3225,3227,3229,3231,3233,3235,3238],{"class":444,"line":658},[442,3214,3215],{"class":448},"async",[442,3217,3218],{"class":448}," function",[442,3220,3221],{"class":452}," fetch",[442,3223,3224],{"class":456},"():",[442,3226,1923],{"class":460},[442,3228,457],{"class":456},[442,3230,1396],{"class":460},[442,3232,523],{"class":456},[442,3234,904],{"class":456},[442,3236,3237],{"class":456}," ...",[442,3239,2973],{"class":456},[442,3241,3242,3244,3246,3248,3251,3253,3256,3258,3260,3262],{"class":444,"line":664},[442,3243,1433],{"class":448},[442,3245,1734],{"class":460},[442,3247,1299],{"class":456},[442,3249,3250],{"class":460}," Awaited",[442,3252,457],{"class":456},[442,3254,3255],{"class":460},"ReturnType",[442,3257,1785],{"class":456},[442,3259,3221],{"class":492},[442,3261,1963],{"class":456},[442,3263,3264],{"class":559},"        \u002F\u002F User\n",[1236,3266,3267,3286],{"color":1238,"icon":1239},[1241,3268,1243,3269,1248,3272,3285],{},[1245,3270,3271],{},"Câu PV nhiều khả năng:",[1250,3273,545,3274,3277,3278,3277,3281,3284],{},[439,3275,3276],{},"Pick",", ",[439,3279,3280],{},"Omit",[439,3282,3283],{},"Partial"," định nghĩa thế nào?\""," — Hỏi để check bạn có hiểu mapped + conditional types không.",[432,3287,3289],{"className":434,"code":3288,"language":436,"meta":437,"style":437},"type Pick\u003CT, K extends keyof T> = { [P in K]: T[P] };\ntype Omit\u003CT, K extends keyof any> = Pick\u003CT, Exclude\u003Ckeyof T, K>>;\ntype Partial\u003CT> = { [P in keyof T]?: T[P] };\n",[439,3290,3291,3340,3386],{"__ignoreMap":437},[442,3292,3293,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313,3315,3317,3319,3322,3324,3326,3328,3330,3332,3334,3336,3338],{"class":444,"line":445},[442,3294,1433],{"class":448},[442,3296,2989],{"class":460},[442,3298,457],{"class":456},[442,3300,461],{"class":460},[442,3302,587],{"class":456},[442,3304,1091],{"class":460},[442,3306,901],{"class":448},[442,3308,1096],{"class":456},[442,3310,474],{"class":460},[442,3312,523],{"class":456},[442,3314,1299],{"class":456},[442,3316,904],{"class":456},[442,3318,614],{"class":492},[442,3320,3321],{"class":460},"P",[442,3323,2134],{"class":456},[442,3325,1091],{"class":460},[442,3327,643],{"class":492},[442,3329,471],{"class":456},[442,3331,474],{"class":460},[442,3333,1123],{"class":492},[442,3335,3321],{"class":460},[442,3337,623],{"class":492},[442,3339,2153],{"class":456},[442,3341,3342,3344,3346,3348,3350,3352,3354,3356,3358,3360,3362,3364,3366,3368,3370,3372,3374,3377,3379,3381,3383],{"class":444,"line":485},[442,3343,1433],{"class":448},[442,3345,3026],{"class":460},[442,3347,457],{"class":456},[442,3349,461],{"class":460},[442,3351,587],{"class":456},[442,3353,1091],{"class":460},[442,3355,901],{"class":448},[442,3357,1096],{"class":456},[442,3359,1545],{"class":460},[442,3361,523],{"class":456},[442,3363,1299],{"class":456},[442,3365,2989],{"class":460},[442,3367,457],{"class":456},[442,3369,461],{"class":460},[442,3371,587],{"class":456},[442,3373,3159],{"class":460},[442,3375,3376],{"class":456},"\u003Ckeyof",[442,3378,474],{"class":460},[442,3380,587],{"class":456},[442,3382,1091],{"class":460},[442,3384,3385],{"class":456},">>;\n",[442,3387,3388,3390,3392,3394,3396,3398,3400,3402,3404,3406,3408,3410,3412,3414,3416,3418,3420,3422,3424],{"class":444,"line":499},[442,3389,1433],{"class":448},[442,3391,2160],{"class":460},[442,3393,457],{"class":456},[442,3395,461],{"class":460},[442,3397,523],{"class":456},[442,3399,1299],{"class":456},[442,3401,904],{"class":456},[442,3403,614],{"class":492},[442,3405,3321],{"class":460},[442,3407,2134],{"class":456},[442,3409,1096],{"class":456},[442,3411,474],{"class":460},[442,3413,643],{"class":492},[442,3415,1336],{"class":456},[442,3417,474],{"class":460},[442,3419,1123],{"class":492},[442,3421,3321],{"class":460},[442,3423,623],{"class":492},[442,3425,2153],{"class":456},[427,3427,3429,3430],{"id":3428},"_9-index-access-type-tk","9. Index access type — ",[439,3431,3432],{},"T[K]",[432,3434,3436],{"className":434,"code":3435,"language":436,"meta":437,"style":437},"interface User { id: number; name: string; address: { city: string } }\n\ntype Name = User[\"name\"];                  \u002F\u002F string\ntype Id = User[\"id\"];                      \u002F\u002F number\ntype City = User[\"address\"][\"city\"];       \u002F\u002F string nested\n\n\u002F\u002F Combine với keyof — lookup mọi value type\ntype UserValue = User[keyof User];         \u002F\u002F string | number | { city: string }\n\n\u002F\u002F Array element\ntype Items = string[];\ntype Item = Items[number];                 \u002F\u002F string\n\n\u002F\u002F Tuple element\ntype Tup = [string, number, boolean];\ntype T0 = Tup[0];                          \u002F\u002F string\ntype Any = Tup[number];                    \u002F\u002F string | number | boolean\n",[439,3437,3438,3481,3485,3511,3537,3574,3578,3583,3608,3612,3617,3632,3654,3658,3663,3689,3712],{"__ignoreMap":437},[442,3439,3440,3442,3444,3446,3448,3450,3452,3454,3456,3458,3460,3462,3465,3467,3469,3472,3474,3476,3479],{"class":444,"line":445},[442,3441,804],{"class":448},[442,3443,2943],{"class":460},[442,3445,904],{"class":456},[442,3447,1166],{"class":634},[442,3449,471],{"class":456},[442,3451,831],{"class":460},[442,3453,556],{"class":456},[442,3455,1176],{"class":634},[442,3457,471],{"class":456},[442,3459,1451],{"class":460},[442,3461,556],{"class":456},[442,3463,3464],{"class":634}," address",[442,3466,471],{"class":456},[442,3468,904],{"class":456},[442,3470,3471],{"class":634}," city",[442,3473,471],{"class":456},[442,3475,1451],{"class":460},[442,3477,3478],{"class":456}," }",[442,3480,2973],{"class":456},[442,3482,3483],{"class":444,"line":485},[442,3484,509],{"emptyLinePlaceholder":508},[442,3486,3487,3489,3492,3494,3496,3498,3500,3502,3504,3506,3508],{"class":444,"line":499},[442,3488,1433],{"class":448},[442,3490,3491],{"class":460}," Name",[442,3493,1299],{"class":456},[442,3495,2943],{"class":460},[442,3497,1123],{"class":492},[442,3499,545],{"class":456},[442,3501,1203],{"class":548},[442,3503,545],{"class":456},[442,3505,643],{"class":492},[442,3507,556],{"class":456},[442,3509,3510],{"class":559},"                  \u002F\u002F string\n",[442,3512,3513,3515,3518,3520,3522,3524,3526,3528,3530,3532,3534],{"class":444,"line":505},[442,3514,1433],{"class":448},[442,3516,3517],{"class":460}," Id",[442,3519,1299],{"class":456},[442,3521,2943],{"class":460},[442,3523,1123],{"class":492},[442,3525,545],{"class":456},[442,3527,826],{"class":548},[442,3529,545],{"class":456},[442,3531,643],{"class":492},[442,3533,556],{"class":456},[442,3535,3536],{"class":559},"                      \u002F\u002F number\n",[442,3538,3539,3541,3544,3546,3548,3550,3552,3555,3557,3560,3562,3565,3567,3569,3571],{"class":444,"line":512},[442,3540,1433],{"class":448},[442,3542,3543],{"class":460}," City",[442,3545,1299],{"class":456},[442,3547,2943],{"class":460},[442,3549,1123],{"class":492},[442,3551,545],{"class":456},[442,3553,3554],{"class":548},"address",[442,3556,545],{"class":456},[442,3558,3559],{"class":492},"][",[442,3561,545],{"class":456},[442,3563,3564],{"class":548},"city",[442,3566,545],{"class":456},[442,3568,643],{"class":492},[442,3570,556],{"class":456},[442,3572,3573],{"class":559},"       \u002F\u002F string nested\n",[442,3575,3576],{"class":444,"line":538},[442,3577,509],{"emptyLinePlaceholder":508},[442,3579,3580],{"class":444,"line":563},[442,3581,3582],{"class":559},"\u002F\u002F Combine với keyof — lookup mọi value type\n",[442,3584,3585,3587,3590,3592,3594,3596,3599,3601,3603,3605],{"class":444,"line":568},[442,3586,1433],{"class":448},[442,3588,3589],{"class":460}," UserValue",[442,3591,1299],{"class":456},[442,3593,2943],{"class":460},[442,3595,1123],{"class":492},[442,3597,3598],{"class":456},"keyof",[442,3600,2943],{"class":460},[442,3602,643],{"class":492},[442,3604,556],{"class":456},[442,3606,3607],{"class":559},"         \u002F\u002F string | number | { city: string }\n",[442,3609,3610],{"class":444,"line":574},[442,3611,509],{"emptyLinePlaceholder":508},[442,3613,3614],{"class":444,"line":629},[442,3615,3616],{"class":559},"\u002F\u002F Array element\n",[442,3618,3619,3621,3624,3626,3628,3630],{"class":444,"line":648},[442,3620,1433],{"class":448},[442,3622,3623],{"class":460}," Items",[442,3625,1299],{"class":456},[442,3627,1451],{"class":460},[442,3629,2052],{"class":492},[442,3631,496],{"class":456},[442,3633,3634,3636,3639,3641,3643,3645,3647,3649,3651],{"class":444,"line":653},[442,3635,1433],{"class":448},[442,3637,3638],{"class":460}," Item",[442,3640,1299],{"class":456},[442,3642,3623],{"class":460},[442,3644,1123],{"class":492},[442,3646,520],{"class":460},[442,3648,643],{"class":492},[442,3650,556],{"class":456},[442,3652,3653],{"class":559},"                 \u002F\u002F string\n",[442,3655,3656],{"class":444,"line":658},[442,3657,509],{"emptyLinePlaceholder":508},[442,3659,3660],{"class":444,"line":664},[442,3661,3662],{"class":559},"\u002F\u002F Tuple element\n",[442,3664,3665,3667,3670,3672,3674,3676,3678,3680,3682,3685,3687],{"class":444,"line":681},[442,3666,1433],{"class":448},[442,3668,3669],{"class":460}," Tup",[442,3671,1299],{"class":456},[442,3673,614],{"class":492},[442,3675,1575],{"class":460},[442,3677,587],{"class":456},[442,3679,831],{"class":460},[442,3681,587],{"class":456},[442,3683,3684],{"class":460}," boolean",[442,3686,643],{"class":492},[442,3688,496],{"class":456},[442,3690,3691,3693,3696,3698,3700,3702,3705,3707,3709],{"class":444,"line":704},[442,3692,1433],{"class":448},[442,3694,3695],{"class":460}," T0",[442,3697,1299],{"class":456},[442,3699,3669],{"class":460},[442,3701,1123],{"class":492},[442,3703,3704],{"class":529},"0",[442,3706,643],{"class":492},[442,3708,556],{"class":456},[442,3710,3711],{"class":559},"                          \u002F\u002F string\n",[442,3713,3714,3716,3719,3721,3723,3725,3727,3729,3731],{"class":444,"line":751},[442,3715,1433],{"class":448},[442,3717,3718],{"class":460}," Any",[442,3720,1299],{"class":456},[442,3722,3669],{"class":460},[442,3724,1123],{"class":492},[442,3726,520],{"class":460},[442,3728,643],{"class":492},[442,3730,556],{"class":456},[442,3732,3733],{"class":559},"                    \u002F\u002F string | number | boolean\n",[427,3735,3737],{"id":3736},"_10-decorator-tc39-stage-3-stable-ts-50-metadata-stable-59","10. Decorator (TC39 stage 3, stable TS 5.0+, metadata stable 5.9)",[432,3739,3741],{"className":434,"code":3740,"language":436,"meta":437,"style":437},"\u002F\u002F Class decorator\nfunction logged\u003CT extends { new (...args: any[]): {} }>(target: T) {\n  return class extends target {\n    constructor(...args: any[]) {\n      super(...args);\n      console.log(`Created ${target.name}`);\n    }\n  };\n}\n\n@logged\nclass Service { }\n\n\u002F\u002F Method decorator (TC39 stage 3 syntax)\nfunction logTime(originalMethod: any, context: ClassMethodDecoratorContext) {\n  return function (this: any, ...args: any[]) {\n    console.time(String(context.name));\n    const result = originalMethod.apply(this, args);\n    console.timeEnd(String(context.name));\n    return result;\n  };\n}\n\nclass Calculator {\n  @logTime\n  sum(a: number, b: number) { return a + b; }\n}\n",[439,3742,3743,3748,3793,3807,3827,3843,3874,3879,3884,3888,3892,3900,3911,3915,3920,3950,3981,4009,4039,4064,4072,4076,4080,4084,4093,4101,4141],{"__ignoreMap":437},[442,3744,3745],{"class":444,"line":445},[442,3746,3747],{"class":559},"\u002F\u002F Class decorator\n",[442,3749,3750,3752,3755,3757,3759,3761,3763,3765,3767,3769,3771,3773,3775,3777,3780,3782,3785,3787,3789,3791],{"class":444,"line":485},[442,3751,449],{"class":448},[442,3753,3754],{"class":452}," logged",[442,3756,457],{"class":456},[442,3758,461],{"class":460},[442,3760,901],{"class":448},[442,3762,904],{"class":456},[442,3764,757],{"class":456},[442,3766,1717],{"class":456},[442,3768,1720],{"class":467},[442,3770,471],{"class":456},[442,3772,1545],{"class":460},[442,3774,2052],{"class":492},[442,3776,477],{"class":456},[442,3778,3779],{"class":456}," {}",[442,3781,914],{"class":456},[442,3783,3784],{"class":467},"target",[442,3786,471],{"class":456},[442,3788,474],{"class":460},[442,3790,533],{"class":456},[442,3792,482],{"class":456},[442,3794,3795,3797,3800,3802,3805],{"class":444,"line":499},[442,3796,489],{"class":488},[442,3798,3799],{"class":448}," class",[442,3801,901],{"class":448},[442,3803,3804],{"class":460}," target",[442,3806,482],{"class":456},[442,3808,3809,3812,3815,3817,3819,3821,3823,3825],{"class":444,"line":505},[442,3810,3811],{"class":448},"    constructor",[442,3813,3814],{"class":456},"(...",[442,3816,1720],{"class":467},[442,3818,471],{"class":456},[442,3820,1545],{"class":460},[442,3822,2052],{"class":634},[442,3824,533],{"class":456},[442,3826,482],{"class":456},[442,3828,3829,3832,3834,3837,3839,3841],{"class":444,"line":512},[442,3830,3831],{"class":492},"      super",[442,3833,526],{"class":634},[442,3835,3836],{"class":456},"...",[442,3838,1720],{"class":492},[442,3840,533],{"class":634},[442,3842,496],{"class":456},[442,3844,3845,3848,3850,3853,3855,3857,3860,3862,3864,3866,3868,3870,3872],{"class":444,"line":538},[442,3846,3847],{"class":492},"      console",[442,3849,944],{"class":456},[442,3851,3852],{"class":452},"log",[442,3854,526],{"class":634},[442,3856,2426],{"class":456},[442,3858,3859],{"class":548},"Created ",[442,3861,2340],{"class":456},[442,3863,3784],{"class":492},[442,3865,944],{"class":456},[442,3867,1203],{"class":492},[442,3869,2357],{"class":456},[442,3871,533],{"class":634},[442,3873,496],{"class":456},[442,3875,3876],{"class":444,"line":563},[442,3877,3878],{"class":456},"    }\n",[442,3880,3881],{"class":444,"line":568},[442,3882,3883],{"class":456},"  };\n",[442,3885,3886],{"class":444,"line":574},[442,3887,502],{"class":456},[442,3889,3890],{"class":444,"line":629},[442,3891,509],{"emptyLinePlaceholder":508},[442,3893,3894,3897],{"class":444,"line":648},[442,3895,3896],{"class":456},"@",[442,3898,3899],{"class":492},"logged\n",[442,3901,3902,3904,3907,3909],{"class":444,"line":653},[442,3903,667],{"class":448},[442,3905,3906],{"class":460}," Service",[442,3908,904],{"class":456},[442,3910,2973],{"class":456},[442,3912,3913],{"class":444,"line":658},[442,3914,509],{"emptyLinePlaceholder":508},[442,3916,3917],{"class":444,"line":664},[442,3918,3919],{"class":559},"\u002F\u002F Method decorator (TC39 stage 3 syntax)\n",[442,3921,3922,3924,3927,3929,3932,3934,3936,3938,3941,3943,3946,3948],{"class":444,"line":681},[442,3923,449],{"class":448},[442,3925,3926],{"class":452}," logTime",[442,3928,526],{"class":456},[442,3930,3931],{"class":467},"originalMethod",[442,3933,471],{"class":456},[442,3935,1545],{"class":460},[442,3937,587],{"class":456},[442,3939,3940],{"class":467}," context",[442,3942,471],{"class":456},[442,3944,3945],{"class":460}," ClassMethodDecoratorContext",[442,3947,533],{"class":456},[442,3949,482],{"class":456},[442,3951,3952,3954,3956,3958,3961,3963,3965,3967,3969,3971,3973,3975,3977,3979],{"class":444,"line":704},[442,3953,489],{"class":488},[442,3955,3218],{"class":448},[442,3957,722],{"class":456},[442,3959,3960],{"class":488},"this",[442,3962,471],{"class":456},[442,3964,1545],{"class":460},[442,3966,587],{"class":456},[442,3968,3237],{"class":456},[442,3970,1720],{"class":467},[442,3972,471],{"class":456},[442,3974,1545],{"class":460},[442,3976,2052],{"class":634},[442,3978,533],{"class":456},[442,3980,482],{"class":456},[442,3982,3983,3986,3988,3991,3993,3996,3998,4001,4003,4005,4007],{"class":444,"line":751},[442,3984,3985],{"class":492},"    console",[442,3987,944],{"class":456},[442,3989,3990],{"class":452},"time",[442,3992,526],{"class":634},[442,3994,3995],{"class":452},"String",[442,3997,526],{"class":634},[442,3999,4000],{"class":492},"context",[442,4002,944],{"class":456},[442,4004,1203],{"class":492},[442,4006,774],{"class":634},[442,4008,496],{"class":456},[442,4010,4011,4014,4017,4019,4022,4024,4027,4029,4032,4035,4037],{"class":444,"line":779},[442,4012,4013],{"class":448},"    const",[442,4015,4016],{"class":492}," result",[442,4018,1299],{"class":456},[442,4020,4021],{"class":492}," originalMethod",[442,4023,944],{"class":456},[442,4025,4026],{"class":452},"apply",[442,4028,526],{"class":634},[442,4030,4031],{"class":456},"this,",[442,4033,4034],{"class":492}," args",[442,4036,533],{"class":634},[442,4038,496],{"class":456},[442,4040,4041,4043,4045,4048,4050,4052,4054,4056,4058,4060,4062],{"class":444,"line":785},[442,4042,3985],{"class":492},[442,4044,944],{"class":456},[442,4046,4047],{"class":452},"timeEnd",[442,4049,526],{"class":634},[442,4051,3995],{"class":452},[442,4053,526],{"class":634},[442,4055,4000],{"class":492},[442,4057,944],{"class":456},[442,4059,1203],{"class":492},[442,4061,774],{"class":634},[442,4063,496],{"class":456},[442,4065,4066,4068,4070],{"class":444,"line":790},[442,4067,754],{"class":488},[442,4069,4016],{"class":492},[442,4071,496],{"class":456},[442,4073,4074],{"class":444,"line":795},[442,4075,3883],{"class":456},[442,4077,4078],{"class":444,"line":801},[442,4079,502],{"class":456},[442,4081,4082],{"class":444,"line":818},[442,4083,509],{"emptyLinePlaceholder":508},[442,4085,4086,4088,4091],{"class":444,"line":846},[442,4087,667],{"class":448},[442,4089,4090],{"class":460}," Calculator",[442,4092,482],{"class":456},[442,4094,4095,4098],{"class":444,"line":868},[442,4096,4097],{"class":456},"  @",[442,4099,4100],{"class":492},"logTime\n",[442,4102,4104,4107,4109,4111,4113,4115,4117,4119,4121,4123,4125,4127,4130,4132,4135,4137,4139],{"class":444,"line":4103},26,[442,4105,4106],{"class":634},"  sum",[442,4108,526],{"class":456},[442,4110,595],{"class":467},[442,4112,471],{"class":456},[442,4114,831],{"class":460},[442,4116,587],{"class":456},[442,4118,605],{"class":467},[442,4120,471],{"class":456},[442,4122,831],{"class":460},[442,4124,533],{"class":456},[442,4126,904],{"class":456},[442,4128,4129],{"class":488}," return",[442,4131,941],{"class":492},[442,4133,4134],{"class":456}," +",[442,4136,605],{"class":492},[442,4138,556],{"class":456},[442,4140,2973],{"class":456},[442,4142,4144],{"class":444,"line":4143},27,[442,4145,502],{"class":456},[1236,4147,4148,4153,4176],{"color":1663,"icon":1664},[1241,4149,4150],{},[1245,4151,4152],{},"Có 2 dạng decorator:",[4154,4155,4156,4170],"ul",{},[4157,4158,4159,722,4162,4165,4166,4169],"li",{},[1245,4160,4161],{},"Legacy \u002F experimental",[439,4163,4164],{},"experimentalDecorators: true"," + ",[439,4167,4168],{},"emitDecoratorMetadata",") — dùng cho NestJS\u002FAngular\u002FTypeORM truyền thống.",[4157,4171,4172,4175],{},[1245,4173,4174],{},"TC39 stage 3"," — chuẩn ECMAScript, stable từ TS 5.0. Khác signature.",[1241,4177,4178],{},"Frameworks đang migrate dần — biết cả 2.",[427,4180,4182],{"id":4181},"_11-module-augmentation-declaration-merging","11. Module augmentation & declaration merging",[432,4184,4186],{"className":434,"code":4185,"language":436,"meta":437,"style":437},"\u002F\u002F Mở rộng module ngoài\ndeclare module \"express\" {\n  interface Request {\n    user?: { id: number; email: string };\n  }\n}\n\n\u002F\u002F Sau đó dùng req.user trong route handler — TS biết kiểu\napp.get(\"\u002Fme\", (req, res) => {\n  res.json(req.user);                       \u002F\u002F typed\n});\n",[439,4187,4188,4193,4210,4220,4246,4250,4254,4258,4263,4299,4325],{"__ignoreMap":437},[442,4189,4190],{"class":444,"line":445},[442,4191,4192],{"class":559},"\u002F\u002F Mở rộng module ngoài\n",[442,4194,4195,4198,4201,4203,4206,4208],{"class":444,"line":485},[442,4196,4197],{"class":448},"declare",[442,4199,4200],{"class":448}," module",[442,4202,995],{"class":456},[442,4204,4205],{"class":548},"express",[442,4207,545],{"class":456},[442,4209,482],{"class":456},[442,4211,4212,4215,4218],{"class":444,"line":499},[442,4213,4214],{"class":448},"  interface",[442,4216,4217],{"class":460}," Request",[442,4219,482],{"class":456},[442,4221,4222,4225,4227,4229,4231,4233,4235,4237,4240,4242,4244],{"class":444,"line":505},[442,4223,4224],{"class":634},"    user",[442,4226,1336],{"class":456},[442,4228,904],{"class":456},[442,4230,1166],{"class":634},[442,4232,471],{"class":456},[442,4234,831],{"class":460},[442,4236,556],{"class":456},[442,4238,4239],{"class":634}," email",[442,4241,471],{"class":456},[442,4243,1451],{"class":460},[442,4245,1188],{"class":456},[442,4247,4248],{"class":444,"line":512},[442,4249,782],{"class":456},[442,4251,4252],{"class":444,"line":538},[442,4253,502],{"class":456},[442,4255,4256],{"class":444,"line":563},[442,4257,509],{"emptyLinePlaceholder":508},[442,4259,4260],{"class":444,"line":568},[442,4261,4262],{"class":559},"\u002F\u002F Sau đó dùng req.user trong route handler — TS biết kiểu\n",[442,4264,4265,4268,4270,4272,4274,4276,4279,4281,4283,4285,4288,4290,4293,4295,4297],{"class":444,"line":574},[442,4266,4267],{"class":492},"app",[442,4269,944],{"class":456},[442,4271,1193],{"class":452},[442,4273,526],{"class":492},[442,4275,545],{"class":456},[442,4277,4278],{"class":548},"\u002Fme",[442,4280,545],{"class":456},[442,4282,587],{"class":456},[442,4284,722],{"class":456},[442,4286,4287],{"class":467},"req",[442,4289,587],{"class":456},[442,4291,4292],{"class":467}," res",[442,4294,533],{"class":456},[442,4296,733],{"class":448},[442,4298,482],{"class":456},[442,4300,4301,4304,4306,4309,4311,4313,4315,4318,4320,4322],{"class":444,"line":629},[442,4302,4303],{"class":492},"  res",[442,4305,944],{"class":456},[442,4307,4308],{"class":452},"json",[442,4310,526],{"class":634},[442,4312,4287],{"class":492},[442,4314,944],{"class":456},[442,4316,4317],{"class":492},"user",[442,4319,533],{"class":634},[442,4321,556],{"class":456},[442,4323,4324],{"class":559},"                       \u002F\u002F typed\n",[442,4326,4327,4329,4331],{"class":444,"line":648},[442,4328,2420],{"class":456},[442,4330,533],{"class":492},[442,4332,496],{"class":456},[427,4334,4336],{"id":4335},"_12-common-patterns-phải-biết","12. Common patterns — phải biết",[4338,4339,4341],"h3",{"id":4340},"branded-type-nominal-type","Branded type \u002F nominal type",[432,4343,4345],{"className":434,"code":4344,"language":436,"meta":437,"style":437},"type UserId = number & { __brand: \"UserId\" };\ntype OrderId = number & { __brand: \"OrderId\" };\n\nfunction getUser(id: UserId) { ... }\n\nconst uid = 1 as UserId;\nconst oid = 2 as OrderId;\ngetUser(uid);          \u002F\u002F OK\ngetUser(oid);          \u002F\u002F ❌ — chống nhầm ID\n",[439,4346,4347,4376,4404,4408,4431,4435,4452,4469,4482],{"__ignoreMap":437},[442,4348,4349,4351,4354,4356,4358,4360,4362,4365,4367,4369,4372,4374],{"class":444,"line":445},[442,4350,1433],{"class":448},[442,4352,4353],{"class":460}," UserId",[442,4355,1299],{"class":456},[442,4357,831],{"class":460},[442,4359,2350],{"class":456},[442,4361,904],{"class":456},[442,4363,4364],{"class":634}," __brand",[442,4366,471],{"class":456},[442,4368,995],{"class":456},[442,4370,4371],{"class":548},"UserId",[442,4373,545],{"class":456},[442,4375,1188],{"class":456},[442,4377,4378,4380,4383,4385,4387,4389,4391,4393,4395,4397,4400,4402],{"class":444,"line":485},[442,4379,1433],{"class":448},[442,4381,4382],{"class":460}," OrderId",[442,4384,1299],{"class":456},[442,4386,831],{"class":460},[442,4388,2350],{"class":456},[442,4390,904],{"class":456},[442,4392,4364],{"class":634},[442,4394,471],{"class":456},[442,4396,995],{"class":456},[442,4398,4399],{"class":548},"OrderId",[442,4401,545],{"class":456},[442,4403,1188],{"class":456},[442,4405,4406],{"class":444,"line":499},[442,4407,509],{"emptyLinePlaceholder":508},[442,4409,4410,4412,4415,4417,4419,4421,4423,4425,4427,4429],{"class":444,"line":505},[442,4411,449],{"class":448},[442,4413,4414],{"class":452}," getUser",[442,4416,526],{"class":456},[442,4418,826],{"class":467},[442,4420,471],{"class":456},[442,4422,4353],{"class":460},[442,4424,533],{"class":456},[442,4426,904],{"class":456},[442,4428,3237],{"class":456},[442,4430,2973],{"class":456},[442,4432,4433],{"class":444,"line":512},[442,4434,509],{"emptyLinePlaceholder":508},[442,4436,4437,4439,4442,4444,4446,4448,4450],{"class":444,"line":538},[442,4438,1155],{"class":448},[442,4440,4441],{"class":492}," uid ",[442,4443,1161],{"class":456},[442,4445,1171],{"class":529},[442,4447,2332],{"class":488},[442,4449,4353],{"class":460},[442,4451,496],{"class":456},[442,4453,4454,4456,4459,4461,4463,4465,4467],{"class":444,"line":563},[442,4455,1155],{"class":448},[442,4457,4458],{"class":492}," oid ",[442,4460,1161],{"class":456},[442,4462,1022],{"class":529},[442,4464,2332],{"class":488},[442,4466,4382],{"class":460},[442,4468,496],{"class":456},[442,4470,4471,4474,4477,4479],{"class":444,"line":568},[442,4472,4473],{"class":452},"getUser",[442,4475,4476],{"class":492},"(uid)",[442,4478,556],{"class":456},[442,4480,4481],{"class":559},"          \u002F\u002F OK\n",[442,4483,4484,4486,4489,4491],{"class":444,"line":574},[442,4485,4473],{"class":452},[442,4487,4488],{"class":492},"(oid)",[442,4490,556],{"class":456},[442,4492,4493],{"class":559},"          \u002F\u002F ❌ — chống nhầm ID\n",[4338,4495,4497],{"id":4496},"type-safe-object-key-iteration","Type-safe object key iteration",[432,4499,4501],{"className":434,"code":4500,"language":436,"meta":437,"style":437},"\u002F\u002F Object.keys trả string[] — TS không biết key cụ thể\nfunction typedKeys\u003CT extends object>(obj: T): (keyof T)[] {\n  return Object.keys(obj) as (keyof T)[];\n}\n\nfor (const key of typedKeys(user)) {\n  user[key];           \u002F\u002F typed correctly\n}\n",[439,4502,4503,4508,4544,4577,4581,4585,4607,4623],{"__ignoreMap":437},[442,4504,4505],{"class":444,"line":445},[442,4506,4507],{"class":559},"\u002F\u002F Object.keys trả string[] — TS không biết key cụ thể\n",[442,4509,4510,4512,4515,4517,4519,4521,4524,4526,4528,4530,4532,4534,4536,4538,4540,4542],{"class":444,"line":485},[442,4511,449],{"class":448},[442,4513,4514],{"class":452}," typedKeys",[442,4516,457],{"class":456},[442,4518,461],{"class":460},[442,4520,901],{"class":448},[442,4522,4523],{"class":460}," object",[442,4525,464],{"class":456},[442,4527,1103],{"class":467},[442,4529,471],{"class":456},[442,4531,474],{"class":460},[442,4533,477],{"class":456},[442,4535,722],{"class":492},[442,4537,3598],{"class":456},[442,4539,474],{"class":460},[442,4541,2024],{"class":492},[442,4543,626],{"class":456},[442,4545,4546,4548,4551,4553,4556,4558,4560,4563,4566,4568,4570,4572,4575],{"class":444,"line":499},[442,4547,489],{"class":488},[442,4549,4550],{"class":492}," Object",[442,4552,944],{"class":456},[442,4554,4555],{"class":452},"keys",[442,4557,526],{"class":634},[442,4559,1103],{"class":492},[442,4561,4562],{"class":634},") ",[442,4564,4565],{"class":488},"as",[442,4567,722],{"class":634},[442,4569,3598],{"class":456},[442,4571,474],{"class":460},[442,4573,4574],{"class":634},")[]",[442,4576,496],{"class":456},[442,4578,4579],{"class":444,"line":505},[442,4580,502],{"class":456},[442,4582,4583],{"class":444,"line":512},[442,4584,509],{"emptyLinePlaceholder":508},[442,4586,4587,4590,4592,4594,4597,4600,4602,4605],{"class":444,"line":538},[442,4588,4589],{"class":488},"for",[442,4591,722],{"class":492},[442,4593,1155],{"class":448},[442,4595,4596],{"class":492}," key ",[442,4598,4599],{"class":456},"of",[442,4601,4514],{"class":452},[442,4603,4604],{"class":492},"(user)) ",[442,4606,626],{"class":456},[442,4608,4609,4612,4614,4616,4618,4620],{"class":444,"line":563},[442,4610,4611],{"class":492},"  user",[442,4613,1123],{"class":634},[442,4615,1142],{"class":492},[442,4617,643],{"class":634},[442,4619,556],{"class":456},[442,4621,4622],{"class":559},"           \u002F\u002F typed correctly\n",[442,4624,4625],{"class":444,"line":568},[442,4626,502],{"class":456},[4338,4628,4630],{"id":4629},"builder-pattern-type-safe","Builder pattern type-safe",[432,4632,4634],{"className":434,"code":4633,"language":436,"meta":437,"style":437},"class QueryBuilder\u003CT = {}> {\n  constructor(private state: T = {} as T) {}\n  \n  where\u003CK extends string, V>(key: K, value: V): QueryBuilder\u003CT & Record\u003CK, V>> {\n    return new QueryBuilder({ ...this.state, [key]: value } as T & Record\u003CK, V>);\n  }\n  \n  build(): T { return this.state; }\n}\n\nconst q = new QueryBuilder()\n  .where(\"name\", \"Alice\")\n  .where(\"age\", 25)\n  .build();\n\u002F\u002F q: { name: string; age: number }\n",[439,4635,4636,4654,4682,4687,4747,4802,4806,4810,4832,4836,4840,4856,4883,4904,4916],{"__ignoreMap":437},[442,4637,4638,4640,4643,4645,4647,4649,4652],{"class":444,"line":445},[442,4639,667],{"class":448},[442,4641,4642],{"class":460}," QueryBuilder",[442,4644,457],{"class":456},[442,4646,461],{"class":460},[442,4648,1299],{"class":456},[442,4650,4651],{"class":456}," {}>",[442,4653,482],{"class":456},[442,4655,4656,4658,4660,4663,4666,4668,4670,4672,4674,4676,4678,4680],{"class":444,"line":485},[442,4657,684],{"class":448},[442,4659,526],{"class":456},[442,4661,4662],{"class":448},"private",[442,4664,4665],{"class":467}," state",[442,4667,471],{"class":456},[442,4669,474],{"class":460},[442,4671,1299],{"class":456},[442,4673,3779],{"class":456},[442,4675,2332],{"class":488},[442,4677,474],{"class":460},[442,4679,533],{"class":456},[442,4681,701],{"class":456},[442,4683,4684],{"class":444,"line":499},[442,4685,4686],{"class":492},"  \n",[442,4688,4689,4692,4694,4696,4698,4700,4702,4705,4707,4709,4711,4713,4715,4717,4719,4721,4723,4725,4727,4729,4731,4734,4736,4738,4740,4742,4745],{"class":444,"line":505},[442,4690,4691],{"class":634},"  where",[442,4693,457],{"class":456},[442,4695,1126],{"class":460},[442,4697,901],{"class":448},[442,4699,1451],{"class":460},[442,4701,587],{"class":456},[442,4703,4704],{"class":460}," V",[442,4706,464],{"class":456},[442,4708,1142],{"class":467},[442,4710,471],{"class":456},[442,4712,1091],{"class":460},[442,4714,587],{"class":456},[442,4716,692],{"class":467},[442,4718,471],{"class":456},[442,4720,4704],{"class":460},[442,4722,477],{"class":456},[442,4724,4642],{"class":460},[442,4726,457],{"class":456},[442,4728,461],{"class":460},[442,4730,2350],{"class":456},[442,4732,4733],{"class":460}," Record",[442,4735,457],{"class":456},[442,4737,1126],{"class":460},[442,4739,587],{"class":456},[442,4741,4704],{"class":460},[442,4743,4744],{"class":456},">>",[442,4746,482],{"class":456},[442,4748,4749,4751,4753,4755,4757,4760,4763,4766,4768,4770,4772,4774,4776,4778,4780,4782,4784,4786,4788,4790,4792,4794,4796,4798,4800],{"class":444,"line":512},[442,4750,754],{"class":488},[442,4752,757],{"class":456},[442,4754,4642],{"class":452},[442,4756,526],{"class":634},[442,4758,4759],{"class":456},"{",[442,4761,4762],{"class":456}," ...this.",[442,4764,4765],{"class":492},"state",[442,4767,587],{"class":456},[442,4769,614],{"class":634},[442,4771,1142],{"class":492},[442,4773,643],{"class":634},[442,4775,471],{"class":456},[442,4777,692],{"class":492},[442,4779,3478],{"class":456},[442,4781,2332],{"class":488},[442,4783,474],{"class":460},[442,4785,2350],{"class":456},[442,4787,4733],{"class":460},[442,4789,457],{"class":456},[442,4791,1126],{"class":460},[442,4793,587],{"class":456},[442,4795,4704],{"class":460},[442,4797,523],{"class":456},[442,4799,533],{"class":634},[442,4801,496],{"class":456},[442,4803,4804],{"class":444,"line":538},[442,4805,782],{"class":456},[442,4807,4808],{"class":444,"line":563},[442,4809,4686],{"class":492},[442,4811,4812,4815,4817,4819,4821,4823,4826,4828,4830],{"class":444,"line":568},[442,4813,4814],{"class":634},"  build",[442,4816,3224],{"class":456},[442,4818,474],{"class":460},[442,4820,904],{"class":456},[442,4822,4129],{"class":488},[442,4824,4825],{"class":456}," this.",[442,4827,4765],{"class":492},[442,4829,556],{"class":456},[442,4831,2973],{"class":456},[442,4833,4834],{"class":444,"line":574},[442,4835,502],{"class":456},[442,4837,4838],{"class":444,"line":629},[442,4839,509],{"emptyLinePlaceholder":508},[442,4841,4842,4844,4847,4849,4851,4853],{"class":444,"line":648},[442,4843,1155],{"class":448},[442,4845,4846],{"class":492}," q ",[442,4848,1161],{"class":456},[442,4850,757],{"class":456},[442,4852,4642],{"class":452},[442,4854,4855],{"class":492},"()\n",[442,4857,4858,4861,4864,4866,4868,4870,4872,4874,4876,4878,4880],{"class":444,"line":653},[442,4859,4860],{"class":456},"  .",[442,4862,4863],{"class":452},"where",[442,4865,526],{"class":492},[442,4867,545],{"class":456},[442,4869,1203],{"class":548},[442,4871,545],{"class":456},[442,4873,587],{"class":456},[442,4875,995],{"class":456},[442,4877,1183],{"class":548},[442,4879,545],{"class":456},[442,4881,4882],{"class":492},")\n",[442,4884,4885,4887,4889,4891,4893,4895,4897,4899,4902],{"class":444,"line":658},[442,4886,4860],{"class":456},[442,4888,4863],{"class":452},[442,4890,526],{"class":492},[442,4892,545],{"class":456},[442,4894,1225],{"class":548},[442,4896,545],{"class":456},[442,4898,587],{"class":456},[442,4900,4901],{"class":529}," 25",[442,4903,4882],{"class":492},[442,4905,4906,4908,4911,4914],{"class":444,"line":664},[442,4907,4860],{"class":456},[442,4909,4910],{"class":452},"build",[442,4912,4913],{"class":492},"()",[442,4915,496],{"class":456},[442,4917,4918],{"class":444,"line":681},[442,4919,4920],{"class":559},"\u002F\u002F q: { name: string; age: number }\n",[427,4922,4924],{"id":4923},"_13-typescript-70-go-compiler-song-song-hóa-type-checking","13. TypeScript 7.0 — Go compiler & song song hóa type-checking",[1241,4926,4927,4928,4931,4932,4935],{},"TS 7.0 là bản nâng cấp lớn nhất từ trước đến nay: toàn bộ compiler được viết lại bằng ",[1245,4929,4930],{},"Go",", thay thế JavaScript cũ. Điểm nổi bật nhất là ",[1245,4933,4934],{},"type-checking song song"," — nhiều luồng kiểm tra type cùng lúc.",[4338,4937,4939],{"id":4938},"cli-flags-mới","CLI flags mới",[432,4941,4945],{"className":4942,"code":4943,"language":4944,"meta":437,"style":437},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Type-checking song song\ntsgo --checkers 8          # 8 worker thread kiểm tra type (mặc định 4)\n\n# Build song song cho monorepo\ntsgo --builders 4          # 4 project reference builder song song\n\n# Chạy đơn luồng (khi debug)\ntsgo --singleThreaded\n\n# Kết hợp: --checkers 4 --builders 4 = tối đa 16 type-checker đồng thời\n","bash",[439,4946,4947,4952,4966,4970,4975,4988,4992,4997,5004,5008],{"__ignoreMap":437},[442,4948,4949],{"class":444,"line":445},[442,4950,4951],{"class":559},"# Type-checking song song\n",[442,4953,4954,4957,4960,4963],{"class":444,"line":485},[442,4955,4956],{"class":460},"tsgo",[442,4958,4959],{"class":548}," --checkers",[442,4961,4962],{"class":529}," 8",[442,4964,4965],{"class":559},"          # 8 worker thread kiểm tra type (mặc định 4)\n",[442,4967,4968],{"class":444,"line":499},[442,4969,509],{"emptyLinePlaceholder":508},[442,4971,4972],{"class":444,"line":505},[442,4973,4974],{"class":559},"# Build song song cho monorepo\n",[442,4976,4977,4979,4982,4985],{"class":444,"line":512},[442,4978,4956],{"class":460},[442,4980,4981],{"class":548}," --builders",[442,4983,4984],{"class":529}," 4",[442,4986,4987],{"class":559},"          # 4 project reference builder song song\n",[442,4989,4990],{"class":444,"line":538},[442,4991,509],{"emptyLinePlaceholder":508},[442,4993,4994],{"class":444,"line":563},[442,4995,4996],{"class":559},"# Chạy đơn luồng (khi debug)\n",[442,4998,4999,5001],{"class":444,"line":568},[442,5000,4956],{"class":460},[442,5002,5003],{"class":548}," --singleThreaded\n",[442,5005,5006],{"class":444,"line":574},[442,5007,509],{"emptyLinePlaceholder":508},[442,5009,5010],{"class":444,"line":629},[442,5011,5012],{"class":559},"# Kết hợp: --checkers 4 --builders 4 = tối đa 16 type-checker đồng thời\n",[4338,5014,5016],{"id":5015},"cách-parallel-type-checking-hoạt-động","Cách parallel type-checking hoạt động",[4154,5018,5019,5025,5032,5038,5048,5051],{},[4157,5020,5021,5022],{},"Mỗi worker nhận ",[1245,5023,5024],{},"input file giống hệt nhau",[4157,5026,5027,5028,5031],{},"Phân chia công việc ",[1245,5029,5030],{},"deterministic"," — cùng kết quả mỗi lần chạy",[4157,5033,5034,5037],{},[439,5035,5036],{},"stableTypeOrdering: true"," bắt buộc — đảm bảo kết quả nhất quán giữa các worker",[4157,5039,5040,5043,5044,5047],{},[1245,5041,5042],{},"Parsing"," và ",[1245,5045,5046],{},"emitting"," cũng được song song hóa tự động",[4157,5049,5050],{},"Dùng nhiều checker → dùng nhiều RAM hơn — cần tune cẩn thận",[4157,5052,5053,5054,1672,5057],{},"Hiệu ứng ",[1245,5055,5056],{},"cấp số nhân",[439,5058,5059],{},"--builders × --checkers",[4338,5061,5063],{"id":5062},"performance-tuning","Performance tuning",[2763,5065,5066,5076],{},[2766,5067,5068],{},[2769,5069,5070,5073],{},[2772,5071,5072],{},"Tình huống",[2772,5074,5075],{},"Gợi ý",[2779,5077,5078,5089,5100,5111,5122,5133],{},[2769,5079,5080,5083],{},[2784,5081,5082],{},"Dự án nhỏ (\u003C 500 file)",[2784,5084,5085,5088],{},[439,5086,5087],{},"--checkers 2"," — đủ dùng, tiết kiệm RAM",[2769,5090,5091,5094],{},[2784,5092,5093],{},"Dự án vừa (500 – 5000 file)",[2784,5095,5096,5099],{},[439,5097,5098],{},"--checkers 4"," (mặc định)",[2769,5101,5102,5105],{},[2784,5103,5104],{},"Dự án lớn (> 5000 file)",[2784,5106,5107,5110],{},[439,5108,5109],{},"--checkers 8"," hoặc cao hơn, monitor RAM",[2769,5112,5113,5116],{},[2784,5114,5115],{},"Monorepo nhiều package",[2784,5117,5118,5121],{},[439,5119,5120],{},"--builders 4"," cho project references",[2769,5123,5124,5127],{},[2784,5125,5126],{},"CI\u002FCD pipeline",[2784,5128,5129,5132],{},[439,5130,5131],{},"--checkers 8 --builders 2"," — ưu tiên type-check từng project",[2769,5134,5135,5138],{},[2784,5136,5137],{},"Local dev",[2784,5139,5140,4165,5143,5146],{},[439,5141,5142],{},"--incremental",[439,5144,5145],{},"--watch"," — rebuild nhanh",[4338,5148,5150],{"id":5149},"chiến-lược-monorepo","Chiến lược monorepo",[432,5152,5154],{"className":4942,"code":5153,"language":4944,"meta":437,"style":437},"# Build toàn bộ monorepo với project references\ntsgo --build tsconfig.json --builders 4\n\n# Chỉ type-check dự án hiện tại (không build dependency)\ntsgo --noEmit --checkers 8\n\n# Watch mode — rebuild khi file thay đổi (dùng @parcel\u002Fwatcher port)\ntsgo --watch --incremental\n",[439,5155,5156,5161,5176,5180,5185,5197,5201,5206],{"__ignoreMap":437},[442,5157,5158],{"class":444,"line":445},[442,5159,5160],{"class":559},"# Build toàn bộ monorepo với project references\n",[442,5162,5163,5165,5168,5171,5173],{"class":444,"line":485},[442,5164,4956],{"class":460},[442,5166,5167],{"class":548}," --build",[442,5169,5170],{"class":548}," tsconfig.json",[442,5172,4981],{"class":548},[442,5174,5175],{"class":529}," 4\n",[442,5177,5178],{"class":444,"line":499},[442,5179,509],{"emptyLinePlaceholder":508},[442,5181,5182],{"class":444,"line":505},[442,5183,5184],{"class":559},"# Chỉ type-check dự án hiện tại (không build dependency)\n",[442,5186,5187,5189,5192,5194],{"class":444,"line":512},[442,5188,4956],{"class":460},[442,5190,5191],{"class":548}," --noEmit",[442,5193,4959],{"class":548},[442,5195,5196],{"class":529}," 8\n",[442,5198,5199],{"class":444,"line":538},[442,5200,509],{"emptyLinePlaceholder":508},[442,5202,5203],{"class":444,"line":563},[442,5204,5205],{"class":559},"# Watch mode — rebuild khi file thay đổi (dùng @parcel\u002Fwatcher port)\n",[442,5207,5208,5210,5213],{"class":444,"line":568},[442,5209,4956],{"class":460},[442,5211,5212],{"class":548}," --watch",[442,5214,5215],{"class":548}," --incremental\n",[4338,5217,5219],{"id":5218},"stabletypeordering-union-ordering-bắt-buộc","stableTypeOrdering — union ordering bắt buộc",[1236,5221,5223,5235],{"color":1238,"icon":5222},"i-lucide-alert-triangle",[1241,5224,1243,5225,5228,5229,1248,5232,944],{},[1245,5226,5227],{},"Quan trọng cho advanced types:"," Trong TS 7.0, ",[439,5230,5231],{},"stableTypeOrdering",[1245,5233,5234],{},"luôn bật, không tắt được",[4154,5236,5237,5243,5249],{},[4157,5238,5239,5240,5242],{},"Union types có thứ tự ",[1245,5241,5030],{}," giữa mọi lần build",[4157,5244,5245,5246],{},"Conditional types phụ thuộc thứ tự union sẽ chạy ",[1245,5247,5248],{},"nhất quán",[4157,5250,5251,5252,5255],{},"Có thể ",[1245,5253,5254],{},"lộ bug"," nếu code của bạn vô tình dựa vào thứ tự union cũ (không ổn định)",[432,5257,5259],{"className":434,"code":5258,"language":436,"meta":437,"style":437},"\u002F\u002F TS 7.0: union ordering luôn deterministic\ntype A = \"a\" | \"b\" | \"c\";   \u002F\u002F luôn \"a\" | \"b\" | \"c\" (theo thứ tự khai báo)\ntype B = \"c\" | \"b\" | \"a\";   \u002F\u002F luôn \"a\" | \"b\" | \"c\" (TS sắp xếp canonical)\n\n\u002F\u002F Conditional distributive qua union — kết quả nhất quán giữa mọi lần build\ntype Filter\u003CT, U> = T extends U ? T : never;\ntype R = Filter\u003C\"a\" | \"b\" | \"c\", \"b\" | \"c\">;  \u002F\u002F \"b\" | \"c\" — deterministic\n",[439,5260,5261,5266,5303,5338,5342,5347,5382],{"__ignoreMap":437},[442,5262,5263],{"class":444,"line":445},[442,5264,5265],{"class":559},"\u002F\u002F TS 7.0: union ordering luôn deterministic\n",[442,5267,5268,5270,5272,5274,5276,5278,5280,5282,5284,5287,5289,5291,5293,5296,5298,5300],{"class":444,"line":485},[442,5269,1433],{"class":448},[442,5271,600],{"class":460},[442,5273,1299],{"class":456},[442,5275,995],{"class":456},[442,5277,595],{"class":548},[442,5279,545],{"class":456},[442,5281,838],{"class":456},[442,5283,995],{"class":456},[442,5285,5286],{"class":548},"b",[442,5288,545],{"class":456},[442,5290,838],{"class":456},[442,5292,995],{"class":456},[442,5294,5295],{"class":548},"c",[442,5297,545],{"class":456},[442,5299,556],{"class":456},[442,5301,5302],{"class":559},"   \u002F\u002F luôn \"a\" | \"b\" | \"c\" (theo thứ tự khai báo)\n",[442,5304,5305,5307,5309,5311,5313,5315,5317,5319,5321,5323,5325,5327,5329,5331,5333,5335],{"class":444,"line":499},[442,5306,1433],{"class":448},[442,5308,590],{"class":460},[442,5310,1299],{"class":456},[442,5312,995],{"class":456},[442,5314,5295],{"class":548},[442,5316,545],{"class":456},[442,5318,838],{"class":456},[442,5320,995],{"class":456},[442,5322,5286],{"class":548},[442,5324,545],{"class":456},[442,5326,838],{"class":456},[442,5328,995],{"class":456},[442,5330,595],{"class":548},[442,5332,545],{"class":456},[442,5334,556],{"class":456},[442,5336,5337],{"class":559},"   \u002F\u002F luôn \"a\" | \"b\" | \"c\" (TS sắp xếp canonical)\n",[442,5339,5340],{"class":444,"line":505},[442,5341,509],{"emptyLinePlaceholder":508},[442,5343,5344],{"class":444,"line":512},[442,5345,5346],{"class":559},"\u002F\u002F Conditional distributive qua union — kết quả nhất quán giữa mọi lần build\n",[442,5348,5349,5351,5354,5356,5358,5360,5362,5364,5366,5368,5370,5372,5374,5376,5378,5380],{"class":444,"line":538},[442,5350,1433],{"class":448},[442,5352,5353],{"class":460}," Filter",[442,5355,457],{"class":456},[442,5357,461],{"class":460},[442,5359,587],{"class":456},[442,5361,736],{"class":460},[442,5363,523],{"class":456},[442,5365,1299],{"class":456},[442,5367,474],{"class":460},[442,5369,901],{"class":448},[442,5371,736],{"class":460},[442,5373,959],{"class":456},[442,5375,474],{"class":460},[442,5377,964],{"class":456},[442,5379,1557],{"class":460},[442,5381,496],{"class":456},[442,5383,5384,5386,5388,5390,5392,5394,5396,5398,5400,5402,5404,5406,5408,5410,5412,5414,5416,5418,5420,5422,5424,5426,5428,5430,5432,5434],{"class":444,"line":563},[442,5385,1433],{"class":448},[442,5387,1734],{"class":460},[442,5389,1299],{"class":456},[442,5391,5353],{"class":460},[442,5393,457],{"class":456},[442,5395,545],{"class":456},[442,5397,595],{"class":548},[442,5399,545],{"class":456},[442,5401,838],{"class":456},[442,5403,995],{"class":456},[442,5405,5286],{"class":548},[442,5407,545],{"class":456},[442,5409,838],{"class":456},[442,5411,995],{"class":456},[442,5413,5295],{"class":548},[442,5415,545],{"class":456},[442,5417,587],{"class":456},[442,5419,995],{"class":456},[442,5421,5286],{"class":548},[442,5423,545],{"class":456},[442,5425,838],{"class":456},[442,5427,995],{"class":456},[442,5429,5295],{"class":548},[442,5431,545],{"class":456},[442,5433,1492],{"class":456},[442,5435,5436],{"class":559},"  \u002F\u002F \"b\" | \"c\" — deterministic\n",[4338,5438,5440],{"id":5439},"programmatic-api-cảnh-báo","Programmatic API — CẢNH BÁO",[1236,5442,5443,5449,5499],{"color":2501,"icon":5222},[1241,5444,5445,5446],{},"🚨 ",[1245,5447,5448],{},"TS 7.0 không có Compiler API cũ!",[4154,5450,5451,5466,5483,5489],{},[4157,5452,5453,3277,5456,3277,5459,5462,5463],{},[439,5454,5455],{},"ts.createProgram",[439,5457,5458],{},"ts.createSourceFile",[439,5460,5461],{},"ts.transform"," — ",[1245,5464,5465],{},"đã bị xóa",[4157,5467,5468,5469,3277,5472,3277,5475,5478,5479,5482],{},"Các tool như ",[1245,5470,5471],{},"ts-morph",[1245,5473,5474],{},"ts-jest",[1245,5476,5477],{},"ts-node"," hiện ",[1245,5480,5481],{},"không hoạt động"," với tsgo",[4157,5484,5485,5486],{},"Compiler API mới sẽ có trong ",[1245,5487,5488],{},"TS 7.1",[4157,5490,5491,5492,5495,5496,5498],{},"Giải pháp tạm thời: giữ ",[1245,5493,5494],{},"TS 6"," cho tool cần API, dùng ",[1245,5497,4956],{}," cho build và type-check",[432,5500,5502],{"className":4942,"code":5501,"language":4944,"meta":437,"style":437},"# Build & type-check — dùng tsgo\nnpx tsgo --noEmit\n\n# Tool cần Compiler API — dùng TS 6\nnpx tsc --version   # vẫn là TS 6.x\n",[439,5503,5504,5509,5520,5524,5529],{"__ignoreMap":437},[442,5505,5506],{"class":444,"line":445},[442,5507,5508],{"class":559},"# Build & type-check — dùng tsgo\n",[442,5510,5511,5514,5517],{"class":444,"line":485},[442,5512,5513],{"class":460},"npx",[442,5515,5516],{"class":548}," tsgo",[442,5518,5519],{"class":548}," --noEmit\n",[442,5521,5522],{"class":444,"line":499},[442,5523,509],{"emptyLinePlaceholder":508},[442,5525,5526],{"class":444,"line":505},[442,5527,5528],{"class":559},"# Tool cần Compiler API — dùng TS 6\n",[442,5530,5531,5533,5536,5539],{"class":444,"line":512},[442,5532,5513],{"class":460},[442,5534,5535],{"class":548}," tsc",[442,5537,5538],{"class":548}," --version",[442,5540,5541],{"class":559},"   # vẫn là TS 6.x\n",[4338,5543,5545],{"id":5544},"build-mode-cải-tiến","Build mode cải tiến",[432,5547,5549],{"className":4942,"code":5548,"language":4944,"meta":437,"style":437},"# Watch mode (viết lại bằng Go, dùng @parcel\u002Fwatcher port)\ntsgo --watch\n\n# Build kèm declaration files\ntsgo --declaration\n\n# Build incremental\ntsgo --incremental\n\n# Project references (hỗ trợ đầy đủ)\ntsgo --build tsconfig.json\n",[439,5550,5551,5556,5563,5567,5572,5579,5583,5588,5594,5598,5603],{"__ignoreMap":437},[442,5552,5553],{"class":444,"line":445},[442,5554,5555],{"class":559},"# Watch mode (viết lại bằng Go, dùng @parcel\u002Fwatcher port)\n",[442,5557,5558,5560],{"class":444,"line":485},[442,5559,4956],{"class":460},[442,5561,5562],{"class":548}," --watch\n",[442,5564,5565],{"class":444,"line":499},[442,5566,509],{"emptyLinePlaceholder":508},[442,5568,5569],{"class":444,"line":505},[442,5570,5571],{"class":559},"# Build kèm declaration files\n",[442,5573,5574,5576],{"class":444,"line":512},[442,5575,4956],{"class":460},[442,5577,5578],{"class":548}," --declaration\n",[442,5580,5581],{"class":444,"line":538},[442,5582,509],{"emptyLinePlaceholder":508},[442,5584,5585],{"class":444,"line":563},[442,5586,5587],{"class":559},"# Build incremental\n",[442,5589,5590,5592],{"class":444,"line":568},[442,5591,4956],{"class":460},[442,5593,5215],{"class":548},[442,5595,5596],{"class":444,"line":574},[442,5597,509],{"emptyLinePlaceholder":508},[442,5599,5600],{"class":444,"line":629},[442,5601,5602],{"class":559},"# Project references (hỗ trợ đầy đủ)\n",[442,5604,5605,5607,5609],{"class":444,"line":648},[442,5606,4956],{"class":460},[442,5608,5167],{"class":548},[442,5610,5611],{"class":548}," tsconfig.json\n",[427,5613,5615],{"id":5614},"_14-ts-60-tính-năng-chuyển-tiếp","14. TS 6.0 — tính năng chuyển tiếp",[4338,5617,5619],{"id":5618},"nouncheckedsideeffectimports",[439,5620,5621],{},"noUncheckedSideEffectImports",[432,5623,5626],{"className":5624,"code":5625,"language":4308,"meta":437,"style":437},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F tsconfig.json — mặc định bật từ TS 6.0+\n{\n  \"compilerOptions\": {\n    \"noUncheckedSideEffectImports\": true\n  }\n}\n",[439,5627,5628,5633,5637,5651,5665,5669],{"__ignoreMap":437},[442,5629,5630],{"class":444,"line":445},[442,5631,5632],{"class":559},"\u002F\u002F tsconfig.json — mặc định bật từ TS 6.0+\n",[442,5634,5635],{"class":444,"line":485},[442,5636,626],{"class":456},[442,5638,5639,5642,5645,5647,5649],{"class":444,"line":499},[442,5640,5641],{"class":456},"  \"",[442,5643,5644],{"class":448},"compilerOptions",[442,5646,545],{"class":456},[442,5648,471],{"class":456},[442,5650,482],{"class":456},[442,5652,5653,5656,5658,5660,5662],{"class":444,"line":505},[442,5654,5655],{"class":456},"    \"",[442,5657,5621],{"class":460},[442,5659,545],{"class":456},[442,5661,471],{"class":456},[442,5663,5664],{"class":456}," true\n",[442,5666,5667],{"class":444,"line":512},[442,5668,782],{"class":456},[442,5670,5671],{"class":444,"line":538},[442,5672,502],{"class":456},[1241,5674,5675],{},"Bắt lỗi import side-effect không kiểm soát:",[432,5677,5679],{"className":434,"code":5678,"language":436,"meta":437,"style":437},"\u002F\u002F ❌ Bị bắt nếu file import không có type\u002Fvalue export\nimport \".\u002Fpolyfills\";           \u002F\u002F side-effect import — phải khai báo rõ\n\n\u002F\u002F ✅ OK nếu polyfills.ts có export ít nhất 1 type\u002Fvalue\nimport \".\u002Fsetup\";               \u002F\u002F setup.ts export hàm init()\n",[439,5680,5681,5686,5703,5707,5712],{"__ignoreMap":437},[442,5682,5683],{"class":444,"line":445},[442,5684,5685],{"class":559},"\u002F\u002F ❌ Bị bắt nếu file import không có type\u002Fvalue export\n",[442,5687,5688,5691,5693,5696,5698,5700],{"class":444,"line":485},[442,5689,5690],{"class":488},"import",[442,5692,995],{"class":456},[442,5694,5695],{"class":548},".\u002Fpolyfills",[442,5697,545],{"class":456},[442,5699,556],{"class":456},[442,5701,5702],{"class":559},"           \u002F\u002F side-effect import — phải khai báo rõ\n",[442,5704,5705],{"class":444,"line":499},[442,5706,509],{"emptyLinePlaceholder":508},[442,5708,5709],{"class":444,"line":505},[442,5710,5711],{"class":559},"\u002F\u002F ✅ OK nếu polyfills.ts có export ít nhất 1 type\u002Fvalue\n",[442,5713,5714,5716,5718,5721,5723,5725],{"class":444,"line":512},[442,5715,5690],{"class":488},[442,5717,995],{"class":456},[442,5719,5720],{"class":548},".\u002Fsetup",[442,5722,545],{"class":456},[442,5724,556],{"class":456},[442,5726,5727],{"class":559},"               \u002F\u002F setup.ts export hàm init()\n",[4338,5729,5731],{"id":5730},"temporal-api-kiểu-dựng-sẵn","Temporal API — kiểu dựng sẵn",[432,5733,5735],{"className":434,"code":5734,"language":436,"meta":437,"style":437},"\u002F\u002F Temporal API (Stage 3) — có sẵn lib typing trong TS 6.0+\nconst now = Temporal.Now.plainDateISO();       \u002F\u002F Temporal.PlainDate\nconst zoned = Temporal.Now.zonedDateTimeISO(\"Asia\u002FSaigon\"); \u002F\u002F Temporal.ZonedDateTime\nconst dur = Temporal.Duration.from({ hours: 2, minutes: 30 }); \u002F\u002F Temporal.Duration\n",[439,5736,5737,5742,5771,5807],{"__ignoreMap":437},[442,5738,5739],{"class":444,"line":445},[442,5740,5741],{"class":559},"\u002F\u002F Temporal API (Stage 3) — có sẵn lib typing trong TS 6.0+\n",[442,5743,5744,5746,5749,5751,5754,5756,5759,5761,5764,5766,5768],{"class":444,"line":485},[442,5745,1155],{"class":448},[442,5747,5748],{"class":492}," now ",[442,5750,1161],{"class":456},[442,5752,5753],{"class":492}," Temporal",[442,5755,944],{"class":456},[442,5757,5758],{"class":492},"Now",[442,5760,944],{"class":456},[442,5762,5763],{"class":452},"plainDateISO",[442,5765,4913],{"class":492},[442,5767,556],{"class":456},[442,5769,5770],{"class":559},"       \u002F\u002F Temporal.PlainDate\n",[442,5772,5773,5775,5778,5780,5782,5784,5786,5788,5791,5793,5795,5798,5800,5802,5804],{"class":444,"line":499},[442,5774,1155],{"class":448},[442,5776,5777],{"class":492}," zoned ",[442,5779,1161],{"class":456},[442,5781,5753],{"class":492},[442,5783,944],{"class":456},[442,5785,5758],{"class":492},[442,5787,944],{"class":456},[442,5789,5790],{"class":452},"zonedDateTimeISO",[442,5792,526],{"class":492},[442,5794,545],{"class":456},[442,5796,5797],{"class":548},"Asia\u002FSaigon",[442,5799,545],{"class":456},[442,5801,533],{"class":492},[442,5803,556],{"class":456},[442,5805,5806],{"class":559}," \u002F\u002F Temporal.ZonedDateTime\n",[442,5808,5809,5811,5814,5816,5818,5820,5823,5825,5828,5830,5832,5835,5837,5839,5841,5844,5846,5849,5851,5853,5855],{"class":444,"line":505},[442,5810,1155],{"class":448},[442,5812,5813],{"class":492}," dur ",[442,5815,1161],{"class":456},[442,5817,5753],{"class":492},[442,5819,944],{"class":456},[442,5821,5822],{"class":492},"Duration",[442,5824,944],{"class":456},[442,5826,5827],{"class":452},"from",[442,5829,526],{"class":492},[442,5831,4759],{"class":456},[442,5833,5834],{"class":634}," hours",[442,5836,471],{"class":456},[442,5838,1022],{"class":529},[442,5840,587],{"class":456},[442,5842,5843],{"class":634}," minutes",[442,5845,471],{"class":456},[442,5847,5848],{"class":529}," 30",[442,5850,3478],{"class":456},[442,5852,533],{"class":492},[442,5854,556],{"class":456},[442,5856,5857],{"class":559}," \u002F\u002F Temporal.Duration\n",[4338,5859,5861],{"id":5860},"regexpescape",[439,5862,5863],{},"RegExp.escape()",[432,5865,5867],{"className":434,"code":5866,"language":436,"meta":437,"style":437},"\u002F\u002F Escape string để dùng trong RegExp — có typing sẵn\nconst escaped = RegExp.escape(\".$?*+{}|()[]\"); \u002F\u002F \"\\\\.\\\\$\\\\?\\\\*\\\\+\\\\{\\\\}\\\\|\\\\(\\\\)\\\\[\\\\]\"\nconst re = new RegExp(escaped);                 \u002F\u002F RegExp\n",[439,5868,5869,5874,5907],{"__ignoreMap":437},[442,5870,5871],{"class":444,"line":445},[442,5872,5873],{"class":559},"\u002F\u002F Escape string để dùng trong RegExp — có typing sẵn\n",[442,5875,5876,5878,5881,5883,5886,5888,5891,5893,5895,5898,5900,5902,5904],{"class":444,"line":485},[442,5877,1155],{"class":448},[442,5879,5880],{"class":492}," escaped ",[442,5882,1161],{"class":456},[442,5884,5885],{"class":492}," RegExp",[442,5887,944],{"class":456},[442,5889,5890],{"class":452},"escape",[442,5892,526],{"class":492},[442,5894,545],{"class":456},[442,5896,5897],{"class":548},".$?*+{}|()[]",[442,5899,545],{"class":456},[442,5901,533],{"class":492},[442,5903,556],{"class":456},[442,5905,5906],{"class":559}," \u002F\u002F \"\\\\.\\\\$\\\\?\\\\*\\\\+\\\\{\\\\}\\\\|\\\\(\\\\)\\\\[\\\\]\"\n",[442,5908,5909,5911,5914,5916,5918,5920,5923,5925],{"class":444,"line":499},[442,5910,1155],{"class":448},[442,5912,5913],{"class":492}," re ",[442,5915,1161],{"class":456},[442,5917,757],{"class":456},[442,5919,5885],{"class":452},[442,5921,5922],{"class":492},"(escaped)",[442,5924,556],{"class":456},[442,5926,5927],{"class":559},"                 \u002F\u002F RegExp\n",[4338,5929,5931],{"id":5930},"iterable-asynciterable-trên-dom-types","Iterable & AsyncIterable trên DOM types",[432,5933,5935],{"className":434,"code":5934,"language":436,"meta":437,"style":437},"\u002F\u002F DOM collections giờ implement Iterable \u002F AsyncIterable\nconst nodes = document.querySelectorAll(\"div\");\nfor (const el of nodes) { }           \u002F\u002F ✅ Iterable\u003CHTMLDivElement>\n\nconst stream = response.body;         \u002F\u002F ReadableStream\nfor await (const chunk of stream) { } \u002F\u002F ✅ AsyncIterable\u003CUint8Array>\n",[439,5936,5937,5942,5972,5995,5999,6021],{"__ignoreMap":437},[442,5938,5939],{"class":444,"line":445},[442,5940,5941],{"class":559},"\u002F\u002F DOM collections giờ implement Iterable \u002F AsyncIterable\n",[442,5943,5944,5946,5949,5951,5954,5956,5959,5961,5963,5966,5968,5970],{"class":444,"line":485},[442,5945,1155],{"class":448},[442,5947,5948],{"class":492}," nodes ",[442,5950,1161],{"class":456},[442,5952,5953],{"class":492}," document",[442,5955,944],{"class":456},[442,5957,5958],{"class":452},"querySelectorAll",[442,5960,526],{"class":492},[442,5962,545],{"class":456},[442,5964,5965],{"class":548},"div",[442,5967,545],{"class":456},[442,5969,533],{"class":492},[442,5971,496],{"class":456},[442,5973,5974,5976,5978,5980,5983,5985,5988,5990,5992],{"class":444,"line":499},[442,5975,4589],{"class":488},[442,5977,722],{"class":492},[442,5979,1155],{"class":448},[442,5981,5982],{"class":492}," el ",[442,5984,4599],{"class":456},[442,5986,5987],{"class":492}," nodes) ",[442,5989,4759],{"class":456},[442,5991,3478],{"class":456},[442,5993,5994],{"class":559},"           \u002F\u002F ✅ Iterable\u003CHTMLDivElement>\n",[442,5996,5997],{"class":444,"line":505},[442,5998,509],{"emptyLinePlaceholder":508},[442,6000,6001,6003,6006,6008,6011,6013,6016,6018],{"class":444,"line":512},[442,6002,1155],{"class":448},[442,6004,6005],{"class":492}," stream ",[442,6007,1161],{"class":456},[442,6009,6010],{"class":492}," response",[442,6012,944],{"class":456},[442,6014,6015],{"class":492},"body",[442,6017,556],{"class":456},[442,6019,6020],{"class":559},"         \u002F\u002F ReadableStream\n",[442,6022,6023,6025,6028,6030,6032,6035,6037,6040,6042,6044],{"class":444,"line":538},[442,6024,4589],{"class":488},[442,6026,6027],{"class":488}," await",[442,6029,722],{"class":492},[442,6031,1155],{"class":448},[442,6033,6034],{"class":492}," chunk ",[442,6036,4599],{"class":456},[442,6038,6039],{"class":492}," stream) ",[442,6041,4759],{"class":456},[442,6043,3478],{"class":456},[442,6045,6046],{"class":559}," \u002F\u002F ✅ AsyncIterable\u003CUint8Array>\n",[1236,6048,6049,6057],{"color":1238,"icon":1239},[1241,6050,1243,6051,1248,6054],{},[1245,6052,6053],{},"Câu PV:",[1250,6055,6056],{},"\"TS 7.0 thay đổi gì lớn nhất?\"",[1257,6058,6059],{},[1241,6060,6061,6062,6065,6066,6068,6069,3277,6071,3277,6073,6076,6077,6079],{},"\"Compiler viết lại bằng Go, hỗ trợ type-checking song song với ",[439,6063,6064],{},"--checkers",". ",[439,6067,5231],{}," bắt buộc khiến union ordering deterministic. Compiler API cũ bị xóa — tool như ts-morph\u002Fts-node chưa hoạt động cho đến TS 7.1. Build mode có ",[439,6070,5145],{},[439,6072,5142],{},[439,6074,6075],{},"--declaration"," chạy qua ",[439,6078,4956],{},".\"",[1236,6081,6083,6084],{"color":1663,"icon":6082},"i-lucide-arrow-right","Tiếp theo: ",[595,6085,6086],{"href":308},"Câu hỏi phỏng vấn TypeScript",[6088,6089,6090],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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);}",{"title":437,"searchDepth":485,"depth":485,"links":6092},[6093,6094,6096,6097,6099,6101,6102,6103,6104,6106,6107,6108,6113,6122],{"id":429,"depth":485,"text":430},{"id":873,"depth":485,"text":6095},"2. Generic constraint — extends",{"id":1278,"depth":485,"text":1279},{"id":1414,"depth":485,"text":6098},"4. Conditional types — T extends U ? X : Y",{"id":1678,"depth":485,"text":6100},"5. infer — đặt biến type trong conditional",{"id":2096,"depth":485,"text":2097},{"id":2393,"depth":485,"text":2394},{"id":2760,"depth":485,"text":2761},{"id":3428,"depth":485,"text":6105},"9. Index access type — T[K]",{"id":3736,"depth":485,"text":3737},{"id":4181,"depth":485,"text":4182},{"id":4335,"depth":485,"text":4336,"children":6109},[6110,6111,6112],{"id":4340,"depth":499,"text":4341},{"id":4496,"depth":499,"text":4497},{"id":4629,"depth":499,"text":4630},{"id":4923,"depth":485,"text":4924,"children":6114},[6115,6116,6117,6118,6119,6120,6121],{"id":4938,"depth":499,"text":4939},{"id":5015,"depth":499,"text":5016},{"id":5062,"depth":499,"text":5063},{"id":5149,"depth":499,"text":5150},{"id":5218,"depth":499,"text":5219},{"id":5439,"depth":499,"text":5440},{"id":5544,"depth":499,"text":5545},{"id":5614,"depth":485,"text":5615,"children":6123},[6124,6125,6126,6127],{"id":5618,"depth":499,"text":5621},{"id":5730,"depth":499,"text":5731},{"id":5860,"depth":499,"text":5863},{"id":5930,"depth":499,"text":5931},"Generic + constraint, conditional types, mapped types, infer, template literal, decorator, utility types.","md",null,{},{"title":302,"icon":305},{"title":422,"description":6128},"1gIPBfGVpTiY9kcQBR-L2g8vFrnuH3ICQufM0sKVq1c",[6136,6138],{"title":298,"path":299,"stem":300,"description":6137,"icon":81,"children":-1},"Primitive, object, array, tuple, enum, union, intersection, literal, narrowing, type guard, any vs unknown vs never.",{"title":307,"path":308,"stem":309,"description":6139,"icon":196,"children":-1},"73+ câu hỏi TypeScript phổ biến cho dev frontend\u002Ffullstack — bao gồm TS 7.0 RC.",1783490357758]