🤯 “Wait… Why Is undefined Allowed Here?”
Meet Tchaaca - a junior developer working on a TypeScript codebase for the first time. While refactoring some legacy JavaScript into TypeScript, he proudly writes:
function greet(name?: string) { console.log(`Hello, ${name ?? "guest"}!`); } So far, so good.
But a few lines later, his senior dev does this:
greet(undefined); // no error Tchaaca frowns.
“Hold on... I thought
name?meant optional. Why can we passundefinedexplicitly? Shouldn’t TypeScript stop that?”
That’s when confusion kicks in - and it happens to most of us.
đź’ˇ What ? Really Means in TypeScript
When you write:
function greet(name?: string) It’s shorthand for:
function greet(name: string | undefined) So yes, undefined is allowed - both implicitly and explicitly.
?means: “This can be missing - or beundefined.”
That’s why both of these work:
greet(); // âś… OK - omitted greet(undefined); // âś… OK - explicit undefined đź§ So... What's the Problem?
For many teams, especially those transitioning from JS to TS, allowing explicit undefined can lead to:
- Confusion between omitting vs manually passing undefined
- Bugs when passing
undefinedto required functions or props - Inconsistent coding practices
đźš« Preventing Manual undefined with ESLint
If you want to avoid explicitly passing or assigning undefined, you can enforce that with ESLint.
📦 Install the necessary packages:
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev đź”§ .eslintrc.js setup:
module.exports = { parser: "@typescript-eslint/parser", plugins: ["@typescript-eslint"], extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ], rules: { "no-undefined": "error" // ⛔️ Prevent manual usage of undefined } }; ❌ Will throw ESLint error:
let name: string | undefined; name = undefined; // đź”´ ESLint: 'undefined' is not allowed âś… Still allows optional omission:
function greet(name?: string) { // Using undefined for checks is still fine if (name === undefined) { console.log("Guest"); } } 🛡️ Bonus: Use strictNullChecks in tsconfig.json
To avoid nullish bugs entirely, turn on:
{ "compilerOptions": { "strict": true, "strictNullChecks": true } } This ensures TypeScript treats undefined and null strictly and never assumes they’re just “nothing.”
đź§µ Final Thoughts
Tchaaca learned that name?: string is more powerful - and subtle - than it looks. It doesn’t reject undefined, it accepts it. Which is great when you're okay with that... but confusing when you're not.
If you want to avoid accidentally introducing undefined manually, the fix isn’t in TypeScript - it’s in your lint rules.
So next time you're puzzled by what ? means, remember:
"Optional" means "maybe undefined" - and yes, even on purpose.
Top comments (1)
Tips and more tips forU guys