Open
Description
What happened
Using Immutable.js 4.0.0-rc.9
and flow-bin@0.77.0
. It appears it's not possible to correctly express in the Flow type-system downcasting of a Record
type to another Record
type whose fields are a strict subset.
(Reading https://flow.org/en/docs/lang/subtypes/ I feel like this should work, so feel free to redirect me to open a feature request / bugreport in Flow instead.)
How to reproduce
//@flow strict
import { Record } from 'immutable'
import type { RecordFactory, RecordOf } from 'immutable'
type SubProps = {a: number}
export const makeSub: RecordFactory<SubProps> = Record({a: 0})
export type Sub = RecordOf<SubProps>
type SuperProps = {a: number, b: number}
export const makeSuper: RecordFactory<SuperProps> = Record({a: 0, b: 0})
export type Super = RecordOf<SuperProps>
function f(o: Sub): number {
return o.get('a')
}
const o = makeSuper()
f(o)
Output of yarn run flow
:
Cannot call f with o bound to o because property b is missing in SubProps [1] but exists in SuperProps [2] in type
argument Values [3].
src/repro.js
[1] 7│ export type Sub = RecordOf<SubProps>
8│
9│ type SuperProps = {a: number, b: number}
[2] 10│ export const makeSuper: RecordFactory<SuperProps> = Record({a: 0, b: 0})
:
15│ }
16│
17│ const o = makeSuper()
18│ f(o)
19│
node_modules/immutable/dist/immutable.js.flow
[3] 1379│ type RecordOf<Values: Object> = RecordInstance<Values> & Values;