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

Vue: Improve types for array, union and intersection when using vue-docgen-api #26177

Merged
merged 8 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion code/frameworks/vue3-vite/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import type { BuilderOptions, StorybookConfigVite } from '@storybook/builder-vite';
import type { StorybookConfig as StorybookConfigBase } from '@storybook/types';
import type { ComponentMeta } from 'vue-component-meta';
import type { ComponentDoc } from 'vue-docgen-api';

type FrameworkName = '@storybook/vue3-vite';
type BuilderName = '@storybook/builder-vite';

/**
* Available docgen plugins for vue.
*/
export type VueDocgenPlugin = 'vue-docgen-api' | 'vue-component-meta';

export type FrameworkOptions = {
builder?: BuilderOptions;
/**
Expand All @@ -14,7 +21,7 @@ export type FrameworkOptions = {
* "vue-component-meta" will become the new default in the future and "vue-docgen-api" will be removed.
* @default "vue-docgen-api"
*/
docgen?: 'vue-docgen-api' | 'vue-component-meta';
docgen?: VueDocgenPlugin;
};

type StorybookConfigFramework = {
Expand Down Expand Up @@ -43,3 +50,37 @@ export type StorybookConfig = Omit<
> &
StorybookConfigVite &
StorybookConfigFramework;

/**
* Gets the type of a single array element.
*/
type ArrayElement<T> = T extends readonly (infer A)[] ? A : never;

/**
* Type of "__docgenInfo" depending on the used docgenPlugin.
*/
export type VueDocgenInfo<T extends VueDocgenPlugin> = T extends 'vue-component-meta'
? ComponentMeta
: ComponentDoc;

/**
* Single prop/event/slot/exposed entry of "__docgenInfo" depending on the used docgenPlugin.
*
* @example
* ```ts
* type PropInfo = VueDocgenInfoEntry<"vue-component-meta", "props">;
* ```
*/
export type VueDocgenInfoEntry<
T extends VueDocgenPlugin,
TKey extends 'props' | 'events' | 'slots' | 'exposed' | 'expose' =
| 'props'
| 'events'
| 'slots'
| 'exposed'
| 'expose',
> = ArrayElement<
T extends 'vue-component-meta'
? VueDocgenInfo<'vue-component-meta'>[Exclude<TKey, 'expose'>]
: VueDocgenInfo<'vue-docgen-api'>[Exclude<TKey, 'exposed'>]
>;
4 changes: 3 additions & 1 deletion code/lib/docs-tools/src/argTypes/docgen/utils/docgenInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import type { Component } from '../../types';
import { str } from './string';

export function hasDocgen(component: Component): boolean {
export function hasDocgen<T = any>(
component: Component
): component is object & { __docgenInfo: T } {
return !!component.__docgenInfo;
}

Expand Down
Loading
Loading