Flow: Immutable definitions for Record<T> are sloppy

Created on 3 Jul 2019  路  5Comments  路  Source: facebook/flow

Flow version: 0.97.0

Expected behavior

Creation of records should have types.

Actual behavior

When creating records, unless you are very explicit, you have no type safety.

type Product = { address: string };
type App = { name: string };
const AppDefaults: App = { name: '' };

const AppRecordImplicit = Record(AppDefaults);        // class RecordInstance<T: any = any>
const AppRecordExplicit = Record<App>({ name: '' });  // class RecordInstance<T: any = any>
const AppRecordBorked: RecordFactory<App> =           // RecordFactory<App>
  Record<Product>({ address: '' });

const appImplicit = AppRecordImplicit({ name: 'i' }); // RecordOf<empty>
const appExplicit = AppRecordExplicit({ name: 'e' }); // RecordOf<empty>
const appBorked = AppRecordBorked({ name: 'b' });     // RecordOf<App>

In the above code, none of the ways of creating records work. The only way that actually works is to say:

const AppRecordExtraExplicit: RecordFactory<App> = Record<App>(AppDefaults);

Ideally, I'd expect either of the first two to work (AppRecordImplicit or AppRecordExplicit). However, they create RecordOf<empty> since they are not typed themselves (they receive class RecordInstance<T: any>).
The third call illustrates how that is a bit crazy, since you can successfully cast a record factory of one type to another (which leads you to be able to make records of the wrong type entirely).

Only by using AppRecordExtraExplicit -- and using it correctly, since it is the same form as AppRecordBorked -- can you get a RecordFactory<App> and produce actual RecordOf<App>.

Immutable.js

All 5 comments

Why is this bug being reported here? File this bug in the flow-typed or Immutable.js repos.

@jcready no idea :\ Also flow has Immutable.js label for some reason

@jcready @goodmind , sorry I did not know where to put it. I had put some similar bugs yesterday here. You are probably right that this one (but not the others I posted, I think they are more subtle) is just a type definition issue, but it's not clear as a user of flow/immutable that this is the case. I will post this one in the immutable repo.

@gryn I will say that flow and Immutable.js mix about as well as water and oil. You will be hard pressed to find any success stories of using both together.

@jcready That's unfortunate to hear. Do you have any specific reading or examples I can look into? I am typescript in one project and flow in the other, but we are both using immutable.

Was this page helpful?
0 / 5 - 0 ratings