UNPKG

@reduxjs/toolkit

Version:

The official, opinionated, batteries-included toolset for efficient Redux development

612 lines (549 loc) 20.3 kB
import type { SerializedError } from '@reduxjs/toolkit' import type { FetchBaseQueryError, TypedUseQueryHookResult, TypedUseQueryStateResult, TypedUseQuerySubscriptionResult, TypedUseMutationResult, } from '@reduxjs/toolkit/query/react' import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { expectExactType, expectType } from './helpers' const baseQuery = fetchBaseQuery() const api = createApi({ baseQuery, endpoints: (build) => ({ test: build.query<string, void>({ query: () => '' }), mutation: build.mutation<string, void>({ query: () => '' }), }), }) describe.skip('TS only tests', () => { test('query selector union', () => { const result = api.endpoints.test.select()({} as any) if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) } if (result.isLoading) { expectExactType('' as string | undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('useQuery union', () => { const result = api.endpoints.test.useQuery() if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isLoading) { expectExactType(undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as boolean)(result.isFetching) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as boolean)(result.isFetching) } if (result.isFetching) { expectExactType('' as string | undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as boolean)(result.isLoading) expectExactType(false as boolean)(result.isSuccess) expectExactType(false as false)(result.isError) } expectExactType('' as string | undefined)(result.currentData) // @ts-expect-error expectExactType('' as string)(result.currentData) if (result.isSuccess) { if (!result.isFetching) { expectExactType('' as string)(result.currentData) } else { expectExactType('' as string | undefined)(result.currentData) // @ts-expect-error expectExactType('' as string)(result.currentData) } } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('useQuery TS4.1 union', () => { const result = api.useTestQuery() if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isLoading) { expectExactType(undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as boolean)(result.isFetching) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as boolean)(result.isFetching) } if (result.isFetching) { expectExactType('' as string | undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as boolean)(result.isLoading) expectExactType(false as boolean)(result.isSuccess) expectExactType(false as false)(result.isError) } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('useLazyQuery union', () => { const [_trigger, result] = api.endpoints.test.useLazyQuery() if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isLoading) { expectExactType(undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as boolean)(result.isFetching) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as boolean)(result.isFetching) } if (result.isFetching) { expectExactType('' as string | undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as boolean)(result.isLoading) expectExactType(false as boolean)(result.isSuccess) expectExactType(false as false)(result.isError) } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('useLazyQuery TS4.1 union', () => { const [_trigger, result] = api.useLazyTestQuery() if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isLoading) { expectExactType(undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) expectExactType(false as boolean)(result.isFetching) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) expectExactType(false as false)(result.isFetching) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as boolean)(result.isFetching) } if (result.isFetching) { expectExactType('' as string | undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as boolean)(result.isLoading) expectExactType(false as boolean)(result.isSuccess) expectExactType(false as false)(result.isError) } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('queryHookResult (without selector) union', async () => { const useQueryStateResult = api.endpoints.test.useQueryState() const useQueryResult = api.endpoints.test.useQuery() const useQueryStateWithSelectFromResult = api.endpoints.test.useQueryState( undefined, { selectFromResult: () => ({ x: true }), } ) const { refetch, ...useQueryResultWithoutMethods } = useQueryResult expectExactType(useQueryStateResult)(useQueryResultWithoutMethods) expectExactType(useQueryStateWithSelectFromResult)( // @ts-expect-error useQueryResultWithoutMethods ) expectType<ReturnType<ReturnType<typeof api.endpoints.test.select>>>( await refetch() ) }) test('useQueryState (with selectFromResult)', () => { const result = api.endpoints.test.useQueryState(undefined, { selectFromResult({ data, isLoading, isFetching, isError, isSuccess, isUninitialized, }) { return { data: data ?? 1, isLoading, isFetching, isError, isSuccess, isUninitialized, } }, }) expectExactType({ data: '' as string | number, isUninitialized: false, isLoading: true, isFetching: true, isSuccess: false, isError: false, })(result) }) test('useQuery (with selectFromResult)', async () => { const { refetch, ...result } = api.endpoints.test.useQuery(undefined, { selectFromResult({ data, isLoading, isFetching, isError, isSuccess, isUninitialized, }) { return { data: data ?? 1, isLoading, isFetching, isError, isSuccess, isUninitialized, } }, }) expectExactType({ data: '' as string | number, isUninitialized: false, isLoading: true, isFetching: true, isSuccess: false, isError: false, })(result) expectType<ReturnType<ReturnType<typeof api.endpoints.test.select>>>( await refetch() ) }) test('useMutation union', () => { const [_trigger, result] = api.endpoints.mutation.useMutation() if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) } if (result.isLoading) { expectExactType(undefined as undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('useMutation (with selectFromResult)', () => { const [_trigger, result] = api.endpoints.mutation.useMutation({ selectFromResult({ data, isLoading, isError, isSuccess, isUninitialized, }) { return { data: data ?? 'hi', isLoading, isError, isSuccess, isUninitialized, } }, }) expectExactType({ data: '' as string, isUninitialized: false, isLoading: true, isSuccess: false, isError: false, reset: () => {}, })(result) }) test('useMutation TS4.1 union', () => { const [_trigger, result] = api.useMutationMutation() if (result.isUninitialized) { expectExactType(undefined)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) } if (result.isLoading) { expectExactType(undefined as undefined)(result.data) expectExactType( undefined as SerializedError | FetchBaseQueryError | undefined )(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isError) expectExactType(false as false)(result.isSuccess) } if (result.isError) { expectExactType('' as string | undefined)(result.data) expectExactType({} as SerializedError | FetchBaseQueryError)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isSuccess) } if (result.isSuccess) { expectExactType('' as string)(result.data) expectExactType(undefined)(result.error) expectExactType(false as false)(result.isUninitialized) expectExactType(false as false)(result.isLoading) expectExactType(false as false)(result.isError) } // @ts-expect-error expectType<never>(result) // is always one of those four if ( !result.isUninitialized && !result.isLoading && !result.isError && !result.isSuccess ) { expectType<never>(result) } }) test('"Typed" helper types', () => { // useQuery { const result = api.endpoints.test.useQuery() expectType<TypedUseQueryHookResult<string, void, typeof baseQuery>>( result ) } // useQuery with selectFromResult { const result = api.endpoints.test.useQuery(undefined, { selectFromResult: () => ({ x: true }), }) expectType< TypedUseQueryHookResult<string, void, typeof baseQuery, { x: boolean }> >(result) } // useQueryState { const result = api.endpoints.test.useQueryState() expectType<TypedUseQueryStateResult<string, void, typeof baseQuery>>( result ) } // useQueryState with selectFromResult { const result = api.endpoints.test.useQueryState(undefined, { selectFromResult: () => ({ x: true }), }) expectType< TypedUseQueryStateResult<string, void, typeof baseQuery, { x: boolean }> >(result) } // useQuerySubscription { const result = api.endpoints.test.useQuerySubscription() expectType< TypedUseQuerySubscriptionResult<string, void, typeof baseQuery> >(result) } // useMutation { const [trigger, result] = api.endpoints.mutation.useMutation() expectType<TypedUseMutationResult<string, void, typeof baseQuery>>(result) } }) })