-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Suggestion: Void-protected types #6981
Comments
Hey @dallonf, thanks for taking the mantle on this and bringing it back. I'm not sure what the TypeScript teams wants to do with this, but since the last discussion about it took place, there has been a lot learned and changed in the language itself. I think this is the right way forward, but there is a lot of trickiness surrounding I'm going to repeat a lot of what you just said, but splitting it up into what I see as the logical separations just to get the full picture and why this particular issue is important and related to it. It's important to note that only the first issue below is encompassed by this proposal. I'm only rehashing the rest of the steps here so that they can be further broken out into new proposals in the future, or discussed here as appropriate. First Problem - built-in
|
@tejacques nit:
Unfortunately |
@yortus: well, technically it could, right? If |
As I understood it, |
@yortus: You're correct about the guard. If it was going to be special cased, it should probably only be on explicit object and array types. I'll update my post to reflect this, but special casing at all might be the wrong thing to do (wouldn't work in generics, and makes the developer need to be aware of context). I only put it in because it's pretty idiomatic JavaScript, and it might clash if TypeScript can't handle that case. |
closing this in favor of #7140 |
Deep in the discussion of non-nullable types, there was a new, more practical, suggestion (credit particularly to @tejacques) of voidable types that are protected against unsafe access, while maintaining backwards compatibility. I think the suggestion is a bit too buried in that thread to be useful or noticed, so I'm creating a new issue for this proposal.
First, some definitions to make sure I'm on the same page as everyone else... for the purposes of this discussion, "void" refers to either a value of
null
orundefined
, which will raise aTypeError
if you attempt to use it in certain ways, particularly accessing a member (e.g.foo.bar
) or calling it as a function (e.g.foo()
). Currently in TypeScript, all types are "voidable", by this definition.The proposal is for a new modifier (I'll use a
?
prefix, similar to Flow's implementation, but it could be anything) that will make a type "void-protected". A void-protected type must be checked for existence before it can be used. For example:This does not affect assignments, for the sake of backwards compatibility:
This is similar in philosophy to Java's
Optional<>
type. While every type in Java is nullable, it has become standard to instead useOptional<>
to express this at an API level. While it doesn't completely protect againstNullPointerException
s (aka the "billion dollar mistake"), it's a step in the right direction, and some IDEs will even log warnings if you assignnull
to a normal, non-Optional
type.In the case of TypeScript, a
--noImplicitVoidable
flag could be added in the distant future, which would make all types non-voidable (that is, you could not assignnull
orundefined
to them) by default. While this is a major breaking change, it can be mitigated by having "void-protected" types in the language for some time prior. That way, most code will already be using?
prefixes wherever void types are expected.Finally, under this proposal, there are basically four levels of voidability, which is more relevant if this hypothetical
--noImplicitVoidable
flag comes to be. A lot of this has been adapted from @tejacques's response in thenon-nullable
thread:w: string
behaves exactly like it does currently: it must be explicitly set, but it can be void. Under--noImplicitVoidable
, it would be a strong guarantee of existence.x: ?string
is new: it must be explicitly set, but can be void. As is, it behaves exactly likew
, but provides more safety for a consumer.y?: string
continues to behave as-is. Under--noImplicitVoidable
, though, it would probably be treated as "undefinable" - that is, it may have a value ofundefined
(implicitly, if it's not set) and accessing it must be guarded, but it would never have a value ofnull
.z?: ?string
is equivalent toy
, but again provides more safety for consumers and would be preferred overy
in most new code.The text was updated successfully, but these errors were encountered: