<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Diana Agliamutdinova</title>
    <description>The latest articles on DEV Community by Diana Agliamutdinova (@diana_agliamutdinova_741a).</description>
    <link>https://dev.to/diana_agliamutdinova_741a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2102853%2F6d7af4b9-d282-4bfc-a391-1a79d73c2e8b.png</url>
      <title>DEV Community: Diana Agliamutdinova</title>
      <link>https://dev.to/diana_agliamutdinova_741a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diana_agliamutdinova_741a"/>
    <language>en</language>
    <item>
      <title>🏡 The Smart Home and the Tireless Assistant: Understanding JavaScript in the Browser</title>
      <dc:creator>Diana Agliamutdinova</dc:creator>
      <pubDate>Tue, 12 Aug 2025 15:58:05 +0000</pubDate>
      <link>https://dev.to/diana_agliamutdinova_741a/the-smart-home-and-the-tireless-assistant-understanding-javascript-in-the-browser-19c8</link>
      <guid>https://dev.to/diana_agliamutdinova_741a/the-smart-home-and-the-tireless-assistant-understanding-javascript-in-the-browser-19c8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I’ve always remembered stories better than facts. So I started wondering — what kind of story could best explain how JavaScript works in the browser? Here’s what I came up with.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine a story about a very busy programmer and his smart home which is managed by his efficient but not very smart assistant who does not multitask.&lt;/p&gt;

&lt;p&gt;🧑💻 &lt;strong&gt;The Programmer&lt;/strong&gt; — You, the one writing instructions.&lt;/p&gt;

&lt;p&gt;🤖 &lt;strong&gt;The Assistant&lt;/strong&gt; (V8 Engine) — Executes your instructions one by one.&lt;/p&gt;

&lt;p&gt;🏠 *&lt;em&gt;The Smart Home *&lt;/em&gt;(Browser) — Full of gadgets (APIs) like timers, smart lights, smart TV, and messaging systems.&lt;/p&gt;

&lt;p&gt;💻 &lt;strong&gt;Home Management Devices&lt;/strong&gt; (Browser APIs) — An application that helps an assistant access your smart home features.&lt;/p&gt;

&lt;p&gt;📬 &lt;strong&gt;Input box queue&lt;/strong&gt;(The Event Loop) — Messages left by smart home&lt;/p&gt;

&lt;p&gt;!!📬 &lt;strong&gt;High Priority input&lt;/strong&gt;( Microtasks) — High-Priority messages from smart home &lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript’s One-Task-at-a-Time Flow
&lt;/h2&gt;

&lt;p&gt;The assistant starts her day by executing her employer’s instructions &lt;strong&gt;one by one, from top to bottom&lt;/strong&gt; of the list. To save time and avoid being blocked by long tasks, she delegates anything time-consuming to the smart home using home management devices. Since &lt;strong&gt;she can only focus on one thing at a time&lt;/strong&gt;, she wants to stay available — just in case something urgent comes up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do you think she manages more complex tasks that needs her supervision? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;⏲️ &lt;strong&gt;setTimeout&lt;/strong&gt;: Boiling an Egg&lt;br&gt;
One task says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Boil an egg for 6 minutes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of waiting next to the pot, she sets a timer using the kitchen device💻 and moves on.&lt;/p&gt;

&lt;p&gt;When 6 minutes pass, the smart home puts a note into her inbox📬:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Time’s up! Remove the egg!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But she’ll only act on that message once she finishes her current task — this is how the event loop works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;putEggsOnStove()

setTimeout(() =&amp;gt; { 
  takeTheEggsOff(); 
}, 6000); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💌 Promises and Microtasks: Dinner with a friend
&lt;/h2&gt;

&lt;p&gt;Another task:&lt;/p&gt;

&lt;p&gt;“Invite a friend to dinner.”&lt;/p&gt;

&lt;p&gt;She texts a message to his friend to ask about dinner and what time she’s available and moves on. His friend is a very busy woman and wouldn't answer right away. At the same time she cannot just wait for a message all day long, so &lt;strong&gt;she delegates the task of waiting to a reminder&lt;/strong&gt;, that will send a message to her high priority inbox !!📬, so she wouldn't miss it and would be able to finish this task.&lt;/p&gt;

&lt;p&gt;The assistant checks her high priority inbox right after her current task, before any other reminders from her regular inbox.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bookTableDinnerTime = async () ⇒ {
  const response = await askFriend();
  if(response.yes) {
    bookTable(response.time)
  } 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 Wrapping It Up
&lt;/h2&gt;

&lt;p&gt;JavaScript in the browser is a lot like our assistant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ One task at a time (single-threaded)&lt;/li&gt;
&lt;li&gt;✅ Uses built-in smart devices (Web APIs) for long tasks&lt;/li&gt;
&lt;li&gt;✅ Gets notified when tasks are done (via callback queues)&lt;/li&gt;
&lt;li&gt;✅ Prioritises some messages over others (microtasks vs callbacks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💬 What About You?&lt;br&gt;
Have you ever used a metaphor to understand programming better?&lt;/p&gt;

&lt;p&gt;Let me know in the comments — or share your favourite one! And if this helped, feel free to follow me for more dev insights 👇&lt;/p&gt;

&lt;h1&gt;
  
  
  JavaScript #Frontend #WebDevelopment #AsyncAwait #EventLoop #BrowserAPIs #ProgrammingStorytelling
&lt;/h1&gt;

&lt;h2&gt;
  
  
  📝 Key Links:
&lt;/h2&gt;

&lt;p&gt;The original article I posted on my LinkedIn &lt;a href="https://www.linkedin.com/pulse/learn-react-basics-without-confusion-diana-agliamutdinova-vvmaf/?trackingId=PnxVujiApzKfIKWFu1VG6A%3D%3D" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Web APIs – &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Event Loop – &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;setTimeout – &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>eventloop</category>
      <category>programming</category>
    </item>
    <item>
      <title>🛠️ I never use 'never' or taming the Unknown in TypeScript.</title>
      <dc:creator>Diana Agliamutdinova</dc:creator>
      <pubDate>Mon, 11 Aug 2025 11:54:04 +0000</pubDate>
      <link>https://dev.to/diana_agliamutdinova_741a/i-never-use-never-or-taming-the-unknown-in-typescript-53o9</link>
      <guid>https://dev.to/diana_agliamutdinova_741a/i-never-use-never-or-taming-the-unknown-in-typescript-53o9</guid>
      <description>&lt;h2&gt;
  
  
  🚧 The Real-World Problem: Runtime Exceptions
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Cannot read property ‘x’ of undefined."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Almost every JavaScript developer has seen this error — often at the worst possible time. That’s because JavaScript is flexible at compile time but unforgiving at runtime.&lt;/p&gt;

&lt;p&gt;TypeScript introduces a compile-time safety net. But in the real world, especially when working with unpredictable APIs, we still encounter data that’s uncertain or incomplete.&lt;/p&gt;

&lt;p&gt;This article explores how to use TypeScript's compiler tools and runtime strategies to safely handle unknown or unexpected data — so your code doesn’t just compile, but also survives in production.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  🚩 The First Instinct: Use any
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFromAPI&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ⚡ might throw!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;'any'&lt;/strong&gt; removes all type checks — you can access any method or property later, and TS won’t stop you. &lt;em&gt;Your code compiles, but it might explode at runtime.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is very attractive to use any especially when compiler errors are everywhere and you want to see at least some of your code work. But you still want to explore benefits of TS making you code more stable and safe. Lets explore alternatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 Prefer unknown over any
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use 'unknown' when you don’t know the type yet. It forces you to narrow before using it. 'any' skips all checks, 'unknown' makes you prove it’s safe.&lt;/p&gt;

&lt;p&gt;So in case you do not know the exact type of data. &lt;strong&gt;'unknown' doesn’t allow you use its methods or properties unless you checked they exist.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Let the Compiler Help You
&lt;/h2&gt;

&lt;p&gt;TypeScript’s greatest strength is &lt;strong&gt;static type checking&lt;/strong&gt; — it checks your code before it runs. You tell it what types values should have, and it ensures everything matches.&lt;/p&gt;

&lt;p&gt;TypeScript’s static type checking shines when you give it strong, precise definitions. Here are some common ways to express different data structures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primitive types&lt;/strong&gt; like string, number, and boolean — e.g., a user's name, age, or account status&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Union types&lt;/strong&gt; like Success | Error — for values that can be in one of several valid shapes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record types&lt;/strong&gt; like Record — for mapping keys (like user IDs) to values (like scores)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuple types&lt;/strong&gt; like [number, number] — for fixed-length pairs, such as coordinates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Array types&lt;/strong&gt; like string[] or Array — for lists of items&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Object types&lt;/strong&gt; like { id: number; name: string } — to define expected shapes directly&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;Interfaces *&lt;/em&gt;— useful for object-oriented patterns and reusable data structures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Literal types&lt;/strong&gt; like type Role = 'admin' | 'user' — to restrict a value to a specific set of strings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these tools, you clearly communicate your expectations, and TypeScript helps enforce them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Superpower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invisibility&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strength&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Hero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IronMan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WonderWoman&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;powers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Superpower&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;IronMan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;WonderWoman&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strength&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Flash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invisibility&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Inform the compiler how to interpret your data('satisfies' and 'as')
&lt;/h2&gt;

&lt;p&gt;Union types are great for representing values that could take on different forms. But what if you know a value is a specific type — say, a WonderWoman — and want to treat it that way? TypeScript won’t let you access properties unless they exist on every possible type in the union.&lt;/p&gt;

&lt;p&gt;That’s where 'as' comes in. You can use a type assertion to tell TypeScript, “Trust me, this is a WonderWoman”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getHero&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// hero: Ironman | WonderWoman&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;WonderWoman&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lasso&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 👈 This bypasses safety checks &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextHeroNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hero&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Error — TypeScript &lt;/span&gt;
&lt;span class="c1"&gt;// won’t allow casting between unrelated types like union of objects // to number.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 'as' keyword in TypeScript is a type assertion, not a type conversion. It tells the compiler, "Trust me, I know what I'm doing" — but it doesn't actually change the value at runtime.&lt;/p&gt;

&lt;p&gt;_&amp;gt; For example, writing "123" as number won't turn a string into a number — TypeScript will still flag this as an error because the types are fundamentally incompatible. So while as overrides some checks, it still respects basic type safety and won't let you assert totally unrelated types.&lt;br&gt;
_&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The satisfies operator is newer and safer. It lets you assert that a value matches a specific type — without changing its inferred shape.&lt;/p&gt;

&lt;p&gt;It checks that:&lt;/p&gt;

&lt;p&gt;The value matches the structure of the type&lt;br&gt;
But still preserves literal types (like 'production' instead of just string)&lt;/p&gt;
&lt;h2&gt;
  
  
  ❌ never: Exhaustive check and Exclude types
&lt;/h2&gt;

&lt;p&gt;The never type represents values that never occur. It’s used to indicate that something is impossible or unreachable in your code.&lt;/p&gt;

&lt;p&gt;When you use a switch or conditional statements with union types, TypeScript can enforce that all possible cases are handled by assigning the never type to the “default” case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_exhaustiveCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌ if a case is missing, TS complains&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, if you forget to handle a new shape (like 'triangle'), TypeScript complains because the default case expects never — meaning it should never happen.&lt;/p&gt;

&lt;p&gt;You can use never in conditional types to filter out types from unions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nb"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Clean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;triangle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'square' | 'triangle'&lt;/span&gt;

&lt;span class="c1"&gt;// Example with literal:&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;OnlyShapes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;OnlyShapes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'color'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means: For each type T, if it extends U (the type to exclude), replace it with never (remove it), otherwise keep it.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ How to handle null and undefined?
&lt;/h2&gt;

&lt;p&gt;Sometimes we need to define values that could be set to 'null' or undefined, like optional variables that were not used. Lets see what TS has for us, obviously it wouldnt allow to use these values as normal.&lt;/p&gt;

&lt;p&gt;The obvious solution is to check! Then you can use the variable as you wish.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// true for both null and undefined&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional chaining &lt;strong&gt;(?.)&lt;/strong&gt; is a concise syntax that allows you to &lt;strong&gt;safely access nested properties or methods on objects that might be null or undefined&lt;/strong&gt;. Instead of causing a runtime error, it short-circuits and returns undefined if any part of the chain is missing, making your code more robust and easier to read.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;user?.profile?.name;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, the non-null assertion operator (!) tells TypeScript that &lt;strong&gt;you are certain a value is neither null nor undefined&lt;/strong&gt; at that point, effectively overriding strict null checks.&lt;/p&gt;

&lt;p&gt;While this can reduce unnecessary checks, it should be used cautiously, as incorrect assumptions may lead to runtime errors. Together, these operators help manage uncertain data while balancing safety and developer convenience.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;user!.login(); // use only if you're 100% sure&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎬 Runtime Type Checks
&lt;/h2&gt;

&lt;p&gt;In real-world projects, values often differ from our expectations—particularly when sourced from APIs or user input. &lt;strong&gt;TypeScript performs static analysis during compilation, but it cannot guarantee that runtime data conforms to the defined types.&lt;/strong&gt; Therefore, some type validations can only be performed at runtime. This is where type guards become essential.&lt;/p&gt;

&lt;p&gt;You need runtime checks to confirm the shape and type of your data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;typeof for primitives&lt;/li&gt;
&lt;li&gt;Array.isArray() for arrays&lt;/li&gt;
&lt;li&gt;instanceof for class instance&lt;/li&gt;
&lt;li&gt;Custom guards using is (type predicates)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They help narrow down from 'unknown' or any to something safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 'typeof' operator
&lt;/h2&gt;

&lt;p&gt;Use 'typeof' when you want to narrow primitive types safely before doing anything risky with the value — especially if it's coming from an unknown or dynamic source.&lt;br&gt;
It returns a string that tells you the general category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For strings like "hello", it returns '&lt;strong&gt;string&lt;/strong&gt;'&lt;/li&gt;
&lt;li&gt;For numbers like 42, it returns '&lt;strong&gt;number'&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;For booleans like true, it returns '&lt;strong&gt;boolean&lt;/strong&gt;'&lt;/li&gt;
&lt;li&gt;For functions, it returns '&lt;strong&gt;function&lt;/strong&gt;'&lt;/li&gt;
&lt;li&gt;For arrays, objects, or even null, it returns '&lt;strong&gt;object&lt;/strong&gt;'&lt;/li&gt;
&lt;li&gt;For variables not assigned a value yet, it returns '&lt;strong&gt;undefined&lt;/strong&gt;'&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&amp;gt; But be careful: typeof null is also 'object', which is a long-standing JavaScript quirk. So, always combine it with a null check like this:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="c1"&gt;// ✅ Safe: It's a real object, not null &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛡️ Custom Guards with 'is' (Bridge between TS and JS)
&lt;/h2&gt;

&lt;p&gt;If this returns true, treat this value as this type.&lt;br&gt;
Сustom type guards are &lt;strong&gt;functions you write to perform runtime checks in JavaScript, but with a special TypeScript syntax&lt;/strong&gt; (value is Type)&lt;/p&gt;

&lt;p&gt;This connects JavaScript’s dynamic checks with TypeScript’s static system by:&lt;/p&gt;

&lt;p&gt;Letting you verify data shapes or types at runtime (the JavaScript part)&lt;br&gt;
Informing TypeScript about the narrowed type after the check (the static typing part)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the function does real JavaScript checks, and TypeScript uses its special return type to know that inside an &lt;code&gt;if (isUser(value))&lt;/code&gt; block, value is safely a User.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Use 'in' to Narrow Union Types
&lt;/h2&gt;

&lt;p&gt;The main use of 'in' in TypeScript is as a type guard. It answers:&lt;/p&gt;

&lt;p&gt;“Does this object have this property?”&lt;br&gt;
If yes, TypeScript narrows the type accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;bark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bark&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ At runtime: 'key' in obj checks whether the property actually exists on the object — this is real JavaScript behavior.&lt;/p&gt;

&lt;p&gt;✅ At compile time: TypeScript sees 'key' in obj and narrows the union type — helping you write safer code by knowing exactly which variant of a type you're dealing with.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Bonus: Validate with Zod or io-ts (Next Article Teaser)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ✅ safe&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zod lets you define and enforce runtime validation schemas — a powerful complement to TypeScript’s static checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Final Advice: Combine Compiler and Runtime Checks
&lt;/h2&gt;

&lt;p&gt;Let TypeScript infer and check statically&lt;br&gt;
Use guards to validate dynamically&lt;br&gt;
Don’t trust outside data blindly&lt;/p&gt;

&lt;p&gt;The type system is here to help — lean on it early, refine later.&lt;br&gt;
Originally I posted this rticle on my Linkedin &lt;a href="https://www.linkedin.com/pulse/i-never-use-taming-unknown-typescript-diana-agliamutdinova-muy4f" rel="noopener noreferrer"&gt;link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 Your First Telegram Mini App: Fast Deployment with Next.js, Vercel and Telegram SDK</title>
      <dc:creator>Diana Agliamutdinova</dc:creator>
      <pubDate>Mon, 11 Aug 2025 10:45:35 +0000</pubDate>
      <link>https://dev.to/diana_agliamutdinova_741a/your-first-telegram-mini-app-fast-deployment-with-nextjs-vercel-and-telegram-sdk-4063</link>
      <guid>https://dev.to/diana_agliamutdinova_741a/your-first-telegram-mini-app-fast-deployment-with-nextjs-vercel-and-telegram-sdk-4063</guid>
      <description>&lt;p&gt;In this guide, I’ll show you how to build a &lt;strong&gt;Telegram Mini App&lt;/strong&gt; for your bot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚙️ &lt;strong&gt;Create a Next.js project&lt;/strong&gt; (BFF — backend for frontend)&lt;/li&gt;
&lt;li&gt;☁️ &lt;strong&gt;Deploy your app on Vercel&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🤖 &lt;strong&gt;Register your Mini App with BotFather&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔐 &lt;strong&gt;Authorize users through Telegram’s Web App initData&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;Enable core features&lt;/strong&gt;: Message sharing, Styling tips, Back button initialization&lt;/li&gt;
&lt;li&gt;💡 &lt;strong&gt;Use Telegram Popups&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of this guide, you’ll have a working Mini App inside the Telegram environment that is production-ready on Vercel.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 1. Project set up
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0to0e8djdw4vx8ocli2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0to0e8djdw4vx8ocli2h.png" alt="Project schema" width="800" height="770"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠 What You’ll Need
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a bot with &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;&lt;/strong&gt; and get your &lt;code&gt;BOT_TOKEN&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24duubp1fj6fozz8o4tw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24duubp1fj6fozz8o4tw.png" alt="Bot token in the telegram bots page in @BotFather interface" width="708" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create your Next.js app&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open your terminal and run the following command. Follow the interactive setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🏗️ Using Next.js as a &lt;strong&gt;BFF (Backend-for-Frontend)&lt;/strong&gt; with App Router&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvdp73f81dxtkz3v8c6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvdp73f81dxtkz3v8c6s.png" alt="How files and directories located in Next.js project" width="800" height="874"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Push your project to GitHub&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Go to &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, create a new repository, and follow the &lt;strong&gt;Quick setup&lt;/strong&gt; instructions to push your local project to the repo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Deploy your app to Vercel&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Telegram doesn’t host your website — your Mini App must be hosted somewhere publicly accessible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an account on Vercel&lt;/li&gt;
&lt;li&gt;Link your GitHub account&lt;/li&gt;
&lt;li&gt;Select your newly created repository&lt;/li&gt;
&lt;li&gt;Follow the prompts to deploy your project&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 By this point, your app should be live and hosted on the web — ready to be linked with your Telegram bot. Also your app will be redeployed on every commit to the remote repository.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🪄 2. Set Up a Mini App
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;✅ Method 1: Using &lt;code&gt;/newapp&lt;/code&gt; Command&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send &lt;code&gt;/newapp&lt;/code&gt; to BotFather&lt;/li&gt;
&lt;li&gt;Choose your bot (e.g., &lt;code&gt;@YourAppBot&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;title&lt;/strong&gt; and &lt;strong&gt;description&lt;/strong&gt; for your Web App&lt;/li&gt;
&lt;li&gt;Provide the &lt;strong&gt;URL&lt;/strong&gt; of your hosted Mini App (e.g., your Vercel app URL)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;⚙️ Method 2: Via BotFather’s Web Interface (Mini App Panel)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open BotFather’s &lt;strong&gt;Mini App panel&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;My Bots&lt;/strong&gt; and select the bot you want to update&lt;/li&gt;
&lt;li&gt;Navigate to: &lt;code&gt;Settings → Mini Apps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Main App&lt;/strong&gt;, enable it, and paste in your Mini App’s URL&lt;/li&gt;
&lt;li&gt;Optionally, create a &lt;strong&gt;Direct Link&lt;/strong&gt; — this is a link that directly opens your Mini App from Telegram( e.g., t.me//your_bot_name/…)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Once set, the&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;“Open” button&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;on the right should launch your Mini App inside Telegram. 🎉&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7op7d72u5lux1rjukizo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7op7d72u5lux1rjukizo.png" alt="Link" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🔐 3. Authorize a user with the Telegram Mini App SDK
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Frontend: Get initData from SDK and send it to your backend with API requests.&lt;/li&gt;
&lt;li&gt;Backend: Validate initData using your bot token.&lt;/li&gt;
&lt;li&gt;If valid: The user is authorized! You can trust the user info in initData.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Install the SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @telegram-apps/sdk-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Telegram injects the &lt;code&gt;Telegram&lt;/code&gt; object &lt;strong&gt;only in the browser&lt;/strong&gt;, you must use the SDK inside a &lt;strong&gt;client-only component&lt;/strong&gt; — otherwise, you’ll run into SSR issues.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;next/dynamic&lt;/code&gt; to import your Telegram logic with SSR disabled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const TelegramInit = dynamic(() =&amp;gt; import('../telegram/client/TelegramInit'), {
  ssr: false,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save rawInitData to use it for autorization. Send it to your backend to autorize api requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useRawInitData } from '@telegram-apps/sdk-react';

export default function TelegramInit() {
  const rawInitData = useRawInitData();
  useEffect(() =&amp;gt; {
    if (rawInitdata) {
      localStorage.setItem('token', rawInitdata);
    }
  }, [rawInitdata]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const res = await fetch(url, {
  method: method,
  headers: {
  'Content-Type': 'application/json',
  Authorization: `Bearer ${localStorage.getItem('token')}`,
  },
  body: body ? JSON.stringify(body) : undefined,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also you can get usefull user information from telegram(first_name, last_name, is_bot, photo_url, …)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { parse } from '@telegram-apps/init-data-node/web';
const initData = localStorage.getItem('token');
    if (initData) {
      try {
        const parsedData = parse(initData);
        if (parsedData.user) {
          createUserInDB(parsedData.user);
          setUser(parsedData.user);
        }
      } catch (error) {
        console.error('Failed to parse user data:', error);
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate initdata on the server using the Telegram Mini Apps SDK:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;token&lt;/strong&gt; is initdata you get from request headers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BOT_TOKEN&lt;/strong&gt; is your bot token from BotFather:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { isValid } from '@telegram-apps/init-data-node/web';
...
const isAuthorized = isValid(token, process.env.BOT_TOKEN!);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If valid, you can safely use the user info for DB operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Don’t Forget: Set Your &lt;code&gt;BOT_TOKEN&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To securely use your bot’s token in both development and production environments:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 1. Add it to your local environment
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env.local&lt;/code&gt; file in the root of your Next.js project and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BOT_TOKEN=your_telegram_bot_token_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This keeps your token out of version control and safe from exposure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ☁️ 2. Add it to Vercel Environment Variables
&lt;/h3&gt;

&lt;p&gt;To make sure your bot works in production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your project dashboard on &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Settings&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Environment Variables&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add a new variable:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;BOT_TOKEN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value:&lt;/strong&gt; your actual bot token&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;redeploy&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;your project after saving the variable so it’s available at runtime.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;📤 4. Sharing Messages from Mini App&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Frontend: User clicks “Share” → send data to /api/share&lt;/li&gt;
&lt;li&gt;Backend: Call &lt;strong&gt;savePreparedInlineMessage&lt;/strong&gt; → get message ID&lt;/li&gt;
&lt;li&gt;Frontend: Call &lt;strong&gt;shareMessage&lt;/strong&gt;({ id }) with the message ID&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { shareMessage } from '@telegram-apps/sdk-react';
// send info to the backend
const response = await shareTodo(todoId, userId, title, description);
if (response.ok) {
// get event id
  const data = await response.json();
  if (shareMessage.isAvailable()) {
// share message
    await shareMessage(data.id);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Backend:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On your backend, receive the data and call the Telegram Bot API’s &lt;strong&gt;savePreparedInlineMessage&lt;/strong&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const shareMessage = {
  user_id: userId,
  result: {
    type: 'photo',
    id: `todo-${todoId}`,
    photo_url: 'https://example.com/photo.jpg',
    thumbnail_url: 'https://example.com/thumb.jpg',
    title: `📝 ${todoTitle}`,
    description: todoDescription || 'A task from my Mini App',
    caption: `**${todoTitle}**\n\n${todoDescription || ''}`,
    parse_mode: 'Markdown',
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// send reuest to Telegram Bot API
const result = await savePreparedInlineMessage(shareMessage);
return NextResponse.json({ id: result.id });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📱 5. Telegram-Specific Features
&lt;/h3&gt;

&lt;p&gt;🔙 &lt;strong&gt;Back Button Behavior&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your Mini App has multiple pages or routing, you might want to enable back navigation. By default, the Telegram back button doesn’t behave like a browser back button — it needs to be explicitly initialized and controlled.&lt;/p&gt;

&lt;p&gt;On pages where you want the back button visible, you should show it; on others, hide it. Otherwise, pressing back will close the Mini App instead of navigating back.&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Closing Behavior&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to remind users to save their data before closing the app, you can enable a confirmation prompt on close. This helps prevent accidental loss of unsaved changes by asking the user for confirmation before exiting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎨 Mini App Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To customize your Mini App — like setting the header or background colors — or to use status methods like checking if the Mini App is active, you first need to initialize (mount) the Mini App component. Only after mounting can you safely call these methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client';

import { useEffect } from 'react';
import {
  backButton,
  closingBehavior,
  init,
  miniApp,
  useRawInitData,
} from '@telegram-apps/sdk-react';

export default function TelegramInit() {
  const rawInitdata = useRawInitData();

  useEffect(() =&amp;gt; {
    try {
      init(); // Initialize Telegram SDK
      if (backButton.mount.isAvailable()) {
        backButton.mount();
        backButton.onClick(() =&amp;gt; {
          if (backButton.isMounted()) {
            backButton.hide();
          }
          window.history.back();
        });
      }
      console.log('TelegramProvider - init()');
      if (miniApp.mountSync.isAvailable()) {
        miniApp.mountSync();
      }
      if (closingBehavior.mount.isAvailable()) {
        closingBehavior.mount();
        closingBehavior.isMounted(); // true
      }
      if (closingBehavior.enableConfirmation.isAvailable()) {
        closingBehavior.enableConfirmation();
        closingBehavior.isConfirmationEnabled(); // true
      }
    } catch (err) {
      console.error('Telegram SDK init failed:', err);
      const cleanUrl = window.location.origin + window.location.pathname;
      window.history.replaceState({}, '', cleanUrl);
    }

    return () =&amp;gt; {
      if (backButton.isMounted()) {
        backButton.unmount();
      }
    };
  }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  💬 6. Telegram Popups
&lt;/h3&gt;

&lt;p&gt;Basically you create a popup through popup.show with buttons you need.&lt;/p&gt;

&lt;p&gt;Then you wait for buttonId which popup.show returns(which button user clicked) and do accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { popup } from '@telegram-apps/sdk-react';

export const showTelegramPopup = async (
  title: string,
  message: string,
  buttonText: string[]
): Promise&amp;lt;boolean&amp;gt; =&amp;gt; {

  if (popup) {
    const promise = popup.show({
      title: title,
      message: message,
      buttons: buttonText.map((text, index) =&amp;gt; ({
        id: `button_${index}`,
        type: 'default',
        text: text,
      })),
    });
    // popup.isOpened() -&amp;gt; true
    const buttonId = await promise;
    if (buttonId === 'button_0') {
      return true;
      // do something
    } else if (buttonId === 'button_1') {
      return false;
      // do something else
    }
    // If buttonId is neither 'ok' nor 'cancel', return false by default
    return false;
  }
  // If popup is not available, return false
  return false;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🔗 Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Telegram Mini Apps SDK: &lt;code&gt;@telegram-apps/sdk-react&lt;/code&gt; and &lt;a href="https://docs.telegram-mini-apps.com/packages/telegram-apps-sdk-react/3-x" rel="noopener noreferrer"&gt;docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telegram Bot API: &lt;a href="https://api.telegram.org/" rel="noopener noreferrer"&gt;https://api.telegram.org&lt;/a&gt; and &lt;a href="https://core.telegram.org/bots/api" rel="noopener noreferrer"&gt;docs&lt;/a&gt; on how to use it.&lt;/li&gt;
&lt;li&gt;Check out final &lt;a href="http://t.me/mini_app_template_bot/miniapp" rel="noopener noreferrer"&gt;app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧠 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Telegram Mini Apps are a powerful way to create native-like experiences directly within Telegram. With the help of Vercel, you can go from idea to live app in no time.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔥 Teaser
&lt;/h3&gt;

&lt;p&gt;There’s more to explore — like &lt;strong&gt;handling payments with Telegram Stars&lt;/strong&gt; — but it didn’t quite fit in this article.&lt;/p&gt;

&lt;p&gt;If you’d like me to cover it next, please &lt;strong&gt;like this post&lt;/strong&gt; or &lt;strong&gt;drop a comment below&lt;/strong&gt; letting me know!&lt;/p&gt;

&lt;p&gt;Your feedback helps me prioritize what to write about next.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://medium.com/@diapant95/your-first-telegram-mini-app-fast-deployment-with-vercel-and-telegram-sdk-639f50402ade" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>telegramminiapps</category>
      <category>webdev</category>
      <category>vercel</category>
    </item>
  </channel>
</rss>
