hotwired / stimulus

A modest JavaScript framework for the HTML you already have

Home Page:https://stimulus.hotwired.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypedStimulusController - some Typescript love :)

ajaishankar opened this issue · comments

Hi

Have been playing with Stimulus, and came up with this sample that can automatically type the values, targets, outlets...

Would there be any interest in including a full implementation of this as part of Stimulus or would it be more suited as a separate package?

type Statics<Values extends object> = {
    values?: Values
}

function TypedStimulusController<Values extends object>(statics: Statics<Values>) {
    return class extends StimulusController {
        static values = statics.values
        constructor(context: Context) {
            super(context)
        }
    } as unknown as {
        new (context: Context): StimulusController & TypedValues<Values>
    }
}

type TypedValues<Values extends object> = {
    [K in keyof Values as `${K & string}Value`]:
        Values[K] extends NumberConstructor ? number
        : Values[K] extends StringConstructor ? string
        : unknown
}

const values = {
    url: String,
    interval: Number
}

class LoaderController extends TypedStimulusController({ values }) {
    connect() {
        fetch(this.urlValue).then(/* … */)
    }
}

class Context {}

class StimulusController {
    constructor(context: Context) {}
}

This will let Typescript users avoid having to manually override the types

  declare urlValue: string
  declare readonly hasUrlValue: boolean

See similar issue here: #723

I took a look at this and made some improvements (support default values) but was unable to make it work as well for targets and outlets

TypeScript has already been removed from Turbo and I would not be surprised if it is removed from Stimulus soon

Removed as in...? Stimulus itself is written in Typescript.

Yes, but it will probably switch to JavaScript soon, just like Turbo did a few weeks ago

Got it.

Even if the implementation switches to Javascript (for whatever reason), the type definitions would be published.

Anyway what I proposed is a nicety for the end typescript users, and can definitely live outside Stimulus as a separate package.