I am facing an issue with a function that is supposed to return NetworkState
. However, despite the code clearly showing that the function does not return the correct type in most cases, TypeScript does not flag any errors. Can someone point out what I might be missing?
SECOND UPDATE: I appreciate all the feedback provided by everyone. I have tried to simplify and condense the code as much as possible, making it easy to copy and paste into TypeScript playground. Unfortunately, due to the need to include ALL types to replicate the problem, the code ended up being longer than anticipated. Please pay attention to the last line where I suspect there should be an error (based on the return type), but none is raised.
Any assistance would be greatly valued. Thank you.
UPDATE and clarification:
Example 1:
const someFunction = (): string => 45
The above function specifies a return type of string
, yet it returns a number, triggering a TypeScript error:
Type '45' is not assignable to type 'string'
Example 2:
type MyType = {
[key: string]: string | undefined
}
const someFunction = (): MyType => 45
This function sets the return type as MyType
, but it actually returns a number, leading TypeScript to raise an error:
Type '45' is not assignable to type 'MyType'
The issue with the following code:
In the example below, the networkStateReducer
is expected to output data of type NetworkState
. Despite returning data that does not comply with NetworkState
, no error is flagged.
Looking at the first case
closely, for instance:
case NetworkActionType.Failure:
return { ...state, [action.payload.sagaAction]: 'SHOULD_BE_ERROR' }
If we assume that the state
begins as an empty object, the returned value is:
[action.payload.sagaAction]
which equals a string, however, the definition clearly expects an object:
[key in NetworkSagaAction]?: {
networkError?: Error
networkStatus: NetworkStatus
}
Despite this, TypeScript does not throw any errors.
The actual implementation:
export type NetworkSagaAction = 'Login' | 'Logout'
export type NetworkStatus = 'idle' | 'pending' | 'failure' | 'success'
export enum NetworkActionType {
Busy = 'Network/Busy',
Failure = 'Network/Failure',
Idle = 'Network/Idle',
Reset = 'Network/Reset',
Success = 'Network/Success',
}
export type NetworkState = {
[key in NetworkSagaAction]?: {
error?: Error
networkStatus: NetworkStatus
}
}
export interface NetworkPayload {
sagaAction: NetworkSagaAction
}
export const initialState: NetworkState = {}
type FunctionType = (...args: any[]) => any
interface ActionCreatorsMapObject {
[actionCreator: string]: FunctionType
}
export type ActionsUnion<A extends ActionCreatorsMapObject> = ReturnType<A[keyof A]>
export interface Action<T extends string> {
type: T
}
export interface ActionWithPayload<T extends string, P> extends Action<T> {
payload: P
}
export type BusyAction = ActionWithPayload<NetworkActionType.Busy, NetworkPayload>
export function createAction<T extends string, P>(type: T, payload: P): ActionWithPayload<T, P>
export function createAction<T extends string, P>(type: T, payload?: P) {
return payload === undefined ? { type } : { type, payload }
}
export type NetworkActions = ActionsUnion<typeof NetworkActions>
export const NetworkActions = {
busy: (payload: NetworkPayload): BusyAction => createAction(NetworkActionType.Busy, payload),
}
const networkStateReducer = (
state = initialState,
action: NetworkActions,
): NetworkState => {
return {
[action.payload.sagaAction]: 'THIS SHOULD BE OBJECT BUT NOT AND STILL NO TYPE ERROR'
}
}