When could we expect optional chaining support.
It will be released soon with babel@7.
this is super important to make the code more readable. i'd love to have this.
this feature is really important for project i am working for. waiting for implementation!
This is really important for dealing with JSON responses without having to write a plethora of null checks. +1
Note that optional chaining is still a stage 1 proposal and has gone through a number of changes since the Babel plugin was implemented. It's very likely that there will be changes to both the syntax and the behavior before the final JS feature is released.
See various other discussions:
https://github.com/tc39/proposal-optional-chaining
https://github.com/rwaldron/tc39-notes
https://github.com/Microsoft/TypeScript/issues/16
Can be a simple case of optional chaining (optional static property access) implemented today under option's flag esproposal or experemental?
I say about simple property reading from nested objects a?.b?.c, which will be an amazing improvement in the code for React components. Eg when reading graphql responses.
And leave dynamic and function/method calls uncovered while it in stage-1.
cc @calebmer @mroch
which will be an amazing improvement in the code for React components. Eg when reading graphql responses.
would love to see that! we could remove tons of code and checks if flow also supports this syntax. thanks @nodkz and @alangpierce for having an eye on that.
looks like this will be in the next version ๐https://github.com/facebook/flow/commit/763ffb509b237e2358bbace871732ee3e2bd623b
@cloudkite looks like only parsing will be supported. Type support isn't landing, as the feature has been marked as experimental.
I've added (most) type support for optional chaining in 0.71.0 (gated behind the esproposal.optional_chaining
flag). The exception is that you'll get a Flow error if you try to call a member expression where the call and/or member is part of an optional chain. Once I get optional chaining to play nice with our implementation of methods, I'll remove this restriction.
This is amazing, I've been waiting for this.
In the following situation it complains about dash.exampleLogs[x] on line 319 because dash.exampleLogs might be undefined, however given that this code will only run if line 318 is true, shouldn't Flow realize that this cannot be undefined in this context?
Cannot get dash.exampleLogs[x] because an indexer property is missing in undefined [1].
frog/imports/ui/Preview/ShowDashExample.js
316โ const dash = aTdashs[this.state.example];
317โ let data;
318โ if (dash?.exampleLogs?.[x].type === 'state') {
319โ data = dash.exampleLogs[x].state;
320โ } else if (dash.prepareDataForDisplay) {
321โ data = dash.prepareDataForDisplay(
322โ dash.initData,
frog-utils/dist/types.js.flow
[1] 157โ | {
158โ type: 'logs',
159โ title: string,
160โ path: string,
161โ activityMerge?: Object,
162โ instances?: number
163โ }
164โ | { title: string, type: 'state', activityMerge?: Object, state: any }
165โ )[]
@houshuang We could potentially do that, but Flow doesn't currently perform that refinement.
@houshuang feel free to create a separate issue to track and discuss that
@houshuang @fishythefish @mrkev was a separate issue ever created? I too am finding it hard to make use of optional chaining when flow complains that I haven't checked for null
(when I have).
I haven't seen one.
Babel 7 RC has been released - it would be nice to have this and null coalescing ready when Babel 7 is fully released
Babel 7 is being released this week:
https://twitter.com/left_pad/status/1031700991186489344
Any progress on this? Babel 7 is now fully released: https://babeljs.io/blog/2018/08/27/7.0.0
I can only speculate as I'm not a core contributor to Flow but Just because babel supports a feature, doesn't mean Flow will or wont support it. optional chaining happens to be partially supported in Flow already but function calls are not yet supported. Maybe someone from the Flow core team could comment on if adding full support is planned? Or is this a feature the core team would be willing to merge but not prioritized?
function calls not supported and typing also. the optional property become ?any
type(afaik)
@eshikerya If typing is broken, that would be an issue but as far as I've seen, typing when using optional chaining is working as expected. Here's an example. Could you provide an example that demonstrates the issue you're seeing?
````js
function func(prop1 : ? { prop2?: string }) {
return prop1?.prop2;
}
// no error
(func({bar: { bar : 'wow' }}): ?string);
// errors as expected
(func({bar: { bar : 'wow' }}): ?number);
````
cc @samwgoldman or @avikchaudhuri
@vicapow it seems that basic property access work, but methods do not:
with [email protected] it works as expected
type Dictionary<K, V> = { [id: K]: V };
type enmWorkspaceUserRoleType =
| "Nobody"
| "Resource"
| "Spectator"
| "Participant"
| "Leader"
| "Owner";
type WorkspaceUserInfoType = {
id: ID,
name: string,
role: enmWorkspaceUserRoleType
};
type WorkspaceInfoType = {
id: ID,
name: string,
workspaceUser?: WorkspaceUserInfoType
};
const workspaces: Dictionary<string, WorkspaceInfoType> = {
testId: {
id: "testId",
name: "Test Workspace",
workspaceUser: {
id: "userId",
name: "Test User",
role: "Owner"
}
}
};
console.log(workspaces.testId?.workspaceUser?.role);
expected error will be reported in case:
console.log(workspaces.testId?.workspaceUser.role);
Cannot get `workspaces.testId?.workspaceUser.role` because property `role` is missing in undefined [1]. [1]
Assuming the proposal remains unchanged, the plan is to eventually add support for calls in optional chains. However, we're waiting for the proposal to progress beyond stage 1, since it's unclear whether optional calls will make it into the final proposal and, if so, what semantics they will have; see https://github.com/tc39/proposal-optional-chaining/issues/59.
Fair enough. In the meantime, would it be feasible to add an option that disables checking in this particular case, trading a small amount of type safety for the ability to use this syntax?
Feasible, but low priority. (As usual, PRs are welcome!)
@fishythefish seems that optional chaining fails when used with $Call. This does work as expected:
type A = ?{aaa: string};
declare var eee: A;
let www = eee?.aaa; // No error here
This fails:
type F = <T>(T) => ?{aaa: T};
type O<T> = $Call<F, T>;
declare var bbb: O<string>;
let ccc = bbb?.aaa; // Woops! An error!
Why didn't optional chaining prevent an error from being raised?
That's an interesting case. The $
types are typically evaluated lazily, so I believe what's happening here is that when the ?.
is checked, the LHS is seen to be some opaque CallT
type. Flow doesn't recognize this as containing null
or undefined
values, so it ignores that branch and tries to proceed with the usual property access. This eventually forces the evaluation of the $Call
, and Flow complains because we're now trying to perform a property lookup on a nullable type. ?.
should force the evaluation of its LHS earlier. I'll look into this case further.
@fishythefish Thanks for working on optional chaining its a really awesome feature!
In regards to $Call it seems very flakey do you have any insight on whether this is meant to work or why it doesnt? https://github.com/facebook/flow/issues/6506
@fishythefish looks like https://github.com/tc39/proposal-optional-chaining/issues/59 is about things like foo?.()
which is truly controversial, not about foo?.bar()
to be clear, not the short-circuiting of method calls, just the ?.( optional call)
@fishythefish have you implemented the unnecessary optional chaining linting rule? Would it be feasible to add an exception to it if object type is {[id: string]: {a: number}}
(see https://github.com/facebook/flow/issues/6980 )? IMO proper fix would be to make result maybe type but just thinking about potential alternatives.
@villesau Yes, it was in the v0.74 changelog and you can find it in the docs.
We're unlikely to add such an exception right now. It's only a lint, so feel free to suppress or disable it if it makes sense for you. As with array access, it is the programmer's responsibility to ensure that they're looking up a valid key.
@fishythefish I think the lint is maybe the best part of the whole functionality :D It enforces consistency between checks and types: Otherwise the types are much more likely to rot if they don't match conditions. It revealed already after couple of weeks of optional chaining usage many types that didn't had maybe type when they should have had, and vice versa unnecessary checks. But if it does not work with {[id: string]: SomeType}
, that makes it much more difficult to use.
I find array access very different. With array access it is easy to know what is the last available index and stay secure. With arbitrary key access, you don't have such privilege, and the linting rule prevents easy checks. With object on the other hand, you can define finite amount of possible keys if you want to make it more secure. {[id: string]: SomeType}
defines "you _might_ have any key", not "You have every key"
Just reviewed the thread where optional chaining and methods was being discussed. It looks like they've resolved to keep the syntax as is, according to the most recent comment. With this in mind, could we revisit implementing this functionality in flow?
Are we at the point where an implementation PR would be accepted? I'd be happy to take a shot at getting it working if that's the only hurdle left.
IIRC this was waiting for the proposal to go through, though I might be wrong. Someone in the team might know better. @dsainati1
I'm not an expert on this unfortunately so I don't have any new information.
@dsainati1 who would know if this is something that can be added?
Not sure honestly. Maybe @nmote?
Optional chaining has been brought to stage-2 yesterday. Can we move forward now, Flow?
https://github.com/tc39/proposals/commit/effb785bc27388152e3bd307c5189c676ba478eb
https://github.com/tc39/proposal-optional-chaining/issues/83#issuecomment-499145723
Update: Optional chaining has moved to Stage 3
https://github.com/tc39/proposals/commit/25f8d6a4db03bcdd2cfd49bf32e312ce80e1c80e
https://github.com/tc39/proposal-optional-chaining/commit/73cf9852a2eba6d281fbfa98f848aca1b50f43a3
@kenrick95 that was fast
@mroch is it possible to support optional calls?
It is now supported by v8.
Sorry โ typo. It was supposed to say:
It is _now_ supported by v8.
Edited.
At this point it's just a matter of prioritization. The worry with implementing early-stage proposals is that we will implement something that does not match the final specification of the feature, leading to a painful non-backwards-compatible change down the road. At this point, I wouldn't worry about that with optional chaining.
Is it possible to change Flow does not yet support method or property calls in optional chains.
error into a warning?
Any update on the priority of proper support for optional chaining?
We (or at least I) think that flow is really great and we love using it, but sometimes you can't help but ask yourself if it's time to move to TypeScript, which now support optional chaining and null coalescing.
@ovidb Flow supports both for a long time. Optional calls support was introduced in the latest release.
@ovidb Flow supports both for a long time. Optional calls support was introduced in the latest release.
@TrySound I apologise for not checking the release notes, but I am on the latest version and the reason I thought it's still not supported is because whenever you use optional chaining inside an if statement, flow doesn't seem to understand that that maybe value has been checked for. Is this a bug or a known fact?
https://flow.org/try/#0C4TwDgpgBA8mwEsD2A7AhgGygXigbwCgBINAfgC58CooiiAjSgZ2ACcEUBzAGmIF8CAggDMArigDGiVFGAQWcaegwAKJPGTLKizZgCUVIgmFQ1G1JgB0ZS-QOEajx+qVW0ty8CQBlNh04qegDc1I4CAk5OoZEE0U5AA
On the bright side, thanks for letting us know that calls support is now working. Thats amazing news!!!
@ovidb This works: https://flow.org/try/#0C4TwDgpgBA8mwEsD2A7AhgGygXigbwCgoo0B+ALnyKgEgAjSgZ2ACcEUBzAGmoF8D+BAGYBXFAGNEqKMAjM4U9BgAUSeMiWUFGzAEoqxNYswA6MibongSAMqt2HZboDc1BEKir1qU2igBCXBQRDAx9QmIaIx0MMwsrW3tOJ1difl4gA Must be something about using optional chaining in conditionals.
Yes, currently refinement is not preserved. So you need to cache optional chaining result in variable or use null check in if statement.
FTR in case it's helpful for anyone else, it looks like v0.112.0 was the release that introduced support for method calls in optional chains.
I determined that using this handy demo from a comment above:
This works: https://flow.org/try/#0C4TwDgpgBA8mwEsD2A7AhgGygXigbwCgoo0B+ALnyKgEgAjSgZ2ACcEUBzAGmoF8D+BAGYBXFAGNEqKMAjM4U9BgAUSeMiWUFGzAEoqxNYswA6MibongSAMqt2HZboDc1BEKir1qU2igBCXBQRDAx9QmIaIx0MMwsrW3tOJ1difl4gA
and a quick binary search. It's also mentioned in the release notes under v0.112.0, though not very definitively.
Most helpful comment
Optional chaining has been brought to stage-2 yesterday. Can we move forward now, Flow?
https://github.com/tc39/proposals/commit/effb785bc27388152e3bd307c5189c676ba478eb
https://github.com/tc39/proposal-optional-chaining/issues/83#issuecomment-499145723