Skip to content

A type can be named undefined #57573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dragomirtitian opened this issue Feb 28, 2024 · 11 comments Β· Fixed by #57575
Closed

A type can be named undefined #57573

dragomirtitian opened this issue Feb 28, 2024 · 11 comments Β· Fixed by #57575
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@dragomirtitian
Copy link
Contributor

πŸ”Ž Search Terms

type named undefined

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ

⏯ Playground Link

Playground Link

πŸ’» Code

namespace ns {
    export type undefined = "";
    export function x(p: undefined): undefined { // global undefined
        
    }
}

function x(p: ns.undefined) { // undefined from the namespace

}

πŸ™ Actual behavior

Inside the namespace undefined is the global undefined type. We can access the type if we qualify it with the namespace

πŸ™‚ Expected behavior

undefined should not be allowed as a type name. (null is not)

Additional information about the issue

No response

@fatcerberus
Copy link

fatcerberus commented Feb 28, 2024

undefined should not be allowed as a type name. (null is not)

Amusingly, this matches runtime behavior: null is a keyword, while undefined is not--it's a global variable that can be freely shadowed, and prior to ES5 you could actually mutate the global one (which is why void 0 became popular).

@dragomirtitian
Copy link
Contributor Author

dragomirtitian commented Feb 28, 2024

@fatcerberus It does partially match that. Except in ES5 if you defined undefined it would use that in the context. This allows you to define it but then ignores it.

We could allow it. But it'd rather ban it πŸ˜…

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Experience Enhancement Noncontroversial enhancements labels Feb 28, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Feb 28, 2024
@RyanCavanaugh
Copy link
Member

I can't imagine anyone doing this on purpose except to be evil... banning seems like the right call

@jakebailey
Copy link
Member

On second look, what is the problem here per se? Whenever you write undefined in type space, you always get the real undefined, even inside the namespace. It never emits "wrong", because that undefined (even when inferred) always points to the global undefined.

If you do this outside of a namespace, it will say no, but inside it's just a symbol that can only be accessed from the namespace, no other way, so this doesn't seem harmful, just... weird?

@jakebailey
Copy link
Member

Hm, no, it won't say no outside of a namespace. Just error when it's also a global. https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBDAnmYcCuA7AJsAZgSw2CzgF44AiCgbgFgAoIA

@dragomirtitian
Copy link
Contributor Author

On second look, what is the problem here per se? Whenever you write undefined in type space, you always get the real undefined, even inside the namespace. It never emits "wrong", because that undefined (even when inferred) always points to the global undefined.

If you do this outside of a namespace, it will say no, but inside it's just a symbol that can only be accessed from the namespace, no other way, so this doesn't seem harmful, just... weird?

But it feels very strange that you have a local type named undefined, which regular scoping rules would dictate would take precedence over the global undefined and yet it does not.

Erroring on undefined would also make it similar to what happens for other keyword types such as number Playground Link

@jakebailey
Copy link
Member

Ah, there's the error I was looking for. Thanks.

@RyanCavanaugh
Copy link
Member

export type undefined = "";
let m: undefined = "";
// error^

If it's not going to work, we shouldn't let you do it

@reverofevil
Copy link

reverofevil commented Jul 6, 2024

Related #43215

Did anyone check this time there are no other such identifiers? Is there anything like identifier contingency plan, such as refactoring the parser to support precisely defined thought-through identifier classes?

I suspect this might either not be fixed, or will break again soon.

@jakebailey
Copy link
Member

jakebailey commented Jul 6, 2024

Did anyone check this time there are no other such identifiers?

Yes: #57575 (comment)

@jakebailey
Copy link
Member

Is there anything like identifier contingency plan, such as refactoring the parser to support precisely defined thought-through identifier classes?

I suspect this might either not be fixed, or will break again soon.

undefined is the special case as it's not actually a keyword, but a predeclared identifier in JS but a keyword in type space, which is why this wasn't caught.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants