Skip to content

Commit 8d7cd4f

Browse files
author
James Salas
committed
fix: typescript strict issues, remove many instances of any, fix minor bugs identified due to type mismatches
1 parent 7226462 commit 8d7cd4f

File tree

19 files changed

+79
-48
lines changed

19 files changed

+79
-48
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"@commitlint/config-conventional": "7.0.1",
5252
"@commitlint/prompt-cli": "7.0.0",
5353
"@types/jest": "23.1.6",
54+
"@types/webpack-env": "1.13.6",
5455
"babel-core": "6.26.3",
5556
"babel-jest": "23.4.2",
5657
"codelyzer": "4.5.0",

packages/example-app/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@angular/platform-browser": "^7.2.0",
2727
"@angular/platform-browser-dynamic": "^7.2.0",
2828
"@angular/router": "^7.2.0",
29+
"@types/webpack-env": "1.13.6",
2930
"core-js": "^2.6.2",
3031
"flux-standard-action": "^2.0.3",
3132
"ramda": "^0.23.0",

packages/example-app/src/app/animals/animal-list/component.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ export class AnimalListComponent {
1313
@Input() animalType!: string;
1414
@Input() animals!: Observable<Animal[]>;
1515
@Input() loading!: Observable<boolean>;
16-
@Input() error!: Observable<any>;
16+
@Input() error!: Observable<boolean>;
1717

1818
// Since we're observing an array of items, we need to set up a 'trackBy'
1919
// parameter so Angular doesn't tear down and rebuild the list's DOM every
2020
// time there's an update.
21-
getKey(_: any, animal: Animal) {
21+
getKey(_: unknown, animal: Animal) {
2222
return animal.id;
2323
}
2424
}

packages/example-app/src/app/animals/animal/reducers.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Action, Reducer } from 'redux';
2+
3+
import { Animal } from '../model';
24
import { ADD_TICKET, REMOVE_TICKET } from './actions';
35

46
export const ticketsReducer: Reducer<number> = (
@@ -15,10 +17,13 @@ export const ticketsReducer: Reducer<number> = (
1517
};
1618

1719
// Basic reducer logic.
18-
export const animalComponentReducer: Reducer<any> = (
19-
state: any = {},
20+
export const animalComponentReducer = (
21+
state: Animal | undefined,
2022
action: Action,
21-
): {} => ({
22-
...state,
23-
tickets: ticketsReducer(state.tickets, action),
24-
});
23+
) =>
24+
state
25+
? {
26+
...state,
27+
tickets: ticketsReducer(state.tickets, action),
28+
}
29+
: {};

packages/example-app/src/app/animals/api/actions.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { dispatch } from '@angular-redux/store';
22
import { Injectable } from '@angular/core';
33
import { FluxStandardAction } from 'flux-standard-action';
4-
import { Animal, AnimalType, LoadError } from '../model';
4+
5+
import { Animal, AnimalError, AnimalType } from '../model';
56

67
// Flux-standard-action gives us stronger typing of our actions.
7-
export type Payload = Animal[] | LoadError;
8+
export type Payload = Animal[] | AnimalError;
89

910
export interface MetaData {
1011
animalType: AnimalType;
@@ -44,8 +45,8 @@ export class AnimalAPIActions {
4445

4546
loadFailed = (
4647
animalType: AnimalType,
47-
error: LoadError,
48-
): AnimalAPIAction<LoadError> => ({
48+
error: AnimalError,
49+
): AnimalAPIAction<AnimalError> => ({
4950
type: AnimalAPIActions.LOAD_FAILED,
5051
meta: { animalType },
5152
payload: error,

packages/example-app/src/app/animals/api/epics.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { of } from 'rxjs';
55
import { catchError, filter, map, startWith, switchMap } from 'rxjs/operators';
66

77
import { AppState } from '../../store/model';
8-
import { Animal, AnimalType, LoadError } from '../model';
8+
import { Animal, AnimalError, AnimalType } from '../model';
99
import { AnimalAPIAction, AnimalAPIActions } from './actions';
1010
import { AnimalAPIService } from './service';
1111

@@ -37,8 +37,8 @@ export class AnimalAPIEpics {
3737
private createLoadAnimalEpic(
3838
animalType: AnimalType,
3939
): Epic<
40-
AnimalAPIAction<Animal[] | LoadError>,
41-
AnimalAPIAction<Animal[] | LoadError>,
40+
AnimalAPIAction<Animal[] | AnimalError>,
41+
AnimalAPIAction<Animal[] | AnimalError>,
4242
AppState
4343
> {
4444
return (action$, state$) =>

packages/example-app/src/app/animals/api/reducer.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AnimalAPIAction, AnimalAPIActions } from './actions';
77
const INITIAL_STATE: AnimalList = {
88
items: {},
99
loading: false,
10-
error: null,
10+
error: undefined,
1111
};
1212

1313
// A higher-order reducer: accepts an animal type and returns a reducer
@@ -28,14 +28,14 @@ export function createAnimalAPIReducer(animalType: AnimalType) {
2828
...state,
2929
items: {},
3030
loading: true,
31-
error: null,
31+
error: undefined,
3232
};
3333
case AnimalAPIActions.LOAD_SUCCEEDED:
3434
return {
3535
...state,
3636
items: indexBy(prop('id'), action.payload as Animal[]),
3737
loading: false,
38-
error: null,
38+
error: undefined,
3939
};
4040
case AnimalAPIActions.LOAD_FAILED:
4141
return {

packages/example-app/src/app/animals/model.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ export interface Animal {
1313
tickets: number;
1414
}
1515

16+
export interface AnimalResponse {
17+
name: string;
18+
type: AnimalType;
19+
ticketPrice: number;
20+
}
21+
1622
export interface AnimalList {
1723
items: {};
1824
loading: boolean;
19-
error: any;
25+
error: boolean | undefined;
2026
}
2127

22-
export interface LoadError {
28+
export interface AnimalError {
2329
status: string;
2430
}
2531

@@ -31,10 +37,10 @@ export function initialAnimalList(): AnimalList {
3137
};
3238
}
3339

34-
export const fromServer = (record: any): Animal => ({
40+
export const fromServer = (record: AnimalResponse): Animal => ({
3541
id: record.name.toLowerCase(),
36-
animalType: record.animalType,
42+
animalType: record.type,
3743
name: record.name,
3844
ticketPrice: record.ticketPrice || 0,
39-
tickets: record.tickets || 0,
45+
tickets: 0,
4046
});

packages/example-app/src/app/elephants/page.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Observable } from 'rxjs';
1010
import { toArray } from 'rxjs/operators';
1111

1212
import { AnimalAPIActions } from '../animals/api/actions';
13-
import { ANIMAL_TYPES } from '../animals/model';
13+
import { Animal, ANIMAL_TYPES } from '../animals/model';
1414
import { ElephantPageComponent } from './page';
1515

1616
@Component({
@@ -19,9 +19,9 @@ import { ElephantPageComponent } from './page';
1919
})
2020
class MockAnimalListComponent {
2121
@Input() animalsName!: string;
22-
@Input() animals!: Observable<any>;
22+
@Input() animals!: Observable<Animal[]>;
2323
@Input() loading!: Observable<boolean>;
24-
@Input() error!: Observable<any>;
24+
@Input() error!: Observable<boolean>;
2525
}
2626

2727
describe('Elephant Page Container', () => {

packages/example-app/src/app/elephants/page.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ import { map } from 'rxjs/operators';
88
import { AnimalAPIActions } from '../animals/api/actions';
99
import { Animal, ANIMAL_TYPES } from '../animals/model';
1010

11-
export const sortAnimals = (animalDictionary$: Observable<{}>) =>
12-
animalDictionary$.pipe(
11+
export function sortAnimals(animalDictionary$: Observable<{}>) {
12+
return animalDictionary$.pipe(
1313
map(
1414
pipe(
1515
values,
1616
sortBy(prop('name')),
1717
),
1818
),
1919
);
20+
}
2021

2122
@Component({
2223
templateUrl: './page.html',
@@ -31,7 +32,7 @@ export class ElephantPageComponent {
3132
readonly loading!: Observable<boolean>;
3233

3334
@select(['elephant', 'error'])
34-
readonly error!: Observable<any>;
35+
readonly error!: Observable<boolean>;
3536

3637
constructor(actions: AnimalAPIActions) {
3738
actions.loadAnimals(ANIMAL_TYPES.ELEPHANT);

packages/example-app/src/app/lions/page.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Observable } from 'rxjs';
1010
import { toArray } from 'rxjs/operators';
1111

1212
import { AnimalAPIActions } from '../animals/api/actions';
13-
import { ANIMAL_TYPES } from '../animals/model';
13+
import { Animal, ANIMAL_TYPES } from '../animals/model';
1414
import { LionPageComponent } from './page';
1515

1616
@Component({
@@ -19,9 +19,9 @@ import { LionPageComponent } from './page';
1919
})
2020
class MockAnimalListComponent {
2121
@Input() animalsName!: string;
22-
@Input() animals!: Observable<any>;
22+
@Input() animals!: Observable<Animal[]>;
2323
@Input() loading!: Observable<boolean>;
24-
@Input() error!: Observable<any>;
24+
@Input() error!: Observable<boolean>;
2525
}
2626

2727
describe('Lion Page Container', () => {

packages/example-app/src/app/lions/page.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ import { map } from 'rxjs/operators';
77
import { AnimalAPIActions } from '../animals/api/actions';
88
import { Animal, ANIMAL_TYPES } from '../animals/model';
99

10-
export const sortAnimals = (animalDictionary: Observable<{}>) =>
11-
animalDictionary.pipe(
10+
export function sortAnimals(animalDictionary: Observable<{}>) {
11+
return animalDictionary.pipe(
1212
map(() =>
1313
pipe(
1414
values,
1515
sortBy(prop('name')),
1616
),
1717
),
1818
);
19+
}
1920

2021
@Component({
2122
templateUrl: './page.html',
@@ -30,7 +31,7 @@ export class LionPageComponent {
3031
readonly loading!: Observable<boolean>;
3132

3233
@select(['lion', 'error'])
33-
readonly error!: Observable<any>;
34+
readonly error!: Observable<boolean>;
3435

3536
constructor(actions: AnimalAPIActions) {
3637
actions.loadAnimals(ANIMAL_TYPES.LION);

packages/example-app/src/app/store/model.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { AnimalList, AnimalType, initialAnimalList } from '../animals/model';
22

33
export type AppState = { [key in AnimalType]: AnimalList } &
44
Partial<{
5-
routes: any;
6-
feedback: any;
5+
routes: string;
6+
feedback: unknown;
77
}>;
88

99
export function initialAppState() {

packages/example-app/src/app/store/module.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import {
55
} from '@angular-redux/store/testing';
66
import { async, getTestBed, TestBed } from '@angular/core/testing';
77
import { RootEpics } from './epics';
8+
import { AppState } from './model';
89
import { StoreModule } from './module';
910

1011
describe('Store Module', () => {
11-
let mockNgRedux: NgRedux<any>;
12+
let mockNgRedux: NgRedux<AppState>;
1213
let devTools: DevToolsExtension;
1314
let mockEpics: Partial<RootEpics>;
1415

packages/example-app/src/app/store/reducers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const elephant = createAnimalAPIReducer(ANIMAL_TYPES.ELEPHANT);
99
// Define the global store shape by combining our application's
1010
// reducers together into a given structure.
1111
export const rootReducer = composeReducers(
12-
defaultFormReducer<any>(),
12+
defaultFormReducer<unknown>(),
1313
combineReducers({
1414
elephant,
1515
lion: createAnimalAPIReducer(ANIMAL_TYPES.LION),

packages/example-app/src/tsconfig.spec.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"extends": "../tsconfig.json",
33
"compilerOptions": {
44
"outDir": "../out-tsc/spec",
5-
"types": ["jasmine", "node"]
5+
"types": ["jasmine", "node", "webpack-env"]
66
},
77
"files": ["test.ts", "polyfills.ts"],
88
"include": ["**/*.spec.ts", "**/*.d.ts"]

packages/store/src/components/root-store.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ export class RootStore<RootState> extends NgRedux<RootState> {
5151
): void => {
5252
assert(!this.store, 'Store already configured!');
5353
// Variable-arity compose in typescript FTW.
54-
this.setStore(compose<StoreCreator>(
55-
applyMiddleware(...middleware),
54+
this.setStore(
55+
compose<StoreCreator>(
56+
applyMiddleware(...middleware),
5657
...enhancers,
57-
)(createStore)
58-
(enableFractalReducers(rootReducer), initState),
58+
)(createStore)(enableFractalReducers(rootReducer), initState),
5959
);
6060
};
6161

packages/store/src/decorators/dispatch.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Action } from 'redux';
2+
13
import { NgRedux } from '../components/ng-redux';
24
import { getBaseStore } from './helpers';
35

@@ -13,11 +15,14 @@ export function dispatch(): PropertyDecorator {
1315
key: string | symbol | number,
1416
descriptor?: PropertyDescriptor,
1517
): PropertyDescriptor {
16-
let originalMethod: () => void;
18+
let originalMethod: () => Action;
1719

18-
const wrapped = function(this: any, ...args: any) {
19-
const result = originalMethod.apply(this, args);
20-
if (result !== false) {
20+
const wrapped = function(this: unknown, ...args: unknown[]) {
21+
const result = originalMethod.apply<unknown, unknown[], Action>(
22+
this,
23+
args,
24+
);
25+
if (result !== undefined) {
2126
const store = getBaseStore(this) || NgRedux.instance;
2227
if (store) {
2328
store.dispatch(result);
@@ -27,6 +32,7 @@ export function dispatch(): PropertyDecorator {
2732
};
2833

2934
descriptor = descriptor || Object.getOwnPropertyDescriptor(target, key);
35+
3036
if (descriptor === undefined) {
3137
const dispatchDescriptor: PropertyDescriptor = {
3238
get: () => wrapped,
@@ -41,3 +47,6 @@ export function dispatch(): PropertyDecorator {
4147
}
4248
};
4349
}
50+
// get descriptor
51+
// if no descriptor, create one with getter setter
52+
// if descriptor, set original method to descriptor, and then bind the wrapped function instead

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,11 @@
12551255
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
12561256
integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==
12571257

1258+
1259+
version "1.13.6"
1260+
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.6.tgz#128d1685a7c34d31ed17010fc87d6a12c1de6976"
1261+
integrity sha512-5Th3OsZ4gTRdr9Mho83BQ23cex4sRhOR4XTG+m+cJc0FhtUBK9Vn62hBJ+pnQYnSxoPOsKoAPOx6FcphxBC8ng==
1262+
12581263
"@types/webpack-sources@^0.1.5":
12591264
version "0.1.5"
12601265
resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.5.tgz#be47c10f783d3d6efe1471ff7f042611bd464a92"

0 commit comments

Comments
 (0)