8000 Add docs for Record flow types by leebyron · Pull Request #1343 · immutable-js/immutable-js · GitHub
[go: up one dir, main page]

Skip to content

Add docs for Record flow types #1343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions type-definitions/Immutable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2415,6 +2415,33 @@ declare module Immutable {
* var myRecord = new ABRecord({b: 3})
* myRecord.getAB() // 4
* ```
*
*
* **Flow Typing Records:**
*
* Immutable.js exports two Flow types designed to make it easier to use
* Records with flow typed code, `RecordOf<T>` and `RecordFactory<T>`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my gosh, thank you I've been hoping for this.

*
* When defining a new kind of Record factory function, use a flow type that
* describes the values the record contains along with `RecordFactory<T>`.
* To type instances of the Record (which the factory function returns),
* use `RecordOf<T>`.
*
* Typically, new Record definitions will export both the Record factory
* function as well as the Record instance type for use in other code.
*
* ```js
* import type { RecordFactory, RecordOf } from 'immutable';
*
* // Use RecordFactory<T> for defining new Record factory functions.
* type Point3DFields = { x: number, y: number, z: number };
* const makePoint3D: RecordFactory<Point3DFields> = Record({ x: 0, y: 0, z: 0 });
* export makePoint3D;
*
* // Use RecordOf<T> for defining new instances of that Record.
* export type Point3D = RecordOf<Point3DFields>;
* const some3DPoint: Point3D = makePoint3D({ x: 10, y: 20, z: 30 });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check it out @peggyrayzis! Well typed Records!

* ```
*/
export module Record {

Expand Down
11 changes: 6 additions & 5 deletions type-definitions/tests/immutable-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type {
KeyedSeq,
IndexedSeq,
SetSeq,
RecordFactory,
RecordOf,
} from '../../'

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

/* Record */

type PersonRecordMembers = { age: number, name: string }
const PersonRecordClass = Record(({
type PersonRecordFields = { age: number, name: string }
type PersonRecord = RecordOf<PersonRecordFields>;
const makePersonRecord: RecordFactory<PersonRecordFields> = Record({
age: 12,
name: 'Facebook',
}: PersonRecordMembers))
type PersonRecordInstance = RecordOf<PersonRecordMembers>
});

const personRecordInstance: PersonRecordInstance = PersonRecordClass({ age: 25 })
const personRecordInstance: PersonRecord = makePersonRecord({ age: 25 })

// $ExpectError
{ const age: string = personRecordInstance.get('age') }
Expand Down
35 changes: 22 additions & 13 deletions type-definitions/tests/record.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,32 +76,41 @@ var t1a: string = t1.a;
var t1c = t1.c;

// Use of new to create record factories (supported, but discouraged)
const PointNew = new Record({x:0, y:0});
type TPointNew = {x: number, y: number};
type PointNew = RecordOf<TPointNew>;
const MakePointNew: RecordFactory<TPointNew> = new Record({x:0, y:0});
// Not using new allows returning a record.
const origin: RecordOf<{x:number, y:number}> = PointNew();
// Can use the Record constructor type as an alternative,
// it just doesn't support property access.
const originAlt1: PointNew = PointNew();
// Can also sort of use the inner Record values type as an alternative,
// however it does not have the immutable record API, though useful for flowing
// immutable Records where plain objects are expected.
const originAlt2: {x: number, y: number} = PointNew();
const origin: PointNew = MakePointNew();
// Both get and prop access are supported with RecordOf
{ const x: number = origin.get('x') }
{ const x: number = origin.x }
// $ExpectError number is not a string
{ const x: string = origin.x }
// Can use the Record constructor type as an alternative,
// it just doesn't support property access.
const originAlt1: MakePointNew = MakePointNew();
// Both get and prop access are supported with RecordOf
{ const x: number = originAlt1.get('x') }
// $ExpectError cannot use property access for this alternative annotation
{ const x: number = originAlt1.x }
// Can also sort of use the inner Record values type as an alternative,
// however it does not have the immutable record API, though useful for flowing
// immutable Records where plain objects are expected.
const originAlt2: TPointNew = MakePointNew();
// $ExpectError cannot use Record API for this alternative annotation
{ const x: number = originAlt2.get('x') }
{ const x: number = originAlt2.x }

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

// $ExpectError instantiated with invalid type
const mistakeNewRecord = PointNew({x: 'string'});
const mistakeNewRecord = MakePointNew({x: 'string'});
// $ExpectError instantiated with invalid type
const mistakeNewInstance = new PointNew({x: 'string'});
const mistakeNewInstance = new MakePointNew({x: 'string'});
0