stampit-org / stampit

OOP is better with stamps: Composable object factories.
https://stampit.js.org
MIT License
3.02k stars 102 forks source link

[SOLVED] How to express stampit factories and instances in typescript #339

Closed moranje closed 5 years ago

moranje commented 5 years ago

I'm trying to express the result composed Stamp in typescript.

import stampit from "stampit";

/**
 * Type Definitions
 */

// Instance
interface ValueInstance {
  value: any
}

// Factory
interface Value extends stampit.Stamp { // This is important
  ({ value }: { value: any }): ValueInstance
}

// Instance
interface ReadableInstance extends ValueInstance {
  read(): any
}

// Factory
interface Readable extends Value {
  ({ value }: { value: any }): ReadableInstance
}

// Instance
interface WritableInstance extends ReadableInstance {
  write(value: string): void
}

// Factory
interface Writable extends Readable {
  ({ value }: { value: any }): WritableInstance
}

/**
 * Code
 */

const Value: Value = stampit({
  init({value}: { value: any }) {
    this.value = value
  }
})

const Readable: Readable = stampit(Value, {
  methods: {
    read() {
      return this.value
    }
  }
})

const Writable: Writable = stampit(Readable, {
  methods: {
    write(value: any) {
      this.value = value
    }
  }
})

let machine: WritableInstance = Writable({ value: 41 })

// machine. => suggest `.value`, `.read()` an `.write()`

Leaving this here for documentation purposes.

Martien

kuncevic commented 5 years ago

That is the tricky one but you can try to talk on that matter at https://gitter.im/Microsoft/TypeScript

danielkcz commented 5 years ago

Yea, full-blown Typescript support missing for stamps is something that forced me to leave this concept when I started using TypeScript. Unfortunately, I am not that well versed in these advanced and dynamic types to figure out how it should work. Perhaps there might be some inspiration in mobx-state-tree which is written in TypeScript and does these kinds of crazy compositions. It's not perfect either, but it mostly works.

moranje commented 5 years ago

I've updated the example because figured out that stampit() returns a factory function and the factory function returns an instance. That only partly solves my problem it seems...

moranje commented 5 years ago

I've figured it out, I'm closing this but I have adjusted the example for future reference.

Martien