I have a bit of React code that is yielding an error: The right-hand side of an 'in' expression must not be a primitive.. I am not sure how to properly resolve this:
// I want to allow null, string, object, arrays, etc as may be returned from a request type APIGatewaySuccessResponse = unknown ... const [data, setData] = useState<T>(null) ... const fetchData = async () => { onLoading() const data = await sendRequest<T>(route, options) // Checking if object is not enough to get rid of error.... if (typeof data === 'object' && 'error' in data) { setError(data.error) onError(data.error) } else { setData(data) onSuccess(data) } ... Adding the sendRequest code for clarity:
// Make api request export const sendRequest = async <T extends APIGatewaySuccessResponse>( route: string, options?: FetchOptions ): Promise<T | APIGatewayErrorResponse> => { const method = options?.method || FetchMethod.POST const body = options?.payload ? JSON.stringify(options.payload) : null const response = await fetch(route, { method, headers: { ... }, body }) const data = await response.json() if (response.ok) { return data as T } else { return data as APIGatewayErrorResponse } } Because I am passing a generic the in function throws this error. How can I address issue while maintaining a generic?
1 Answer
Well not sure what is going on. I've been reading up on this issue and it appears this example works for people: but it throws the error no matter what TS version I use.
I was however able to resolve it using a type guard:
export const isError = (response: any): response is APIGatewayErrorResponse => { return 'error' in response } And then:
const data = await sendRequest<T>(route, options) if (isError(data)) { setError(data.error) onError(data.error) } else { setData(data) onSuccess(data) }