Skip to content

Instantly share code, notes, and snippets.

@mattboldt
Created January 30, 2020 16:53
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 mattboldt/b2a7ec535f7429ad041b161a3c9e2ebf to your computer and use it in GitHub Desktop.
Save mattboldt/b2a7ec535f7429ad041b161a3c9e2ebf to your computer and use it in GitHub Desktop.
TypeScript OOP Bullshit
class MapProxy {
public map = new Map<string, any>()
keys() {
return this.map.keys()
}
values() {
return this.map.values()
}
get(key: string) {
return this.map.get(key)
}
set(key: string, value: any) {
return this.map.set(key, value)
}
has(key: string) {
return this.map.has(key)
}
}
class ActiveModel extends MapProxy {
public actions: { [key: string]: any } = {}
constructor(options: { [key: string]: any } = {}) {
super()
for (let k of Object.keys(options)) {
this.set(k, options[k])
}
this.set('actions', this.actions)
this[Symbol.iterator] = function*(i) {
yield this.keys()[i]
yield this.get(i)
}
}
send(key: string, arg: any = null): any {
if (arg) {
return this.actions[key](arg)
}
return this.actions[key]()
}
bind(functions: string[], context: any) {
for (let key of functions) {
if (!this.map.has(key)) {
this.set(key, context[key])
}
}
}
get body() {
const obj: any = {}
for (let k of this.keys()) {
obj[k] = this.get(k)
}
return obj
}
}
export default ActiveModel
import ActiveModel from './model'
interface IPerson {
[index: number]: IPerson
email: string
name?: string
friends?: Array<Person>
greet?: Function
}
class Person extends ActiveModel {
constructor(params: IPerson) {
super(params)
}
actions = {
greet: () => `Hello ${this.get('name')}`,
}
}
const friend = new Person({
name: 'Bender',
email: 'bender@destroyallhumans.com',
friends: [
new Person({
name: 'Fry',
email: 'fry@planetexpress.com',
}),
],
})
// console.table(friend.body)
// console.log(friend.send('greet'))
// console.log(friend.get('friends'))
const friend2 = new Person({
name: 'Bender',
email: 'bender@destroyallhumans.com',
greet: (arg: string) => `Hello ${arg}`,
})
// console.log(friend2.get('greet')('Matt'))
const state = new ActiveModel({
myInput: 'Hello Input',
})
const nodes = new ActiveModel()
setInterval(() => {
const add = (args: any) => nodes.set(args['key'], createElement(args))
const createElement = ({ key, tag, content, children = [], ...options }) => {
let el
if (nodes.has(key)) {
el = nodes.get(key)
el.replaceWith(document.createTextNode(content))
} else {
el = document.createElement(tag)
el.appendChild(document.createTextNode(content))
}
for (let key of Object.keys(options)) {
el[key] = options[key]
}
for (let child of children) {
el.appendChild(createElement(child))
}
return el
}
const main = add({
key: '0',
tag: 'div',
content: 'Hello',
children: [
{
key: '1',
tag: 'p',
content: state.get('myInput'),
},
{
key: '2',
tag: 'button',
content: 'Click Me',
style: 'padding: 10px; background: #fff',
onclick: () => {
console.log('Clicked')
},
},
{
key: '3',
tag: 'blockquote',
content: 'This is a quote',
},
{
key: '4',
tag: 'input',
type: 'text',
value: state.get('myInput'),
onkeyup: e => state.set('myInput', e.target.value),
},
],
})
const app = document.createElement('div')
app.id = 'root'
for (let [k, v] of nodes) {
app.appendChild(node)
}
document.getElementById('root').replaceWith(app)
}, 1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment