Skip to content
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

Why is type assignability for any and enum so permissive? #22464

Closed
bcherny opened this issue Mar 10, 2018 · 2 comments
Closed

Why is type assignability for any and enum so permissive? #22464

bcherny opened this issue Mar 10, 2018 · 2 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@bcherny
Copy link

bcherny commented Mar 10, 2018

Keywords: any, null, undefined, enum, assign, assignable, assignability, permissive, strict

From the spec:

S is assignable to a type T, and T is assignable from S, if S has no excess properties with respect to T (3.11.5) and one of the following is true:

  • S and T are identical types.
  • S or T is the Any type.
  • S is the Undefined type.
  • S is the Null type and T is not the Undefined type.
  • S or T is an enum type and the other is the primitive type Number.

Why is:

  • S assignable to T, if S is any and T is not any?
  • S assignable to T, if S is a number and T is an enum? Because enum <: number, T should be assignable to S, but why is the reverse true? And why is this not the case for string enums?
  • S assignable to T, if S is undefined? (this was a Playground bug where strictNullChecks wasn't actually applied)
  • S assignable to T, if S is null and T is not undefined?

Have you guys considered a flag to opt out of some or all of these behaviors? Or are there real uses cases for them besides interop with untyped JS (or TS in non-strict mode)? I read through the spec and searched issues, but had trouble finding a discussion of why TS made these design decisions.

@bcherny bcherny changed the title Why is type assignability with null/undefined so permissive? Why is type assignability for any and enum so permissive? Mar 10, 2018
@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Mar 11, 2018
@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Mar 11, 2018

S assignable to T, if S is any and T is not any?

We think const v: T = <any>(expr); should not be an error regardless of T or the type of expr. There is always a more-safe type assertion available; someone changing an expression's type to any should be a 100% Get-out-of-jail-free card.

"But not all anys come from casts!" you say... Right. noImplicitAny is designed to prevent any from appearing in places where you (or someone else) didn't say something was any via explicitly writing that spelling of the type in some place or another.

There's still the issue of any appearing in lib.d.ts definitions. I think there's a market for a stricter lib.d.ts that puts unknown in place of all anys, but intrinsically changing the definition of any to something else isn't something we think is a productive route.

S assignable to T, if S is a number and T is an enum?

Because there's a bit of a paradox presented by the bitwise operators. See #17734, #21546, #11559, #15591 and other issues on this; it's been brought up a few times.

Have you guys considered a flag

Most weeks we review about a dozen suggestions for new flags, and we've been doing that for about five years now, so... yes 😉

@bcherny
Copy link
Author

bcherny commented Mar 11, 2018

This makes complete sense. Thanks for the quick and detailed response :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

2 participants