Skip to content

Downcasting to Record subset with Flow #1561

Open
@abesto

Description

@abesto

What happened

Using Immutable.js 4.0.0-rc.9 and [email protected]. 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;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions