https://github.com/tc39/proposal-optional-chaining/
https://github.com/tc39/proposal-optional-chaining/issues/59
https://github.com/microsoft/TypeScript/issues/31156
https://github.com/microsoft/TypeScript/pull/31206
string | number
to "hello" | number
.Cat & Mortgage
seems unlikely, but it's indistinguishable from MixinA & MixinB
.hasType
exhibits some issues here, and the new behavior catches this.Is TS team going to implement optional chaining soon? (Maybe here is the wrong place to ask, but related issues have been locked :-)
Conclusion: we don't think we have any idea of how to cleanly solve the current problem. No action chosen. We may
Well? You may... what? Don't leave us hanging here! :smile:
@hax Optional chaining is Stage 2. TS typically doesn't implement proposed syntax until it hits Stage 3.
Ugh, it's been a week but I assume it's probably just "revisit if we come up with other ideas." @andrewbranch?
Actually, I thought the trailing "We may" was very Yoda of you.
But the new behavior explodes in types, is usually not the intent for many cases, and creates impossible branded literal types.
I'm wondering for the sake of performance, whether it is useful to implement some overflow
types in these situations such that they widen automatically as aliases of related basic types (eg string
or any
) if the explosion passes certain limits, thereby allowing them to collapse back to simpler type expressions.
At least then we might avoid performance issues and the programmer can see the underlying problem rather than a huge jumble of type combinations.
It's possible, but it could lead to a lot of unexpected results with behavior that's hard to predict. Also, we often don't know that an operation will cause the creation of many types until you perform the operation itself.
A lot of user intent seems to indicate people think of types as closed.
Excess property checking in object literals is a big contributor to this misconception, I鈥檝e found. You would think the existence of intersection types (implying that overlap is possible) would clue people in, but alas...
To expand on the above point re: closed types, I think the error message for the excess property check is misleading:
interface FooBar {
foo: string;
bar: string;
}
let x: FooBar = {
foo: "pig",
bar: "cow",
baz: "ape", // error here
};
let tmp = {
foo: "pig",
bar: "cow",
baz: "ape",
}
let y: FooBar = tmp; // this is fine
The error message for the assignment to x
is:
Type '{ foo: string; bar: string; baz: string; }' is not assignable to type 'FooBar'.
Object literal may only specify known properties, and 'baz' does not exist in type 'FooBar'.
"Not assignable" sounds like a blanket statement, but clearly it is assignable, since assigning the exact same type through tmp
works; we've just made an exception for direct object literals in order to catch typos. To be fair, it does say "Object literal may only specify known properties", but the position of that text makes it appear like a footnote and easy to miss. Could we improve this error message to make it clearer that this is a special case and not the general statement about object assignability it looks like?
@fatcerberus in a technical sense, the error message is correct - the fresh type '{ foo: string; bar: string; baz: string; }' is not assignable to type 'FooBar'.
. But we don't show freshness in type printback, so it does seem wrong.
We could perhaps say something like
Type of object literal '{ foo: string; bar: string; baz: string; }' is not assignable to type 'FooBar'.
Object literal may only specify known properties, and 'baz' does not exist in type 'FooBar'.
I would probably just say Object literal '{ ... }' is not assignable to...
, without mention of "type" at all. I'd want to make it very clear in the error message that this case only applies because the assignment is from a fresh object literal and is NOT a statement about structural typing in general.
We may
Ugh, it's been a week but I assume it's probably just "revisit if we come up with other ideas."
Sounds right to me 馃槃
Or possibly it was referring to what I posted in the issue?
I may look into doing the correct thing when all constituents of both the original type and the predicate type are primitives, since intersections of those are more intuitive and fall out when empty. On the other hand, I鈥檓 not sure if we want that kind of logical branching鈥攎aybe it鈥檚 better just to keep it in its current slightly wrong but consistent state.
nullish vs. uncallable behavior for optional call
@DanielRosenwasser Can you point me to discussions on this topic? My intuition would be that an optional call feature would test for callability, not nullability. But I'd love to be convinced otherwise. FYI CoffeeScript's optional call feature tests for callability.
If optional call tests for callability, then based on the semantics of optional property access, you'd be propagating out undefined
when you have an uncallable value. In other words, false?.()
gives you undefined
. That doesn't really seem like useful behavior to anyone I've discussed the feature with.
In my opinion it makes the most sense to keep optional call consistent with optional property access in that they both only propagate undefined
from null
/undefined
.
Optional Chaining is Stage 3 now.
Is TS team going to implement optional chaining soon?
@ppjjzz you was faster than me :)
Here is the reference : https://github.com/tc39/proposal-optional-chaining
Can't wait to see it in typescript.
It is not necessarily a good thing for TS. I don't mind TS to leave it alone (and break the "superset of ecmascript" promise). On the other hand, I'd be very upset if it were introduced in a lousy way.
I'm not saying optional chaining
is bad. It is definitely good for JS due to its dynamic (unsafe) feature. That, may not the case in TS world, not without drawbacks.
As you said, TS is a superset of JavaScript, it does not have to miss futur JS features.
If it's not the best feature to come, it's still one, and people are not forced to use it.
But for me it's a great one.
As you said, TS is a superset of JavaScript, it does not have to miss futur JS features.
If it's not the best feature to come, it's still one, and people are not forced to use it.
But for me it's a great one.
I respect that. However don't you think the PL guys should consider more than 'people are not forced to use it'? Isn't any feature like that?
Here's a simple example:
interface Something{
p1: Other
}
interface Other {
p2: string
}
let s: Something = ...
// are you going to let me write this?
// Either way, you are breaking something: the typing or the superset thing
s.p1? .p2?
I'd believe the reality would be much more complicated, as this note says.
@noru As I understand, TS should not allow you write s.p1?.p2
because s.p1
is never nullish. It is only allowed if the interface Something
is:
interface Something{
p1?: Other
}
// or
interface Something{
p1: Other | null
}
// or
interface Something{
p1: Other | null | undefined
}
@noru As I understand, TS should not allow you write
s.p1?.p2
becauses.p1
is never nullish.
Yeah I'd like to see that too. But therefore TS goes separate way with js and drop the runtime null-safe guarantee that js provides.
drop the runtime null-safe guarantee that js provides.
I'm not sure I understand what you mean. Do you mean s.p1
could be nullish in JS runtime even TS never allow it in compile time? It's possible anyway, but I don't think it's a good reason to abuse ?.
to write everything like a?.b?.c?.d?.e
.
But I don't think it's a good reason to abuse
?.
to write everything likea?.b?.c?.d?.e
.
Again, I agree. But I don't see means to prevent such abuse. That's why I said I don't mind not having it in TS when types already solved 80% of my problems.
I think the question is, how to enable full support of optional chaining
without hurt the existing types. It may be a mission impossible...
Again, I agree. But I don't see means to prevent such abuse
TypeScript could give tips for such abuse I believe. @noru
Optional chaining is going to be great, and I look forward to seeing in TypeScript. It will simplify a ton of the code I write in a team every day.
Optional chaining is going to be great, and I look forward to seeing in TypeScript. It will simplify a ton of the code I write in a team every day.
Definitely. Is it fair to ask whether it is reasonable for us to expect this in 3.6? Or is that too soon?
Or is that too soon?
Too soon. We cut the 3.6 beta 4 weeks ago, and the RC is in the next few days.
Most helpful comment
Optional Chaining is Stage 3 now.
Is TS team going to implement optional chaining soon?