Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue2: Improve CSF3 types #19603

Merged
merged 11 commits into from
Oct 25, 2022
Merged

Vue2: Improve CSF3 types #19603

merged 11 commits into from
Oct 25, 2022

Conversation

kasperpeulen
Copy link
Contributor

@kasperpeulen kasperpeulen commented Oct 24, 2022

What I did

This PR provides improved type safety for Vue2 stories (similar to what we changed to React, Svelte and Vue3) but requires vue-tsc instead of tsc (And the Volar VS Code extension for editor support):
https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin

To unlock the full potential of this PR, TS 4.9 is needed, for the new satisfies operator. But, this also improves the types for TS<4.9 users.

Typesafe args

We changed StoryObj and Meta to increase type safety for when the user provides args partially in meta.

Considering a Component like this:

<template>
    <button type="button" class="classes" @click="onClick" :disabled="disabled">{{ label }}</button>
</template>

<script lang="ts">
import Vue from 'vue';
import './button.css';

export default Vue.extend({
    name: 'my-button',

    props: {
        label: {
            type: String,
            required: true,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
    },
    methods: {
        onClick(): void {
            this.$emit('onClick');
        },
    },
});
</script>

It is valid to provide args like this:

import Button from './Button.vue';

// ✅ valid
const meta = {
  component: Button,
  args: { disabled: false },
} satisfies Meta<typeof Button>;

// or const meta = Meta<typeof Button> = { ... } in TS<4.9

export default meta;

type Story = StoryObj<typeof meta>;

export const Basic: Story = {
  args: { label: 'good' }
};

While it is invalid to forget an arg, in either meta or the story:

// ❌ invalid
const meta = {
  component: Button,
} satisfies Meta<typeof Button>;

export const Basic: Story = {
  args: { label: 'good' }
};

// ❌ invalid
const meta = {
  component: Button,
  args: { label: 'good' }
} satisfies Meta<typeof Button>;

export const Basic: Story = {};

Changed Meta to make sure both a Component, as the Props of the component can be used:

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

export default meta;

export const meta = {
  component: Button,
} satisfies Meta<{label: string; disabled: boolean} >;

export default meta;

Typesafe decorators/loaders

Decorators now accept a new generic arg argument to be specified:

const withDecorator: DecoratorFn<{ decoratorArg: string }> = (
  Story,
  { args: { decoratorArg } }
) =>
  Vue.extend({
    components: { Story },
    template: `<div>Decorator: ${decoratorArg}<Story/></div>`,
  });

And the type of meta/story will check if this arg is part of the generic type:

type Props = ButtonProps & { decoratorArg: string };

const meta = satisfies<Meta<Props>>()({
  component: Button,
  args: { disabled: false },
  decorators: [withDecorator],
});

type Story = StoryObj<typeof meta>;
const Basic: Story = { args: { decoratorArg: 0, label: 'good' } };

I also fixed some typescript issues in other files in this package.

How to test

You can test it by running: yarn nx run @storybook/vue:check

Copy link
Member

@tmeasday tmeasday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The tests are going to stand us in very good stead!

Copy link
Member

@shilman shilman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

code/renderers/vue/src/docs/sourceDecorator.ts Outdated Show resolved Hide resolved
@kasperpeulen kasperpeulen removed the request for review from prashantpalikhe October 25, 2022 12:38
@kasperpeulen kasperpeulen merged commit 065bd82 into next Oct 25, 2022
@kasperpeulen kasperpeulen deleted the future/CSF3-vue2 branch October 25, 2022 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants