Reputation: 2374
I have this code in my effect/store:
@Effect() newMessages$ = Observable.interval(5000)
.withLatestFrom(this.store.select("uiState"))
.map(([unreadMessages, uiState]) => new NewMessagesReceivedAction({
unreadMessages,
currentThreadId: uiState.currentThreadId,
currentUserId: uiState.currentUserId
}))
Webstorm warns me that:
Property 'currentThreadId' does not exist on type '{}'.
And here is my store file:
export interface ApplicationState {
uiState: UiState,
storeData: StoreData
}
export const INITIAL_APPLICATION_STATE: ApplicationState = {
uiState: INITIAL_UI_STATE,
storeData: INITIAL_STORE_DATA
}
And here is my uistate file:
export interface UiState {
userId: string;
currentThreadId: string;
}
export const INITIAL_UI_STATE: UiState = {
userId: undefined,
currentThreadId: undefined
}
Anyone know why?
UPDATE:
After @cartant suggestion I updated the code of the @Effect() as below, and I ran into another Webstorm Typescirpt error:
@Effect() newMessages$ = Observable.interval(5000)
.withLatestFrom(this.store.select<UiState>("uiState"))
.map(([any,uiState]) => uiState)
.filter(uiState => uiState.userId) //Error right here --- As I need to filter out the uiState.userId when there is no userId when the store initialized with undefined value.
.switchMap(uiState => this.threadsService.loadNewMessagesForUser(uiState.userId))
.withLatestFrom(this.store.select<UiState>("uiState"))
.map(([unreadMessages, uiState]) => new NewMessagesReceivedAction({
unreadMessages,
currentThreadId: uiState.currentThreadId,
currentUserId: uiState.userId
}))
Argument of type '(uiState: UiState) => string' is not assignable to parameter of type '(value: UiState, index: number) => boolean'. Type 'string' is not assignable to type 'boolean'.)
I need a way to filter out the initial state or any empty userId situation to make sure I do not pass in undefined or null into Firebase call.
Upvotes: 1
Views: 3131
Reputation: 58400
The problem lies with this bit of code:
this.store.select("uiState")
The select
operator extracts the named property from the store's state and emits its value. However, TypeScript has no way of inferring the type of that property. To solve the problem you can specify the type explicitly via the type variable:
this.store.select<UiState>("uiState")
Regarding this line in your amended question:
.filter(uiState => uiState.userId)
The filter
operator takes a predicate that is supposed to return a boolean
and you are returning userId
, which is a string
. There is no implicit TypeScript conversion, so you need to be explicit:
.filter(uiState => Boolean(uiState.userId))
Upvotes: 3