This is actually an issue with the Immutable.js type definition. It always returns an any
type. Basically meaning Record
s aren't typechecked. I went into the reason why records are so loosly defined here. The gist of it is, Flow doesn't support intersect-types with objects yet (which the type of a record would have to be). But you can override the Record
type with the more restrictive type definition describedd in this answer. I copied it over:
declare class Record<T: Object> {
static <T: Object>(spec: T, name?: string): Record<T>;
get: <A>(key: $Keys<T>) => A;
set<A>(key: $Keys<T>, value: A): Record<T>;
remove(key: $Keys<T>): Record<T>;
}
If you add this decleration as a local decleration, you won't be able to access the properties directly anymore (like you did with data.name
), but will have to use the get
function like this data.get('name')
. IMO the downside of this definition is pretty minor, compared to the added type savety. Now sadly, due to other restrictions in the language, the types of the values aren't typechecked, as illustrated in this example.
Sadly there is no good solution for stronly typed immutable data structures in Flow yet. The features, required to make this perfect are pretty much on the roadmap for Flow though.
TL;DR
Record
s aren't typechecked, due to restrictions in the language. But you can improve typechecking by using the declaration provided above.