Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@s-panferov
Created August 1, 2015 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s-panferov/722dad3103b5e9a8e4d9 to your computer and use it in GitHub Desktop.
Save s-panferov/722dad3103b5e9a8e4d9 to your computer and use it in GitHub Desktop.
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);
}
export interface Profile {
firstName: string;
lastName: string;
}
export interface User {
profile: Profile;
login: string;
}
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