Xstate: Typescript compiler complaining about "assign" usage.

Created on 19 May 2019  路  4Comments  路  Source: davidkpiano/xstate

Bug or feature request?

Bug

Description:

Following fairly closely the TODO example the following code won't accept what I wrote for the "onEntry":

import { Machine, actions, EventObject } from "xstate";
const { assign } = actions;

export interface TagContext {
    title: string;
    previousTitle: string | null;
}

export type EventId = "COMMIT";
export interface TagEvent extends EventObject {
  type: EventId;
}

export const TagMachine = Machine<TagContext,any,TagEvent>({
    id: "tag",
    initial: "editing",
    context: {
        previousTitle: null,
        title: ""
    },
    states: {
        editing: {
            onEntry: assign({ previousTitle: ctx => ctx.title }),
            on: {
                COMMIT: {
                    target: "viewing"
                }
            }
        }
    }
})

(Bug) Expected result:

Should compile

(Bug) Actual result:

Argument of type '{ previousTitle: (ctx: TagContext) => string; }' is not assignable to parameter of type 'Assigner<{ previousTitle: string; }, TagEvent> | Partial<{ previousTitle: string | ((context: { previousTitle: string; }, event: TagEvent) => string); }>'.
Type '{ previousTitle: (ctx: TagContext) => string; }' is not assignable to type 'Partial<{ previousTitle: string | ((context: { previousTitle: string; }, event: TagEvent) => string); }>'.
    Types of property 'previousTitle' are incompatible.
      Type '(ctx: TagContext) => string' is not assignable to type 'string | ((context: { previousTitle: string; }, event: TagEvent) => string) | undefined'.
        Type '(ctx: TagContext) => string' is not assignable to type '(context: { previousTitle: string; }, event: TagEvent) => string'.
          Types of parameters 'ctx' and 'context' are incompatible.
            Property 'title' is missing in type '{ previousTitle: string; }' but required in type 'TagContext'.ts(2345)

(Bug) Potential fix:

Somewhere the type definition derails, but I am not actually sure where.

This is typescript 3.4.5 and xstate 4.5.0

typescript

Most helpful comment

Workaround:

onEntry: assign<TagContext>({
  // your assignments here
})

I believe that TypeScript still has a hard time narrowing type definitions inferred from functions; that is, if we can expect AssignObject<TContext> but we are given a function that returns AssignObject<any>, TS sometimes has a hard time narrowing that any to a TContext.

All 4 comments

Workaround:

onEntry: assign<TagContext>({
  // your assignments here
})

I believe that TypeScript still has a hard time narrowing type definitions inferred from functions; that is, if we can expect AssignObject<TContext> but we are given a function that returns AssignObject<any>, TS sometimes has a hard time narrowing that any to a TContext.

Could this be documented somehow in the ts guide ?

Thank you 馃檹

Was this page helpful?
0 / 5 - 0 ratings

Related issues

drmikecrowe picture drmikecrowe  路  3Comments

hnordt picture hnordt  路  3Comments

carlbarrdahl picture carlbarrdahl  路  3Comments

pke picture pke  路  3Comments

ifokeev picture ifokeev  路  3Comments