Skip to content

Commit

Permalink
Fixed an issue in the EmittedFrom type helper that could prevent it…
Browse files Browse the repository at this point in the history
… from inferring the desired type from some service (#3292)

* Fixed an issue in the `EmittedFrom` type helper that could prevent it from inferring the desired type from some service

* Special case Interpreter in the EmittedFrom
  • Loading branch information
Andarist committed May 13, 2022
1 parent 5424178 commit 16514e4
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/popular-wolves-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

Fixed an issue in the `EmittedFrom` type helper that could prevent it from inferring the desired type from some services.
4 changes: 3 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,9 @@ export interface Behavior<TEvent extends EventObject, TEmitted = any> {
}

export type EmittedFrom<T> = ReturnTypeOrValue<T> extends infer R
? R extends ActorRef<infer _, infer TEmitted>
? R extends Interpreter<infer _, infer __, infer ___, infer ____, infer _____>
? R['initialState']
: R extends ActorRef<infer _, infer TEmitted>
? TEmitted
: R extends Behavior<infer _, infer TEmitted>
? TEmitted
Expand Down
36 changes: 36 additions & 0 deletions packages/core/test/typeHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
assign,
ContextFrom,
createMachine,
EmittedFrom,
EventFrom,
interpret,
MachineOptionsFrom,
Expand Down Expand Up @@ -368,3 +369,38 @@ describe('StateValueFrom', () => {
matches('just anything');
});
});

describe('EmittedFrom', () => {
it('should return state type from a service that has concrete event type', () => {
const service = interpret(
createMachine({
schema: {
events: {} as { type: 'FOO' }
}
})
);

function acceptState(_state: EmittedFrom<typeof service>) {}

acceptState(service.initialState);
// @ts-expect-error
acceptState("isn't any");
});

it('should return state from a service created based on a model without any concrete events', () => {
const service = interpret(
createModel(
{},
{
// this empty obj is important for this test case
}
).createMachine({})
);

function acceptState(_state: EmittedFrom<typeof service>) {}

acceptState(service.initialState);
// @ts-expect-error
acceptState("isn't any");
});
});

0 comments on commit 16514e4

Please sign in to comment.