Skip to content

Instantly share code, notes, and snippets.

@garthk
Last active June 8, 2016 02:07
Show Gist options
  • Save garthk/7fdd73f60fa9fe87af843ca7637cdf53 to your computer and use it in GitHub Desktop.
Save garthk/7fdd73f60fa9fe87af843ca7637cdf53 to your computer and use it in GitHub Desktop.
TypeScript Augmentation Challenge
node_modules/
typings/
dist/

TypeScript Augmentation Challenge

Usage: npm install && npm test

Goal: remove as any from this line in example.ts:

store.dispatch(thunkedAction(1) as any);

Good luck!

Trying to augment the module as below masks the type information from node_modules/redux/index.d.ts, leading to errors importing Middleware and Dispatch from redux because they no longer exist:

// add to redux-thunk.d.ts
// or put in its own .d.ts file:
declare module 'redux' {
    export interface Dispatch<S> {
        <R>(thunkAction: ThunkInterface<R>): R;
    }
}
import { applyMiddleware, createStore, combineReducers, Reducer, Store, Action } from 'redux';
import thunkMiddleware, { ThunkInterface } from 'redux-thunk';
type BoringState = {
value: number;
}
type ValueAction = {
type: string;
payload: number;
}
function reducer(state: BoringState, action: Action): BoringState {
if (action.type === 'VALUE_SET') {
return { value: (action as any).payload };
} else {
return state;
}
};
function thunkedAction(value: number): ThunkInterface<ValueAction> {
return dispatch => dispatch({ type: 'VALUE_SET', payload: value });
}
const store: Store<BoringState> = createStore(reducer, applyMiddleware(thunkMiddleware));
store.dispatch(thunkedAction(1) as any); // GOAL: remove 'as any' cheat
console.log(thunkedAction(2)(store.dispatch).type);
console.log('state:', store.getState());
{
"name": "example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"react": "^15.1.0",
"redux": "^3.5.2",
"redux-thunk": "^2.1.0"
},
"devDependencies": {
"rimraf": "^2.5.2",
"typescript": "^1.8.10",
"typings": "^1.0.4"
},
"scripts": {
"clean": "rimraf typings dist",
"pretest": "typings install && tsc",
"test": "node dist/example.js"
},
"author": "",
"license": "ISC"
}
declare module "redux-thunk" {
import { Middleware, Dispatch } from 'redux';
export interface Thunk extends Middleware {}
export interface ThunkInterface<R> {
<S>(dispatch: Dispatch<S>, getState?: () => S): R;
}
var thunk: Thunk;
export default thunk;
}
{
"version": "1.8.10",
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"jsx": "react",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"sourceMap": true,
"target": "es5"
},
"exclude": [
"dist",
"node_modules"
],
"compileOnSave": false
}
{
"name": "example",
"dependencies": {
"react-redux": "registry:npm/react-redux#4.4.0+20160207114942"
},
"globalDependencies": {
"react": "registry:dt/react#0.14.0+20160602151522"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment