Suggest an editImprove this articleRefine the answer for “unknown vs any”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`unknown`** is a safe alternative to `any`: it says "I don't know what this value is, so you must prove its type before using it," and it does not let you do anything with the value until the type has been narrowed. **Key point:** `unknown` stops being safe as soon as you bypass the check with a forced `as` cast - at that point it behaves like plain `any` again.Shown above the full answer for quick recall.Answer (EN)Image## 1. What `unknown` does > `unknown` is a **safe alternative** to `any`. > It says: "I don't know what this value is, **so you must prove its type before using it**." Example: ```javascript let value: unknown = "hello"; value.toUpperCase(); // Error: Object is of type 'unknown' if (typeof value === "string") { value.toUpperCase(); // OK, the type is proven } ``` Unlike `any`, TypeScript **does not let you do anything** until you narrow the type. That is what makes `unknown` *safe by default*. ## 2. Why `unknown` is safer than `any` | Behavior | `any` | `unknown` | |---|---|---| | Can call methods without checking | Yes | No | | Can be assigned to other types | Without restriction | Only after a check | | IDE suggests properties | No | No (until checked) | | Requires type narrowing | No | Yes | | Can cause runtime errors | Often | Only if you bypass the checks | Example: ```javascript let a: any = "hello"; let u: unknown = "hello"; a.foo(); // TS lets it through → fails at runtime u.foo(); // TS does not allow it → safe ``` ## 3. Why `unknown` can still be used **badly** Although `unknown` is safer, **it all depends on what you do with it**. If you **forcibly "break" the typing**, `unknown` stops being safe. ### Mistake 1: Forced casting with `as` ```javascript let data: unknown = "Hello"; const num = data as number; // forced cast console.log(num.toFixed(2)); // runtime error ``` The cast (`as number`) bypasses all of TS's checks. In other words, you are **back to the behavior** of `any`. **Takeaway:** `unknown` is safe as long as you do not force TS to "take your word for it." ### Mistake 2: Spreading `unknown` too widely If you return `unknown` from functions or store it in data structures, the type system loses context. Example: ```javascript function parseJSON(str: string): unknown { return JSON.parse(str); } const result = parseJSON('{"id":1,"name":"Alex"}'); // result: unknown console.log(result.name); // error, until you check it ``` This is *safe*, but **inconvenient**: you are forced to narrow types by hand everywhere. If there are many such values, this leads to **type chaos**. ### Mistake 3: Overly generic function types If everything in an API function is declared as `unknown`, you **lose the benefit of typing**: the IDE no longer knows what the function returns. ```javascript function getUser(): unknown { return { name: "Alex", age: 30 }; } const user = getUser(); user.name; // Error: TS does not know there is an object there ``` The code is safe but useless: TS protects you from errors but does not help you develop. ### Mistake 4: Assigning `unknown` without narrowing ```javascript let data: unknown = 42; let str: string = data; // Error: Type 'unknown' is not assignable to type 'string' ``` It is good that TypeScript **catches this**, but if you write `as string`, the logic still **breaks**: ```javascript let str = data as string; console.log(str.toUpperCase()); // runtime error ``` ## 4. How to use `unknown` correctly **Use** `unknown` **as a safety barrier**, at the boundaries with *external data* that you cannot trust (API, JSON, user input). Example: ```javascript function parse<T>(json: string): T { const data: unknown = JSON.parse(json); if (isUser(data)) { return data; // TS is now sure } throw new Error("Invalid user data"); } ``` Here: - `unknown` → a safe start - `isUser()` → a *type guard* - `T` → we return a typed value ## 5. When `unknown` is better than `any`, and when it is not | Situation | Better with `unknown` | Better with `any` | |---|---|---| | Receiving data from an API | Yes | No | | Quick debugging or temporary code | Possible, but clunky | Yes (temporarily) | | Writing generic functions | Yes (narrow the type later) | No | | Legacy code with no time for strict checks | Inconvenient | Temporarily acceptable | | Public libraries | Yes (external input is `unknown`) | No | ## 6. A correct example with checks ```javascript function isUser(value: unknown): value is { id: number; name: string } { return ( typeof value === "object" && value !== null && "id" in value && "name" in value ); } const data: unknown = JSON.parse('{"id":1,"name":"Alex"}'); if (isUser(data)) { console.log(data.name.toUpperCase()); // safe } else { console.error("Invalid user"); } ``` Here `unknown` does its job: it protects against the wrong type until you prove otherwise. ## 7. The fundamental difference in philosophy | | `any` | `unknown` | |---|---|---| | Philosophy | "I know what I'm doing" | "I don't know what this is yet" | | Safety | absent | maximum | | Use case | temporary solutions, legacy | external data, APIs, dynamic content | | Type checking | disabled | mandatory | | Breaks the type contract | easily | only through `as` | ## Summary | Question | Answer | |---|---| | Why is `unknown` safer? | It **forces** you to check the type before using it. | | Why can it be dangerous? | If you **bypass the checks** with `as` or use it too broadly, the point of typing is lost. | | Where is it appropriate? | At application boundaries: parsing JSON, user input, unpredictable APIs. | | The main idea | `unknown` is a "safe unknown." You cannot use the value until you prove it is the right type. | --- **Just remember:** > `any` - "I know better than TypeScript." > `unknown` - "TypeScript, help me make sure." > > But if you "trick" the compiler yourself (with `as`), > then `unknown` stops being safe and becomes plain `any` in disguise.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.