#TypeScript errors when re-using `play` functions.

123 messages · Page 1 of 1 (latest)

radiant solstice
#

The documentation mentions re-using play functions for interactions testing like this:

play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);

    // Runs the FirstStory and Second story play function before running this story's play function
    await FirstStory.play({ canvasElement });
    await SecondStory.play({ canvasElement });
    await userEvent.type(canvas.getByTestId('another-element'), 'random value');
  },

Although when I do exactly that, there is a TS error:

Argument of type '{ canvasElement: any; }' is not assignable to parameter of type 'PlayFunctionContext<ReactRenderer, {}>'.
  Type '{ canvasElement: any; }' is missing the following properties from type 'StoryIdentifier': componentId, title, kind, id, and 3 more.ts(2345)

I tried passing ...rest but that did not help either (attached screengrabs for more info)

smoky warren
radiant solstice
#

@smoky warren

type StoryFSM = StoryObj<typeof FSMView>;

export default {
  component: FSMView,
} as Meta<typeof FSMView>;

export const SwitchesToBuilder: StoryFSM = {
smoky warren
#

Are you using TS 4.9?

radiant solstice
#

Yeah

smoky warren
radiant solstice
#

Hmmm i had to stop using satisfies because jest complained

#

But let me try if it fixes this issue

smoky warren
#

You may need to update a few other packages, depending on what you use.

radiant solstice
#

@smoky warren changed it to

const meta = {
  component: FSMView,
} satisfies Meta<typeof FSMView>;

export default meta;
smoky warren
#

And the stories should change to reference meta now too, right?

radiant solstice
#

no change afaics

#

how?

smoky warren
#
type Story = StoryObj<typeof meta>;

const base: Story = {
radiant solstice
#

stories are just using StoryObj<typeof ....>

#

ah

#

ok sorry I missed that one in the docs

#

the error is different now

#
Argument of type '{ canvasElement: HTMLElement; }' is not assignable to parameter of type 'PlayFunctionContext<ReactRenderer, { [x: string]: any; }>'.
  Type '{ canvasElement: HTMLElement; }' is missing the following properties from type 'StoryIdentifier': componentId, title, kind, id, and 3 more.ts(2345)
smoky warren
#

I wonder if you need to take the whole context argument and provide it. So, like:

#
play: async (context) => {
    const canvas = within(context.canvasElement);

    // Runs the FirstStory and Second story play function before running this story's play function
    await FirstStory.play(context);
    await SecondStory.play(context);
    await userEvent.type(canvas.getByTestId('another-element'), 'random value');
  },
radiant solstice
#

lets try

#

wouldn't that be the same as supplying rest tho?

smoky warren
#

Yeah you could do that too, either way.

radiant solstice
#

yeah that fixes it

#

so the documentation needs to be updated

smoky warren
#

Can you point to where you saw this?

radiant solstice
#

sure

#

i cant find it

#

it was there an hour ago

#

is it possible it got hotfixed?

#

i cant find the whole page tbh

#

no idea why

#

it was about reusing the play function

smoky warren
#

@balmy storm @quaint zephyr do you know where we document re-using play functions in other stories? It sounds like there might be a problem with it.

radiant solstice
#

got it!

#

geez I am dense 🙂

#

this actually

radiant solstice
#

if you go to TS you can see

// Runs the FirstStory and Second story play function before running this story's play function
    await FirstStory.play({ canvasElement });
    await SecondStory.play({ canvasElement });
smoky warren
#

Would you mind terribly creating a github issue, and tagging @balmy storm and myself on it? Our github handles are the same as here.

#

I'd like to track it, and make sure we fix it.

#

Even better would be a PR. 😉

radiant solstice
#

sure thing

#

@smoky warren this would have to be changed to satisfies too

#
const meta: Meta<typeof MyComponent> = {
  title: 'MyComponent',
  component: MyComponent,
};
smoky warren
#

Did you check if it works without the satisfies change?

#

Was that needed?

radiant solstice
#

I tried that before

#

let me try again

#

just fo sho

#

ok so it works without, as long as the stories are typed as typeof meta

#

so this needs to change

#

type Story = StoryObj<typeof MyComponent>;

#

in the docs

#

but I lost intellisense it looks like

smoky warren
#

yeah that's the downside without satisfies

radiant solstice
#

i dont have intellisense even with satisfies for some reason

#

args have no type

smoky warren
#

Share what you have?

radiant solstice
#

oh wait

#

that's my mistake I think

#

yeah I incorreclty exported my component, all is well

#

even typeof meta works fine

#

it has to be like

const meta = {
  component: FSMView,
} as Meta<typeof FSMView>;

not

const meta: Meta<typeof FSMView> = {
  component: FSMView,
}
#

though

radiant solstice
#

@smoky warren do I need an issue or is PR enough?

smoky warren
#

A PR is great, thanks

radiant solstice
#

So - there seems to be no bug at all

#

well - it depends on how one exports their component

#

I exported mine without any type

#

and that introduced this issue

#

but if you export the component properly (say React.FC<Props>)

#

it works fine

smoky warren
#

did you type your props?

radiant solstice
#

i did - but I did not export purely the component

smoky warren
#

I think most people don't use React.FC, I prefer to avoid that.

radiant solstice
#

the file actually exports

export default compose(
  withGlobalOptionsConsumer(),
  withMessageHandler(),
  withMapperConsumer()
)(FSMView);
#

which introduced the issue

smoky warren
#

ok, that's a bit more complex, yea

radiant solstice
#
export default compose(
  withGlobalOptionsConsumer(),
  withMessageHandler(),
  withMapperConsumer()
)(FSMView) as React.FC<IFSMViewProps>;
``` fixes it
smoky warren
#

So, if you export a normal component, does it work without providing all the context to the play function?

radiant solstice
#

hmmm let me check

#

no

#

but at least the props work

#
Argument of type '{ canvasElement: HTMLElement; }' is not assignable to parameter of type 'PlayFunctionContext<ReactRenderer, IFSMViewProps>'.
  Type '{ canvasElement: HTMLElement; }' is missing the following properties from type 'StoryIdentifier': componentId, title, kind, id, and 3 more.ts(2345)
smoky warren
#

Alright, so we should change that part no matter what it seems

radiant solstice
#

so we did find one issue

#

everything else is OK

#

should I use typeof meta or typeof component then?

smoky warren
#

I guess keep it the same as the old way for now. I guess there's going to have to be an effort to add / update all the examples to the new satisfies approach at some point.

#

(i.e. use typeof component)

radiant solstice
#

aight cool

#

oh crap - it needs to be updated for JS as well

#

or does it?

smoky warren
#

Well, it's just a type error, so it's probably okay the way it was before for JS

radiant solstice
#

it doesnt I guess

#

ok but isn't it confusing?

#

one example is using just { canvasElement }, the other passes ...rest too

#

it would confuse me if I checked that

smoky warren
#

Sure, feel free to make them consistent.

#

Is good if one uses args or something, anyway

radiant solstice
#

you want me to rename rest? I guess ...context would be the best?

smoky warren
#

Yeah, or honestly I'd probably use the approach I suggested, of calling the whole thing context, and destructuring what is needed in the play function itself

radiant solstice
#

ok sure thing

smoky warren
#

Thanks! I added the labels it needs and requested a review from the right person. Appreciate the submission!

balmy storm
#

@radiant solstice I just saw the notification and I'll take a look at it tomorrow morning my time and follow up with on it. Sounds good?

radiant solstice
#

@balmy storm as you wish mate, it's not a blocking issue or anything for me 🙂 thanks

balmy storm
#

No need to thank whatsoever, appreciate you taking the time to help out with the documentation 🙏

radiant solstice
#

Absolutely - can you also check if this screenshot is correct?
#documentation message

#

it seems that it could use a different one, with actual interaction controls there

balmy storm
#

@radiant solstice the assets (images, videos) are getting reworked by our Design team. These were left in as placeholders to demonstrate the behavior. Nonetheless I'll check and relay the feedback back. Sounds good?

radiant solstice
#

Sounds good 🙂

quaint zephyr
#

Thanks for the PR!
I think @urban quarry eslint plugin also warns when you don't pass the whole context.

urban quarry
#

yup!

radiant solstice
#

I am eslint free and would like to keep it that way for as long as I can 😁

smoky warren
#

eslint is great, why would you avoid it?