/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment */ import React from 'react'; import { batch, createStore, createContainer, createSubscriber, createHook, createActionsHook, createStateHook, StoreActionApi, Action, } from 'react-sweet-state'; /** * Store types tests */ type State = { count: number }; type Actions = typeof actions; type SelectorProps = { min: number }; let Test; const actionsGeneric = { // setState tests increment: (n: number): Action => ({ setState }) => { // @ts-expect-error Ensure store type setState(''); // @ts-expect-error Ensure store shape setState({ foo: 1 }); // Correct setState({ count: 2, }); return ''; }, // GetState tests decrement: (): Action => ({ setState, getState }) => { const state = getState(); // @ts-expect-error Ensure property exists const bla = state.bla; // @ts-expect-error Ensure readonly state.count = 1; // correct const { count } = state; return count; }, fetch: (): Action> => async () => { return ''; }, // Dispatch tests setTitle: (title: string): Action => ({ dispatch }) => { const v0 = dispatch(actions.decrement()); // @ts-expect-error Ensure action type dispatch(actions.increment()); // @ts-expect-error Ensure action arg type dispatch(actions.increment('1')); // @ts-expect-error Ensure action arg length dispatch(actions.increment(1, 'foo')); // @ts-expect-error Ensure action return type dispatch(actions.decrement()).then(); // @ts-expect-error Ensure action return type v0.split(''); // Correct batch(() => dispatch(actions.decrement())); dispatch(actions.increment(1)); dispatch(actions.fetch()).then((v) => v.split('')); v0 + 1; }, }; const actions = { // setState tests increment: (n: number) => ({ setState }: StoreActionApi) => { // @ts-expect-error Ensure store type setState(''); // @ts-expect-error Ensure store shape setState({ foo: 1 }); // Correct setState({ count: 2, }); return ''; }, // GetState tests decrement: () => ({ setState, getState }: StoreActionApi) => { const state = getState(); // @ts-expect-error Ensure property exists const bla = state.bla; // @ts-expect-error Ensure readonly state.count = 1; // correct const { count } = state; return count; }, fetch: () => async (): Promise => { return ''; }, // Dispatch tests setTitle: (title: string) => ({ dispatch }: StoreActionApi) => { const v0 = dispatch(actions.decrement()); // @ts-expect-error Ensure action type dispatch(actions.increment()); // @ts-expect-error Ensure action arg type dispatch(actions.increment('1')); // @ts-expect-error Ensure action arg length dispatch(actions.increment(1, 'foo')); // @ts-expect-error Ensure action return type dispatch(actions.decrement()).then(); // @ts-expect-error Ensure action return type v0.split(''); // Correct batch(() => dispatch(actions.decrement())); dispatch(actions.increment(1)); dispatch(actions.fetch()).then((v) => v.split('')); v0 + 1; }, }; // @ts-expect-error const BasStore = createStore({ count: 0 }); createStore({ // @ts-expect-error initialState: { bla: 0 }, actions, }); // @ts-expect-error createStore({ initialState: { count: 0 } }); // @ts-expect-error createStore({ initialState: '', actions }); createStore({ initialState: { count: 0 }, actions, // @ts-expect-error Cannot use override container as containedBy containedBy: createContainer(createStore({} as any)), }); // @ts-expect-error createStore({ initialState: {}, actions: {}, handlers: {} }); // Correct const TypeStore = createStore({ initialState: { count: 0 }, actions, name: 'Type', }); createStore({ initialState: { count: 0 }, actions, name: 'Type', containedBy: createContainer({ displayName: 'CB' }), }); /** * createSubscriber types tests */ const TypeSubscriber = createSubscriber(TypeStore); Test = ( // @ts-expect-error {({ foo }) => foo} ); Test = ( // @ts-expect-error {(__, { increment }) => increment()} ); Test = ( // @ts-expect-error {(__, { increment }) => increment('1')} ); Test = ( // @ts-expect-error {(__, { increment }) => increment(1, 'foo')} ); // Correct Test = {({ count }) => count + 0}; Test = {(__, { increment }) => increment(1)}; /** * createSubscriber with selector types tests */ const TypeSelector = createSubscriber( TypeStore, { selector: (state) => ({ baz: 1 }), } ); Test = ( // @ts-expect-error {({ count }) => count} ); Test = ( // @ts-expect-error {({ baz }) => baz} ); // Correct Test = {({ baz }) => baz}; Test = {(__, { increment }) => increment(1)}; const TypeSelectorNull = createSubscriber(TypeStore, { selector: null, }); Test = ( // @ts-expect-error {({ count }) => count} ); Test = ( // @ts-expect-error {(state) => state === undefined} ); // Correct Test = ( {(state, { increment }) => increment(1)} ); type SelectorState = { baz: number; min: number }; const TypeSelectorProp = createSubscriber< State, Actions, SelectorState, SelectorProps >(TypeStore, { selector: (state, props) => ({ baz: 1, min: props.min }), }); Test = ( // @ts-expect-error {({ baz }) => baz} ); Test = ( // @ts-expect-error {({ baz }) => baz} ); Test = ( // @ts-expect-error {({ min }) => min.split('')} ); // Correct Test = ( {({ baz, min }) => baz + min} ); /** * createHook types tests */ const typeBaseHook = createHook(TypeStore); const baseReturn = typeBaseHook(); // @ts-expect-error typeBaseHook({}); // @ts-expect-error baseReturn[0].foo; // @ts-expect-error baseReturn[1].increment(); // @ts-expect-error baseReturn[1].increment('1'); // @ts-expect-error baseReturn[1].increment(1, 'foo'); // @ts-expect-error baseReturn[1].decrement().then((v) => v); // Correct baseReturn[0].count + 0; baseReturn[1].increment(1); baseReturn[1].decrement(); baseReturn[1].fetch().then((v) => v); /** * createHook with selector types tests */ const typeSelectorHook = createHook( TypeStore, { selector: (state) => ({ baz: 1 }) } ); const selectorReturn = typeSelectorHook(); // @ts-expect-error selectorReturn[0].count; // @ts-expect-error typeSelectorHook({ min: 3 }); // Correct selectorReturn[0].baz; selectorReturn[1].increment(1); const typeNullHook = createHook(TypeStore, { selector: null, }); const nullReturn = typeNullHook(); // @ts-expect-error nullReturn[0].count; // Correct nullReturn[1].increment(1); const typeArgHook = createHook( TypeStore, { selector: (state, props) => ({ baz: 1, min: props.min }) } ); // @ts-expect-error typeArgHook(); // @ts-expect-error typeArgHook({ min: '2' }); const argReturn = typeArgHook({ min: 2 }); // @ts-expect-error argReturn[0].min.split(''); // Correct argReturn[0].min + argReturn[0].baz; /** * createActionsHook types tests */ const typeActionsHook = createActionsHook(TypeStore); const actionsReturn = typeActionsHook(); // @ts-expect-error actionsReturn.length; // @ts-expect-error actionsReturn.count; // Correct actionsReturn.increment(1); actionsReturn.decrement(); actionsReturn.fetch().then((v) => v); /** * createActionsHook types tests */ const typeValueHook = createStateHook< State, Actions, SelectorState, SelectorProps >(TypeStore, { selector: (state, props) => ({ baz: 1, min: props.min }), }); const valueReturn = typeValueHook({ min: 2 }); // @ts-expect-error valueReturn.length; // @ts-expect-error valueReturn.count; // @ts-expect-error valueReturn.decrement(); // Correct valueReturn.min + valueReturn.baz + 1; /** * Container types tests */ const TypeContainer = createContainer(TypeStore); Test = ( // @ts-expect-error {({ count }) => count} ); Test = ( // @ts-expect-error bla ); Test = ( // @ts-expect-error cannot use both isGlobal and scope bla ); // Correct Test = bla; Test = bla; Test = bla; const TypePropsContainer = createContainer( TypeStore ); // @ts-expect-error Test = bla; Test = ( // @ts-expect-error bla ); // Correct Test = ( bla ); /** * Shared Container types tests */ const TypeSharedContainer = createContainer<{ initValue?: number }>(); Test = ( // @ts-expect-error {({ count }) => count} ); Test = ( // @ts-expect-error bla ); Test = ( // @ts-expect-error cannot use both isGlobal and scope bla ); // Correct Test = bla; Test = bla; Test = bla; Test = bla; createStore({ initialState: { count: 0 }, actions: {}, containedBy: TypeSharedContainer, handlers: { onInit: () => ({ setState }, { initValue }) => { if (initValue) { // @ts-expect-error Ensure type inferred properly initValue.split; setState({ count: initValue }); } }, onUpdate: () => () => undefined, onDestroy: () => () => undefined, onContainerUpdate: (nextProps, prevProps) => () => { const isSameScope = nextProps.scope === prevProps.scope; const isSameGlobal = nextProps.isGlobal === prevProps.isGlobal; const isSameValue = nextProps.initValue === prevProps.initValue; }, }, });