Created
August 1, 2015 14:32
-
-
Save s-panferov/722dad3103b5e9a8e4d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as Immutable from 'immutable'; | |
import { | |
Profile, | |
User, | |
} from './models'; | |
export { | |
Profile, | |
User, | |
}; | |
export interface RecordClass<T extends Immutable.Map<string, void>> { | |
new (): T; | |
new (values: T): T; | |
} | |
export interface RecordCtor<R, T extends Immutable.Map<string, any>> { | |
(defaultValues: T | R, name?: string): RecordClass<T> | |
} | |
function fromJSDefault(json) { | |
if (Array.isArray(json)) { | |
return (Immutable.Seq as any).Indexed(json).map(fromJSDefault).toList(); | |
} | |
if (isPlainObj(json)) { | |
return (Immutable.Seq as any).Keyed(json).map(fromJSDefault).toMap(); | |
} | |
return json; | |
} | |
function isPlainObj(value) { | |
return value && (value.constructor === Object || value.constructor === undefined); | |
} | |
/** | |
* Map interface for Profile with specialized getters and setters. | |
*/ | |
export interface ProfileMap extends Profile, Immutable.Map<string, void> { | |
ProfileMap: ProfileMap | |
get(key: 'firstName', defaultValue?: string): string | |
set(key: 'firstName', value: string): ProfileMap | |
get(key: 'lastName', defaultValue?: string): string | |
set(key: 'lastName', value: string): ProfileMap | |
get(key: string, defaultValue?: any): void; | |
set(key: string, value: typeof undefined): ProfileMap; | |
} | |
/** | |
* Default fields that must be provided in ProfileRecord. | |
*/ | |
export interface ProfileRecordDefaults { | |
firstName: string | |
lastName: string | |
} | |
/** | |
* Typed ProfileRecord constructor. | |
*/ | |
export let ProfileRecordCtor: RecordCtor<ProfileRecordDefaults, ProfileMap> = Immutable.Record as any; | |
/** | |
* ProfileRecord dependencies | |
*/ | |
export interface ProfileRecordDeps { | |
ProfileRecord: RecordClass<ProfileMap> | |
} | |
/** | |
* Special method to parse ProfileRecord with all the dependencies. | |
*/ | |
export function parseProfileRecord(value: Profile, deps: ProfileRecordDeps): ProfileMap { | |
var recordWalker = function(value, key) { | |
switch (true) { | |
default: return fromJSDefault(value); | |
} | |
}; | |
var result: any = {}; | |
for (var k in value) { | |
if (value.hasOwnProperty) { | |
result[k] = recordWalker(value[k], k); | |
} | |
} | |
return new deps.ProfileRecord(result); | |
} | |
/** | |
* Map interface for User with specialized getters and setters. | |
*/ | |
export interface UserMap extends User, Immutable.Map<string, void> { | |
UserMap: UserMap | |
get(key: 'profile', defaultValue?: ProfileMap): ProfileMap | |
set(key: 'profile', value: ProfileMap): UserMap | |
get(key: 'login', defaultValue?: string): string | |
set(key: 'login', value: string): UserMap | |
get(key: string, defaultValue?: any): void; | |
set(key: string, value: typeof undefined): UserMap; | |
} | |
/** | |
* Default fields that must be provided in UserRecord. | |
*/ | |
export interface UserRecordDefaults { | |
profile: Profile | |
login: string | |
} | |
/** | |
* Typed UserRecord constructor. | |
*/ | |
export let UserRecordCtor: RecordCtor<UserRecordDefaults, UserMap> = Immutable.Record as any; | |
/** | |
* UserRecord dependencies | |
*/ | |
export interface UserRecordDeps { | |
ProfileRecord: RecordClass<ProfileMap> | |
UserRecord: RecordClass<UserMap> | |
} | |
/** | |
* Special method to parse UserRecord with all the dependencies. | |
*/ | |
export function parseUserRecord(value: User, deps: UserRecordDeps): UserMap { | |
var recordWalker = function(value, key) { | |
switch (true) { | |
case key == 'profile': | |
return parseProfileRecord(value, deps); | |
default: return fromJSDefault(value); | |
} | |
}; | |
var result: any = {}; | |
for (var k in value) { | |
if (value.hasOwnProperty) { | |
result[k] = recordWalker(value[k], k); | |
} | |
} | |
return new deps.UserRecord(result); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface Profile { | |
firstName: string; | |
lastName: string; | |
} | |
export interface User { | |
profile: Profile; | |
login: string; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as models from './models-imm'; | |
export class ProfileRecord extends models.ProfileRecordCtor({ | |
firstName: null, | |
lastName: null | |
}) { | |
} | |
export class UserRecord extends models.UserRecordCtor({ | |
profile: new ProfileRecord(), | |
login: null | |
}) { | |
} | |
let allRecords = { | |
UserRecord, | |
ProfileRecord | |
} | |
let user = models.parseUserRecord({ | |
profile: { | |
firstName: 'Anakin', | |
lastName: 'Skywalker' | |
}, | |
login: 'anakin1990' | |
}, allRecords) | |
console.log(`${user.profile.firstName} ${user.profile.lastName}`) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment