Skip to content

Commit

Permalink
Remove the unsupported machine implementation types from `useActorRef…
Browse files Browse the repository at this point in the history
…`'s signature (#4433)

* Remove the unsupported machine implementation types from `useActorRef`'s signature

* remove redundant type tests
  • Loading branch information
Andarist authored Nov 7, 2023
1 parent 8fb9844 commit 2685a33
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 252 deletions.
45 changes: 4 additions & 41 deletions packages/xstate-react/src/useActorRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,49 +46,12 @@ export function useIdleInterpreter(
return actorRef as any;
}

type RestParams<TLogic extends AnyActorLogic> = TLogic extends AnyStateMachine
? AreAllImplementationsAssumedToBeProvided<
TLogic['__TResolvedTypesMeta']
> extends false
? [
options: ActorOptions<TLogic> &
InternalMachineImplementations<
TLogic['__TContext'],
TLogic['__TEvent'],
TODO,
TODO,
TODO,
TLogic['__TResolvedTypesMeta'],
true
>,
observerOrListener?:
| Observer<StateFrom<TLogic>>
| ((value: StateFrom<TLogic>) => void)
]
: [
options?: ActorOptions<TLogic> &
InternalMachineImplementations<
TLogic['__TContext'],
TLogic['__TEvent'],
TODO,
TODO,
TODO,
TLogic['__TResolvedTypesMeta']
>,
observerOrListener?:
| Observer<StateFrom<TLogic>>
| ((value: StateFrom<TLogic>) => void)
]
: [
options?: ActorOptions<TLogic>,
observerOrListener?:
| Observer<SnapshotFrom<TLogic>>
| ((value: SnapshotFrom<TLogic>) => void)
];

export function useActorRef<TLogic extends AnyActorLogic>(
machine: TLogic,
...[options = {}, observerOrListener]: RestParams<TLogic>
options: ActorOptions<TLogic> = {},
observerOrListener?:
| Observer<SnapshotFrom<TLogic>>
| ((value: SnapshotFrom<TLogic>) => void)
): ActorRefFrom<TLogic> {
const actorRef = useIdleInterpreter(machine, options);

Expand Down
211 changes: 0 additions & 211 deletions packages/xstate-react/test/typegenTypes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,217 +226,6 @@ describe('useMachine', () => {
});

describe('useActorRef', () => {
it('should allow to be used with a machine without any missing implementations', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: never;
delays: never;
guards: never;
actors: never;
};
}

const machine = createMachine({
types: { typegen: {} as TypesMeta }
});

function App() {
useActorRef(machine);
return null;
}

render(<App />);
});

it('should not allow to be used with a machine with some missing implementations', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: 'myAction';
delays: never;
guards: never;
actors: never;
};
eventsCausingActions: {
myAction: 'FOO';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' } | { type: 'BAZ' }
}
});

function App() {
// @ts-expect-error
useActorRef(machine);
return null;
}

render(<App />);
});

it('should require all missing implementations ', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: 'myAction';
delays: 'myDelay';
guards: never;
actors: never;
};
eventsCausingActions: {
myAction: 'FOO';
myDelay: 'BAR';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' } | { type: 'BAZ' }
}
});

function App() {
// @ts-expect-error
useActorRef(machine, {});
useActorRef(machine, {
// @ts-expect-error
actions: {}
});
// @ts-expect-error
useActorRef(machine, {
actions: {
myAction: () => {}
}
});
useActorRef(machine, {
actions: {
myAction: () => {}
},
delays: {
myDelay: () => 42
}
});
return null;
}

render(<App />);
});

it('should allow to override already provided implementation', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: 'fooAction';
delays: never;
guards: never;
actors: never;
};
eventsCausingActions: { fooAction: 'FOO' };
eventsCausingDelays: { barDelay: 'BAR' };
}

const machine = createMachine(
{
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' } | { type: 'BAZ' }
}
},
{
delays: {
barDelay: () => 42
}
}
);

function App() {
useActorRef(machine, {
actions: {
fooAction: () => {}
},
delays: {
barDelay: () => 100
}
});
return null;
}

render(<App />);
});

it('should accept a machine that accepts a specific subset of events in one of the implementations', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: never;
actors: never;
guards: never;
delays: never;
};
eventsCausingActions: {
fooAction: 'FOO';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' }
}
});

function App() {
useActorRef(machine, {
actions: {
// it's important to use `event` here somehow to make this a possible source of information for inference
fooAction: () => {}
}
});
return null;
}

render(<App />);
});

it('should provide subset of the event type to action objects given in the `options` argument', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: never;
actors: never;
guards: never;
delays: never;
};
eventsCausingActions: {
fooAction: 'FOO';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' }
}
});

function App() {
useActorRef(
machine.provide({
actions: {
fooAction: assign(({ event }) => {
((_accept: 'FOO') => {})(event.type);
// @ts-expect-error
((_accept: "test that this isn't any") => {})(event.type);
})
}
})
);
return null;
}

render(<App />);
});

it('Should handle multiple state.matches when passed TypegenMeta', () => {
interface TypesMeta extends TypegenMeta {
matchesStates: 'a' | 'b';
Expand Down

0 comments on commit 2685a33

Please sign in to comment.