Skip to content

Commit

Permalink
Limit inference sites for TContext (#3082)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Feb 23, 2022
1 parent 945a707 commit 8d3f2cf
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/empty-hairs-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

Fixed an issue with context type being inferred from too many places within `createMachine` call and possibly ending up as `any` for the entire machine.
3 changes: 2 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type Equals<A1 extends any, A2 extends any> = (<A>() => A extends A2
: false;
export type IsAny<T> = Equals<T, any>;
export type Cast<A, B> = A extends B ? A : B;
export type NoInfer<T> = [T][T extends any ? 0 : any];

export type EventType = string;
export type ActionType = string;
Expand Down Expand Up @@ -946,7 +947,7 @@ export interface MachineConfig<
TAction extends BaseActionObject = BaseActionObject,
TServiceMap extends ServiceMap = ServiceMap,
TTypesMeta = TypegenDisabled
> extends StateNodeConfig<TContext, TStateSchema, TEvent, TAction> {
> extends StateNodeConfig<NoInfer<TContext>, TStateSchema, TEvent, TAction> {
/**
* The initial context (extended state)
*/
Expand Down
24 changes: 24 additions & 0 deletions packages/core/test/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,30 @@ describe('Typestates', () => {
});
});

describe('context', () => {
it('should not use actions as possible inference sites', () => {
createMachine(
{
schema: {
context: {} as {
count: number;
}
},
entry: (_ctx: any) => {}
},
{
actions: {
someAction: (ctx) => {
((_accept: number) => {})(ctx.count);
// @ts-expect-error
((_accept: string) => {})(ctx.count);
}
}
}
);
});
});

describe('interpreter', () => {
it('should be convertable to Rx observable', () => {
const state$ = from(
Expand Down
32 changes: 30 additions & 2 deletions packages/xstate-react/test/useSelector.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import * as React from 'react';
import { assign, createMachine, interpret, spawn, toActorRef } from 'xstate';
import {
ActorRefFrom,
assign,
createMachine,
interpret,
spawn,
StateFrom,
toActorRef
} from 'xstate';
import { act, render, cleanup, fireEvent } from '@testing-library/react';
import { useInterpret, useMachine, useSelector } from '../src';

Expand Down Expand Up @@ -153,12 +161,16 @@ describe('useSelector', () => {
});

const parentMachine = createMachine({
schema: {
context: {} as { childActor: ActorRefFrom<typeof childMachine> }
},
entry: assign({
childActor: () => spawn(childMachine)
})
});

const selector = (state) => state.context.count;
const selector = (state: StateFrom<typeof childMachine>) =>
state.context.count;

const App = () => {
const [state] = useMachine(parentMachine);
Expand Down Expand Up @@ -200,6 +212,11 @@ describe('useSelector', () => {
});

const parentMachine = createMachine({
schema: {
context: {} as {
childActor: ActorRefFrom<ReturnType<typeof createActor>>;
}
},
entry: assign({
childActor: () => spawn(createActor('foo'))
})
Expand Down Expand Up @@ -242,6 +259,9 @@ describe('useSelector', () => {
});

const parentMachine = createMachine({
schema: {
context: {} as { childActor: ActorRefFrom<typeof childMachine> }
},
entry: assign({
childActor: () => spawn(childMachine)
})
Expand Down Expand Up @@ -281,6 +301,9 @@ describe('useSelector', () => {
});

const parentMachine = createMachine({
schema: {
context: {} as { childActor: ActorRefFrom<typeof childMachine> }
},
entry: assign({
childActor: () => spawn(childMachine)
})
Expand Down Expand Up @@ -328,6 +351,11 @@ describe('useSelector', () => {
});

const parentMachine = createMachine({
schema: {
context: {} as {
childActor: ActorRefFrom<ReturnType<typeof createActor>>;
}
},
entry: assign({
childActor: () => spawn(createActor('foo'))
})
Expand Down

0 comments on commit 8d3f2cf

Please sign in to comment.