In Flow, we currently have $PropertyType, which has been a savior. However, I'm struggling with typing nested objects. I have to deal with a ton of flow types that I don't control (they're auto generated types from a GraphQL schema).
I know we can wrap $PropertyTypes around each other. But after enough nested objects, this solution isn't very readable. I searched around for a good while but can't seem to find much on this use-case. Maybe I'm just a dummy and I'm missing something obvious.
Take this example:
type Article = {
title: string,
author: {
name: string,
location: {
city: string,
state: string,
zip: number
}
}
}
const article: Article = {
title: 'foo',
author: {
name: 'Joe',
location: {
city: 'Los Angeles',
state: 'CA',
zip: 12345,
geo: {
lat: 123,
long: 123
}
}
}
}
Currently, to type article.author.location, I have to do this:
const location: $PropertyType<$PropertyType<Article, 'author'>, 'location'> = article.author.location;
To type article.author.location.geo:
const geo: $PropertyType<$PropertyType<$PropertyType<Article, 'author'>, 'location'>, 'geo'> = article.author.location.geo;
Something like this would be more ideal:
// #1
const location: Article.author.location = article.author.location;
// #2
const location: $PropertyType<Article, 'author.location'> = article.author.location;
Anyone know of a more readable or maintainable solution?
Really want this if there's no solution to get type inference working in mapStateToProps from react-redux without explicitly re-typing the deeply accessed values from my RootState type via idx.
See #5056 for reference issue for my previous comment.
docs describe a pattern to get nested types using $Call
https://flow.org/en/docs/types/utilities/#toc-propertytype
it is not so straightforward either
// Extracting deeply nested types:
type NestedObj = {|
+status: ?number,
+data: ?$ReadOnlyArray<{|
+foo: ?{|
+bar: number,
|},
|}>,
|};
// If you wanted to extract the type for `bar`, you could use $Call:
type BarType = $Call<
<T>({
+data: ?$ReadOnlyArray<{
+foo: ?{
+bar: ?T
},
}>,
}) => T,
NestedObj,
>;
anyways, something like const location: Article.author.location = article.author.location; would be so useful!
@mrkev I think this would be much like the implementation of idx type
this would also make simpler to type lodash ._get
I'm having the same problem typing redux states with nested properties. At first glance, an easy answer to both of our problems is to just break up the type definitions even further.
type Article = {
title: string,
author: {
name: string,
location: {
city: string,
state: string,
zip: number
}
}
}
type Article = {
title: string,
author: ArticleAuthor
}
type ArticleAuthor = {
name: string,
location: ArticleAuthorLocation,
}
type ArticleAuthorLocation = {
city: string,
state: string,
zip: string,
}
But there's no denying that the proposal would be way more ideal for most use cases.
const location: Article.author.location = article.author.location
Most helpful comment
docs describe a pattern to get nested types using
$Callhttps://flow.org/en/docs/types/utilities/#toc-propertytype
it is not so straightforward either