8000 Add docs for Record flow types (#1343) · immutable-js/immutable-js@a976172 · GitHub
[go: up one dir, main page]

Skip to content

Commit a976172

Browse files
authored
Add docs for Record flow types (#1343)
Added a section to the Record documentation describing how to use `RecordFactory<T>` and `RecordOf<T>` and updated some flow tests to better match those usages.
1 parent 0122fef commit a976172

File tree

3 files changed

+55
-18
lines changed

3 files changed

+55
-18
lines changed

type-definitions/Immutable.d.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,33 @@ declare module Immutable {
24282428
* var myRecord = new ABRecord({b: 3})
24292429
* myRecord.getAB() // 4
24302430
* ```
2431+
*
2432+
*
2433+
* **Flow Typing Records:**
2434+
*
2435+
* Immutable.js exports two Flow types designed to make it easier to use
2436+
* Records with flow typed code, `RecordOf<T>` and `RecordFactory<T>`.
2437+
*
2438+
* When defining a new kind of Record factory function, use a flow type that
2439+
* describes the values the record contains along with `RecordFactory<T>`.
2440+
* To type instances of the Record (which the factory function returns),
2441+
* use `RecordOf<T>`.
2442+
*
2443+
* Typically, new Record definitions will export both the Record factory
2444+
* function as well as the Record instance type for use in other code.
2445+
*
2446+
* ```js
2447+
* import type { RecordFactory, RecordOf } from 'immutable';
2448+
*
2449+
* // Use RecordFactory<T> for defining new Record factory functions.
2450+
* type Point3DFields = { x: number, y: number, z: number };
2451+
* const makePoint3D: RecordFactory<Point3DFields> = Record({ x: 0, y: 0, z: 0 });
2452+
* export makePoint3D;
2453+
*
2454+
* // Use RecordOf<T> for defining new instances of that Record.
2455+
* export type Point3D = RecordOf<Point3DFields>;
2456+
* const some3DPoint: Point3D = makePoint3D({ x: 10, y: 20, z: 30 });
2457+
* ```
24312458
*/
24322459
export module Record {
24332460

type-definitions/tests/immutable-flow.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import type {
3131
KeyedSeq,
3232
IndexedSeq,
3333
SetSeq,
34+
RecordFactory,
3435
RecordOf,
3536
} from '../../'
3637

@@ -786,14 +787,14 @@ let maybeNumberSeqSize: ?number = numberSeq.size
786787

787788
/* Record */
788789

789-
type PersonRecordMembers = { age: number, name: string }
790-
const PersonRecordClass = Record(({
790+
type PersonRecordFields = { age: number, name: string }
791+
type PersonRecord = RecordOf<PersonRecordFields>;
792+
const makePersonRecord: RecordFactory<PersonRecordFields> = Record({
791793
age: 12,
792794
name: 'Facebook',
793-
}: PersonRecordMembers))
794-
type PersonRecordInstance = RecordOf<PersonRecordMembers>
795+
});
795796

796-
const personRecordInstance: PersonRecordInstance = PersonRecordClass({ age: 25 })
797+
const personRecordInstance: PersonRecord = makePersonRecord({ age: 25 })
797798

798799
// $ExpectError
799800
{ const age: string = personRecordInstance.get('age') }

type-definitions/tests/record.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,32 +76,41 @@ var t1a: string = t1.a;
7676
var t1c = t1.c;
7777

7878
// Use of new to create record factories (supported, but discouraged)
79-
const PointNew = new Record({x:0, y:0});
79+
type TPointNew = {x: number, y: number};
80+
type PointNew = RecordOf<TPointNew>;
81+
const MakePointNew: RecordFactory<TPointNew> = new Record({x:0, y:0});
8082
// Not using new allows returning a record.
81-
const origin: RecordOf<{x:number, y:number}> = PointNew();
82-
// Can use the Record constructor type as an alternative,
83-
// it just doesn't support property access.
84-
const originAlt1: PointNew = PointNew();
85-
// Can also sort of use the inner Record values type as an alternative,
86-
// however it does not have the immutable record API, though useful for flowing
87-
// immutable Records where plain objects are expected.
88-
const originAlt2: {x: number, y: number} = PointNew();
83+
const origin: PointNew = MakePointNew();
8984
// Both get and prop access are supported with RecordOf
9085
{ const x: number = origin.get('x') }
9186
{ const x: number = origin.x }
9287
// $ExpectError number is not a string
9388
{ const x: string = origin.x }
89+
// Can use the Record constructor type as an alternative,
90+
// it just doesn't support property access.
91+
const originAlt1: MakePointNew = MakePointNew();
92+
// Both get and prop access are supported with RecordOf
93+
{ const x: number = originAlt1.get('x') }
94+
// $ExpectError cannot use property access for this alternative annotation
95+
{ const x: number = originAlt1.x }
96+
// Can also sort of use the inner Record values type as an alternative,
97+
// however it does not have the immutable record API, though useful for flowing
98+
// immutable Records where plain objects are expected.
99+
const originAlt2: TPointNew = MakePointNew();
100+
// $ExpectError cannot use Record API for this alternative annotation
101+
{ const x: number = originAlt2.get('x') }
102+
{ const x: number = originAlt2.x }
94103

95104
// $ExpectError Use of new may only return a class instance, not a record
96-
const mistakeOriginNew: RecordOf<{x: number, y: number}> = new PointNew();
105+
const mistakeOriginNew: PointNew = new MakePointNew();
97106
// An alternative type strategy is instance based
98-
const originNew: PointNew = new PointNew();
107+
const originNew: MakePointNew = new MakePointNew();
99108
// Only get, but not prop access are supported with class instances
100109
{ const x: number = originNew.get('x') }
101110
// $ExpectError property `x`. Property not found in RecordInstance
102111
{ const x: number = originNew.x }
103112

104113
// $ExpectError instantiated with invalid type
105-
const mistakeNewRecord = PointNew({x: 'string'});
114+
const mistakeNewRecord = MakePointNew({x: 'string'});
106115
// $ExpectError instantiated with invalid type
107-
const mistakeNewInstance = new PointNew({x: 'string'});
116+
const mistakeNewInstance = new MakePointNew({x: 'string'});

0 commit comments

Comments
 (0)
0