diff --git a/src/story.test.ts b/src/story.test.ts index 07e1133..c58df9a 100644 --- a/src/story.test.ts +++ b/src/story.test.ts @@ -144,3 +144,13 @@ test('ArgsFromMeta will infer correct args from render/loader/decorators', () => loaderArg2: number; }>(); }); + +test('You can assign a component to Meta, even when you pass a top type', () => { + expectTypeOf({ component: Button }).toMatchTypeOf(); + expectTypeOf({ component: Button }).toMatchTypeOf>>(); + expectTypeOf({ component: Button }).toMatchTypeOf>>(); + expectTypeOf({ component: Button }).toMatchTypeOf>(); + expectTypeOf({ component: Button }).toMatchTypeOf>(); + expectTypeOf({ component: Button }).not.toMatchTypeOf>(); + expectTypeOf({ component: Button }).not.toMatchTypeOf>(); +}); diff --git a/src/story.ts b/src/story.ts index f937a4a..c96eaae 100644 --- a/src/story.ts +++ b/src/story.ts @@ -298,7 +298,24 @@ export interface ComponentAnnotations, Record, any, unknown). + // This is because you can not assign Component with more specific props, to a Component that accepts anything + + // For example this won't compile + // const Button: FC = (props: {prop: number} ) => {} + // + // Note that the subtyping relationship is inversed for T and (t: T) => any. As this is fine: + // const args: Args = { prop: 1 }; + // The correct way would probably to fall back to `never`, being the inverse of unknown. Or maybe `Record` + // + // Any is really weird as it pretends to be never and unknown at the same time (so being the absolute bottom and top type at the same time) + // However, I don't have the guts to fallback to Record, forgive me. + // + // If this all doesn't make sense, you may want to look at the test: You can assign a component to Meta, even when you pass a top type. + T: Record extends Required ? any : TArgs; + })['component']; /** * Auxiliary subcomponents that are part of the stories.