Closed
Description
Non-nullable types (#7140)
Question marks on types
Let's start the bike-shedding! What does T?
mean?
function foo(x?: string) {
// x: string | undefined
}
function foo(x: string?) {
// ?????
}
function foo(x?: string?) {
// x: string | undefined | ?????
}
- @ahejlsberg: It's hard to imagine a world where
T?
means onlyT | null
or onlyT | undefined
. - There is a school of thought that says "neither - this just doesn't need to exist".
- Just ship two type aliases for
T | null
andT | undefined
inlib.d.ts
- We can sort of see that. It's not crazy.
- We can't satisfy everyone - we're going to piss someone off.
- But if we ship this without a
?
type modifier, it's the first thing we're going to hear, and we're going to hear it for the rest of our lives.
- Just ship two type aliases for
- What's crazy about
T | null
?- You have an optional accessor that returns
number? | undefined
.- You end up with these awkward, funny-looking types.
- Lack of symmetry between optional members and nullish types.
- Becomes like the
const
modifier in C++. - Nobody understands where the heck to put
const
(before*
, after*
, at the end of a signature), and the differences are hard for people to grasp.- We understand it, but our users will get tripped up a lot.
- Becomes like the
- People will definitely be confused about which to do.
- Users on GitHub did not seem to be concerned with it - they understood very well.
- Confirmation bias - these are people who are interested in language design to begin with.
- Users on GitHub did not seem to be concerned with it - they understood very well.
- You have an optional accessor that returns
- Too many people are doing
null
to ignore that scenario.- Ultimately the question becomes is this disjoint or does it combine with the "other" use of
?
on optional parameters/properties.
- Ultimately the question becomes is this disjoint or does it combine with the "other" use of
- @RyanCavanaugh: Extremely against
T?
meaningT | null | undefined
because it muddies waters - So if we can't come to a conclusion, I think we should hold off on it. - We want to lead people to a pit of success, and we can't repeat the problem we have with modules.
- Only consistency in discussion on thread is that there is no consistency.
- We don't feel confident that we can do the "right" thing here out of the gate.
- If people go out and fix type definitions and inappropriately use
?
, then you've made the ecosystem worse - we need to wary of this possibility. - @Aleksey-Bykov you get a ⭐
- Consensus: come back to this, since this is not a blocker for non-nullable types anyway.
- Also, look into supplying type aliases in
lib.d.ts
.
- Also, look into supplying type aliases in
Optional members on new members
- Considering adding question marks on other members ([Request for feedback] Nullable types,
null
andundefined
#7426 (comment))- On local variable names (e.g.
let x?: number
). - On property declarations in classes (e.g.
class Foo { x?: number }
). - On call signatures (e.g.
function val(x?: string)?: number
). - On index signatures (e.g.
[x: string]?: Entity
).
- On local variable names (e.g.
- We said it wasn't necessary because classes always have
undefined
by default, but non-nullable types make the world quite different. - Variables are more of a questionable (pun intended) case - not entirely certain.
- It seems like this would actually give you a case to say that your variable can be
undefined
and reflects that in the type. - Can we use that to model the dual of this on
?
in types?- Let's not go down that rabbit-hole.
- It seems like this would actually give you a case to say that your variable can be
- Call signatures would have an awkward syntax.
- Consensus: do it for properties, keep the rest this in mind, but come back to it.
Control-flow based type checking
- We're going to need to do it.
- We think we can do it with no significant perf hit.
- Get perfect definite assignment errors.
- Type guards should work perfectly.
- We'll keep people posted.
UMD module support (#7264)
- Idea with UMD modules is you write a declaration file.
- In that same file, you write
export as namespace Foo
whereFoo
is some arbitrary identifier. - In a module, only if you use a
/// <reference path="..." />
, isFoo
visible. - In a script context,
Foo
is always visible if the.d.ts
is in the compilation context.- Idea is that you're in a script/"non-module" context.
- This is the new, better, way to write type definitions that need to be shared between old script-style code and modules.
- The problem is that you always needed to duplicate your definitions across two different definition files, one which used an
export =
.
- The problem is that you always needed to duplicate your definitions across two different definition files, one which used an
- Problem: how do you reflect the type of the module itself?
-
Sometimes modules have members that refer to themselves.
-
We're still flexible here!
-
Continue using some value, use
export =
, and then use anexport namespace as Foo
.interface jQueryStatic { foo: jQueryStatic } let jQuery: jQueryStatic; export = jQuery; export as namespace jQuery;
-
-
Why does
/// <reference path="..." />
affect things? Why not just use a global module augmentation?
Library include directives (#7263)
- Answer to the question of "How do we easily resolve types for script/global code?"
- Need to avoid situations where users have duplicate definitions due to "global code" being treated as conflicting even though they might refer to the same entities.
- Syntax:
/// <reference library="jquery" />
- What is the order of resolution for declaration files?
- Take
/// <reference library="jquery" />
. - Start from current module location.
- Look for files walking up the spine of directories. For each directory:
- If you see a file named
jquery.d.ts
, use that. - If you see a directory named
typings
, look in there. - If you see a directory named
node_modules
- Try to resolve in
node_modules/jquery/package.json
or use thenode_modules/jquery/index.d.ts
. - Try to resolve in
node_modules/jquery/package.json
or use thenode_modules/@types/jquery/index.d.ts
(or something similar).
- Try to resolve in
- If you see a file named
- Take
- Meeting cut short - may be more to the algorithm.