diff --git a/.changeset/olive-shrimps-shave.md b/.changeset/olive-shrimps-shave.md new file mode 100644 index 0000000000..7fd52391ea --- /dev/null +++ b/.changeset/olive-shrimps-shave.md @@ -0,0 +1,5 @@ +--- +"@storybook/marko": patch +--- + +Improve types. diff --git a/.eslintrc.json b/.eslintrc.json index 2fb9515ff3..6cc81afc82 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,27 +5,29 @@ "parserOptions": { "ecmaVersion": "latest", "sourceType": "module", - "impliedStrict": true, - "warnOnUnsupportedTypeScriptVersion": false + "impliedStrict": true }, "settings": { "import/resolver": { + "node": true, "typescript": true } }, "env": { "node": true, + "mocha": true, "es2024": true, "browser": true }, "rules": { + "import/namespace": "off", "import/order": [ "error", { "groups": [ ["builtin"], ["external"], - "internal", + ["internal"], "parent", "sibling", "index" @@ -51,11 +53,13 @@ ], "rules": { "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-duplicate-enum-values": "off", "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/no-namespace": "off" + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-var-requires": "off" } } ] diff --git a/packages/renderers/marko/src/decorators.ts b/packages/renderers/marko/src/decorators.ts index f2049ebbfd..dde5d9632c 100644 --- a/packages/renderers/marko/src/decorators.ts +++ b/packages/renderers/marko/src/decorators.ts @@ -9,17 +9,14 @@ export const decorateStory: DecoratorApplicator = ( decorators.reduce( (decorated, decorator) => (context: StoryContext): MarkoStoryResult => { - let story: MarkoRenderer["storyResult"] | undefined; - const decoratedStory: MarkoRenderer["storyResult"] = decorator( - (update) => { - story = decorated({ - ...context, - ...sanitizeStoryContextUpdate(update), - }); - return story; - }, - context, - ); + let story: MarkoStoryResult | undefined; + const decoratedStory: MarkoStoryResult = decorator((update) => { + story = decorated({ + ...context, + ...sanitizeStoryContextUpdate(update), + }); + return story; + }, context); story ||= decorated(context); return decoratedStory === story diff --git a/packages/renderers/marko/src/public-types.ts b/packages/renderers/marko/src/public-types.ts index fbef1e49b0..e29926fb45 100644 --- a/packages/renderers/marko/src/public-types.ts +++ b/packages/renderers/marko/src/public-types.ts @@ -52,15 +52,15 @@ export type Story = StoryFn | StoryObj; export type { MarkoRenderer }; export type Decorator = DecoratorFunction< - MarkoRenderer, + MarkoRenderer, Input >; export type Loader = LoaderFunction< - MarkoRenderer, + MarkoRenderer, Input >; export type StoryContext = GenericStoryContext< - MarkoRenderer, + MarkoRenderer, Input >; export type Preview = ProjectAnnotations; diff --git a/packages/renderers/marko/src/testing-api.ts b/packages/renderers/marko/src/testing-api.ts index 651d1ef964..eb8161e5e1 100644 --- a/packages/renderers/marko/src/testing-api.ts +++ b/packages/renderers/marko/src/testing-api.ts @@ -7,12 +7,12 @@ import { import type { Args, ComposedStoryFn, - ProjectAnnotations, Store_CSFExports, + StoryAnnotationsOrFn, } from "@storybook/types"; import { decorateStory } from "./decorators"; -import type { Meta, Story } from "./public-types"; +import type { Meta, Story, Preview } from "./public-types"; import { render } from "./render"; import type { MarkoRenderer } from "./types"; @@ -47,11 +47,7 @@ export type ComposedStory = ComposedStoryFn< * * @param projectAnnotations - e.g. (import projectAnnotations from '../.storybook/preview') */ -export function setProjectAnnotations( - projectAnnotations: - | ProjectAnnotations - | ProjectAnnotations[], -) { +export function setProjectAnnotations(projectAnnotations: Preview | Preview[]) { originalSetProjectAnnotations(projectAnnotations); } @@ -59,11 +55,7 @@ export function setProjectAnnotations( * * @deprecated Use setProjectAnnotations instead */ -export function setGlobalConfig( - projectAnnotations: - | ProjectAnnotations - | ProjectAnnotations[], -) { +export function setGlobalConfig(projectAnnotations: Preview | Preview[]) { deprecate( `setGlobalConfig is deprecated. Use setProjectAnnotations instead.`, ); @@ -71,7 +63,7 @@ export function setGlobalConfig( } // This will not be necessary once we have auto preset loading -const defaultProjectAnnotations: ProjectAnnotations> = { +const defaultProjectAnnotations: Preview = { render, applyDecorators: decorateStory, }; @@ -105,15 +97,18 @@ const defaultProjectAnnotations: ProjectAnnotations> = { */ export function composeStory< Input extends Args = Args, - Export extends Story = Story, + Export extends StoryAnnotationsOrFn< + MarkoRenderer, + Input + > = StoryAnnotationsOrFn, >( story: Export, componentAnnotations: Meta, - projectAnnotations?: ProjectAnnotations>, + projectAnnotations?: Preview, exportsName?: string, ): ComposedStory { return toRenderable( - originalComposeStory, Input>( + originalComposeStory( story as any, componentAnnotations, projectAnnotations, @@ -151,7 +146,7 @@ export function composeStory< */ export function composeStories( csfExports: Exports, - projectAnnotations?: ProjectAnnotations, + projectAnnotations?: Preview, ): ComposedStories { return (originalComposeStories as any)( csfExports, @@ -167,7 +162,7 @@ export function composeStories( * Properties that exist on the story context are also accessible through the proxy. */ function toRenderable( - composed: ComposedStoryFn, Partial>, + composed: ComposedStoryFn>, componentAnnotations: Meta, ) { return { @@ -180,11 +175,11 @@ function toRenderable( cb?: any, ) { const { component, input } = runStory(rawInput); - return component.render(input!, cb); + return component.render(input, cb); }, renderSync(rawInput: Partial> | undefined) { const { component, input } = runStory(rawInput); - return component.renderSync(input!); + return component.renderSync(input); }, renderToString( rawInput: Partial> | undefined, @@ -195,12 +190,12 @@ function toRenderable( }, stream(rawInput: Partial> | undefined) { const { component, input } = runStory(rawInput); - return component.stream(input!); + return component.stream(input); }, } satisfies Marko.Template; function runStory(rawInput: Partial> | undefined) { - const { component = componentAnnotations?.component, input } = + const { component = componentAnnotations?.component, input = {} } = composed(rawInput) || {}; if (!component || !component.renderSync) { throw new Error( diff --git a/packages/renderers/marko/src/types.ts b/packages/renderers/marko/src/types.ts index 058d6a34f6..d13d5b953f 100644 --- a/packages/renderers/marko/src/types.ts +++ b/packages/renderers/marko/src/types.ts @@ -14,6 +14,6 @@ export interface MarkoRenderer extends WebRenderer { } export interface MarkoStoryResult { - component?: Marko.Template; + component?: Marko.Template; input?: Marko.TemplateInput; }