Skip to content

Commit

Permalink
Add types for current Observable interpolation interface (#3067)
Browse files Browse the repository at this point in the history
* Add types about Observable interpolation

* Run through Prettier

* Also run through Prettier
  • Loading branch information
pinyin authored and timdorr committed Mar 19, 2019
1 parent 9827e2d commit 4fb7a44
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
36 changes: 36 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/// <reference types="symbol-observable" />

/**
* An *action* is a plain object that represents an intention to change the
* state. Actions are the only way to get data into the store. Any data,
Expand Down Expand Up @@ -129,6 +131,32 @@ export interface Unsubscribe {
(): void
}

/**
* A minimal observable of state changes.
* For more information, see the observable proposal:
* https://github.com/tc39/proposal-observable
*/
export type Observable<T> = {
/**
* The minimal observable subscription method.
* @param {Object} observer Any object that can be used as an observer.
* The observer object should have a `next` method.
* @returns {subscription} An object with an `unsubscribe` method that can
* be used to unsubscribe the observable from the store, and prevent further
* emission of values from the observable.
*/
subscribe: (observer: Observer<T>) => { unsubscribe: Unsubscribe }
[Symbol.observable](): Observable<T>
}

/**
* An Observer is used to receive data from an Observable, and is supplied as
* an argument to subscribe.
*/
export type Observer<T> = {
next?(value: T): void
}

/**
* A store is an object that holds the application's state tree.
* There should only be a single store in a Redux app, as the composition
Expand Down Expand Up @@ -209,6 +237,14 @@ export interface Store<S = any, A extends Action = AnyAction> {
* @param nextReducer The reducer for the store to use instead.
*/
replaceReducer(nextReducer: Reducer<S, A>): void

/**
* Interoperability point for observable/reactive libraries.
* @returns {observable} A minimal observable of state changes.
* For more information, see the observable proposal:
* https://github.com/tc39/proposal-observable
*/
[Symbol.observable](): Observable<S>
}

export type DeepPartial<T> = {
Expand Down
16 changes: 15 additions & 1 deletion test/typescript/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
StoreEnhancer,
StoreCreator,
StoreEnhancerStoreCreator,
Unsubscribe
Unsubscribe,
Observer
} from 'redux'
import 'symbol-observable'

type State = {
a: 'a'
Expand Down Expand Up @@ -101,3 +103,15 @@ unsubscribe()
const newReducer: Reducer<State> = reducer

store.replaceReducer(newReducer)

/* observable */

let observable = store[Symbol.observable]()
observable = observable[Symbol.observable]()
const observer: Observer<State> = {
next(state: State) {
console.log('current state:', state)
}
}
const unsubscribeFromObservable = observable.subscribe(observer).unsubscribe
unsubscribeFromObservable()

0 comments on commit 4fb7a44

Please sign in to comment.