Skip to content

Commit c74dde0

Browse files
author
Travis CI
committed
Squashed commit of the following: commit 1d9f98adc72f40754c6a8a10e68a21388254302e Author: Travis CI <github@fb.com> Date: Fri Sep 29 17:37:08 2017 -0700 Rename RecordClass to RecordInstance and include RecordOf commit a5c82d59d5b172e658cf1dcf099e0fe601910f36 Merge: cf17600 1f66a82 Author: Travis CI <github@fb.com> Date: Fri Sep 29 16:26:48 2017 -0700 Merge branch 'master' of https://github.com/oreqizer/immutable-js into oreqizer-master commit 1f66a82 Author: oreqizer <oreqizer@gmail.com> Date: Thu Mar 30 19:13:18 2017 +0200 feat(flow): Add more tests for Record constructor commit f0addf8 Author: oreqizer <oreqizer@gmail.com> Date: Thu Mar 30 19:11:11 2017 +0200 feat(flow): Add test for Record constructor commit 54d4025 Author: oreqizer <oreqizer@gmail.com> Date: Thu Mar 30 19:10:37 2017 +0200 fix(flow): Remove <T> in constructors It was overriding RecordClass' generic signature. commit 94a54a0 Author: oreqizer <oreqizer@gmail.com> Date: Thu Mar 30 19:02:26 2017 +0200 refactor(flow): Directly return RecordClass There was an in-between step when constructing Records. Records now directly return a RecordClass that's the former RecordInstance. commit ec1a4a6 Author: oreqizer <oreqizer@gmail.com> Date: Thu Mar 30 18:31:00 2017 +0200 fix(flow): Record returns a Class<T> Makes Record return a Class type instead of an interface. Fixes an issue with constructor calls. commit 51c0e97 Author: Boris <oreqizer@users.noreply.github.com> Date: Thu Mar 30 17:38:03 2017 +0200 fix(flow): Change 'new' to 'constructor' Change definition for Record where constructor was specified with 'new'.
1 parent cf17600 commit c74dde0

File tree

4 files changed

+55
-20
lines changed

4 files changed

+55
-20
lines changed

dist/immutable.js.flow

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,20 +1287,22 @@ declare function Repeat<T>(value: T, times?: number): IndexedSeq<T>;
12871287

12881288
declare function isRecord(maybeRecord: any): boolean %checks(maybeRecord instanceof RecordInstance);
12891289
declare class Record {
1290-
static <Values>(spec: Values, name?: string): RecordClass<Values>;
1291-
constructor<Values>(spec: Values, name?: string): RecordClass<Values>;
1290+
static <Values: Object>(spec: Values, name?: string): Class<RecordInstance<Values>>;
1291+
constructor<Values: Object>(spec: Values, name?: string): Class<RecordInstance<Values>>;
12921292

12931293
static isRecord: typeof isRecord;
12941294

1295-
static getDescriptiveName(record: RecordInstance<*>): string;
1295+
static getDescriptiveName(record: RecordInstance<any>): string;
12961296
}
12971297

1298-
declare interface RecordClass<T> {
1299-
(values: $Shape<T> | Iterable<[string, any]>): RecordInstance<T> & T;
1300-
new (values: $Shape<T> | Iterable<[string, any]>): RecordInstance<T> & T;
1301-
}
1298+
type RecordOf<Values: Object> = RecordInstance<Values> & Values;
13021299

13031300
declare class RecordInstance<T: Object> {
1301+
static (values?: $Shape<T> | Iterable<[string, any]>): RecordOf<T>;
1302+
// Note: a constructor can only create an instance of RecordInstance<T>,
1303+
// it's encouraged to not use `new` when creating Records.
1304+
constructor (values?: $Shape<T> | Iterable<[string, any]>): void;
1305+
13041306
size: number;
13051307

13061308
has(key: string): boolean;
@@ -1421,7 +1423,8 @@ export type {
14211423
SetCollection,
14221424
KeyedSeq,
14231425
IndexedSeq,
1424-
RecordInstance,
14251426
SetSeq,
1427+
RecordOf,
1428+
RecordInstance,
14261429
ValueObject,
14271430
}

type-definitions/immutable.js.flow

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,20 +1287,22 @@ declare function Repeat<T>(value: T, times?: number): IndexedSeq<T>;
12871287

12881288
declare function isRecord(maybeRecord: any): boolean %checks(maybeRecord instanceof RecordInstance);
12891289
declare class Record {
1290-
static <Values>(spec: Values, name?: string): RecordClass<Values>;
1291-
constructor<Values>(spec: Values, name?: string): RecordClass<Values>;
1290+
static <Values: Object>(spec: Values, name?: string): Class<RecordInstance<Values>>;
1291+
constructor<Values: Object>(spec: Values, name?: string): Class<RecordInstance<Values>>;
12921292

12931293
static isRecord: typeof isRecord;
12941294

1295-
static getDescriptiveName(record: RecordInstance<*>): string;
1295+
static getDescriptiveName(record: RecordInstance<any>): string;
12961296
}
12971297

1298-
declare interface RecordClass<T> {
1299-
(values: $Shape<T> | Iterable<[string, any]>): RecordInstance<T> & T;
1300-
new (values: $Shape<T> | Iterable<[string, any]>): RecordInstance<T> & T;
1301-
}
1298+
type RecordOf<Values: Object> = RecordInstance<Values> & Values;
13021299

13031300
declare class RecordInstance<T: Object> {
1301+
static (values?: $Shape<T> | Iterable<[string, any]>): RecordOf<T>;
1302+
// Note: a constructor can only create an instance of RecordInstance<T>,
1303+
// it's encouraged to not use `new` when creating Records.
1304+
constructor (values?: $Shape<T> | Iterable<[string, any]>): void;
1305+
13041306
size: number;
13051307

13061308
has(key: string): boolean;
@@ -1421,7 +1423,8 @@ export type {
14211423
SetCollection,
14221424
KeyedSeq,
14231425
IndexedSeq,
1424-
RecordInstance,
14251426
SetSeq,
1427+
RecordOf,
1428+
RecordInstance,
14261429
ValueObject,
14271430
}

type-definitions/tests/immutable-flow.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ import * as Immutable2 from '../../'
2222
import type {
2323
KeyedCollection,
2424
IndexedCollection,
25-
RecordInstance,
2625
SetCollection,
2726
KeyedSeq,
2827
IndexedSeq,
2928
SetSeq,
29+
RecordOf,
3030
} from '../../'
3131

3232
/**
@@ -783,7 +783,7 @@ const PersonRecordClass = Record(({
783783
age: 12,
784784
name: 'Facebook',
785785
}: PersonRecordMembers))
786-
type PersonRecordInstance = RecordInstance<PersonRecordMembers> & PersonRecordMembers;
786+
type PersonRecordInstance = RecordOf<PersonRecordMembers>
787787

788788
const personRecordInstance: PersonRecordInstance = PersonRecordClass({ age: 25 })
789789

type-definitions/tests/record.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
// Some tests look like they are repeated in order to avoid false positives.
66
// Flow might not complain about an instance of (what it thinks is) T to be assigned to T<K, V>
77

8-
import { Record } from '../../';
8+
import { Record, type RecordOf } from '../../';
99

1010
const Point2 = Record({x:0, y:0});
1111
const Point3 = Record({x:0, y:0, z:0});
12-
const GeoPoint = Record({lat:(null: ?number), lon:(null: ?number)});
12+
type TGeoPoint = {lat: ?number, lon: ?number}
13+
const GeoPoint = Record(({lat: null, lon: null}: TGeoPoint));
1314

1415
let origin2 = Point2({});
1516
let origin3 = Point3({});
@@ -19,6 +20,10 @@ const mistake = Point2({x:'string'});
1920
origin3 = GeoPoint({lat:34})
2021
geo = Point3({});
2122

23+
// Use RecordOf to type the return value of a Record factory function.
24+
// This should expect an error, is flow confused?
25+
let geoPointExpected: RecordOf<TGeoPoint> = GeoPoint({});
26+
2227
const px = origin2.get('x');
2328
const px2: number = origin2.x;
2429
// $ExpectError
@@ -57,3 +62,27 @@ var t4 = t2.setC(10);
5762
var t1a: string = t1.a;
5863
// Note: flow does not check extended Record classes yet
5964
var t1c = t1.c;
65+
66+
// Use of new to create record factories (supported, but discouraged)
67+
const PointNew = new Record({x:0, y:0});
68+
// Not using new allows returning a record.
69+
const origin: RecordOf<{x:number, y:number}> = PointNew();
70+
// Both get and prop access are supported with RecordOf
71+
{ const x: number = origin.get('x') }
72+
{ const x: number = origin.x }
73+
// $ExpectError number is not a string
74+
{ const x: string = origin.x }
75+
76+
// $ExpectError Use of new may only return a class instance, not a record
77+
const mistakeOriginNew: RecordOf<{x:number, y:number}> = new PointNew();
78+
// An alternative type strategy is instance based
79+
const originNew: PointNew = new PointNew();
80+
// Only get, but not prop access are supported with class instances
81+
{ const x: number = originNew.get('x') }
82+
// $ExpectError property `x`. Property not found in RecordInstance
83+
{ const x: number = originNew.x }
84+
85+
// $ExpectError instantiated with invalid type
86+
const mistakeNewRecord = PointNew({x: 'string'});
87+
// $ExpectError instantiated with invalid type
88+
const mistakeNewInstance = new PointNew({x: 'string'});

0 commit comments

Comments
 (0)