type Constructor = new(...args: any[]) => T interface CustomElement { connectedCallback?(): void disconnectedCallback?(): void readonly isConnected: boolean } interface Store { getState(): S subscribe(listener: () => void): () => void } export const connectMixin = (store: Store) => >(baseElement: T) => class extends baseElement { _storeUnsubscribe!: () => void _storeState: S = store.getState() connectedCallback() { if (super.connectedCallback) super.connectedCallback() this._storeState = store.getState() this._storeUnsubscribe = store.subscribe(() => { const newState = store.getState() if (newState !== this._storeState) { this._storeState = newState this.stateChanged(this._storeState) } }) } disconnectedCallback() { this._storeUnsubscribe() if (super.disconnectedCallback) super.disconnectedCallback() } stateChanged(_state: S) {} }