Description
Flow version: 0.97.0 / immutable 4.0.0-rc12
What happened
When defining records, you have to do all the typecasting because Record()
has a incorrect type definition.
How to reproduce
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>
.