Skip to content

Function: propsAndEmitsFactory()

ts
function propsAndEmitsFactory<P, E>(
  props: P,
  emits: E,
  source: string,
): {
  emits: EmitFunctions<E>;
  makeProps: PropFactory<{
    [KeyType in string | number | symbol]: ({
      [Key in string | number | symbol as Key extends keyof PickIndexSignature<
        EmitHandlerProps<E>
      >
        ? never
        : Key]: PickIndexSignature<P>[Key];
    } & PickIndexSignature<EmitHandlerProps<E>> & {
        [Key in
          | string
          | number
          | symbol as Key extends keyof OmitIndexSignature<EmitHandlerProps<E>>
          ? never
          : Key]: OmitIndexSignature<P>[Key];
      } & OmitIndexSignature<EmitHandlerProps<E>>)[KeyType];
  }>;
};

Factory function that creates both props and emits for Vue components with automatic emit handler prop generation.

This utility automatically generates corresponding prop handlers for each emit event, supporting both camelCase and kebab-case naming conventions to maximize template syntax flexibility. For each emit, it creates props that allow users to bind handlers using either :onEventName or @event-name syntax.

The returned makeProps function includes full TypeScript support for both the original props and the automatically generated emit handler props, ensuring type safety throughout component development.

Type Parameters

Type ParameterDescription
P extends ComponentObjectPropsOptions<Data>The type of the component props object
E extends EmitValidatorsThe type of the emit validators object

Parameters

ParameterTypeDescription
propsPComponent props object that will be extended with emit handler props
emitsEObject containing emit validator functions
sourcestringSource identifier for the props factory (used for debugging/tooling)

Returns

ts
{
  emits: EmitFunctions<E>;
  makeProps: PropFactory<{
    [KeyType in string | number | symbol]: ({
      [Key in string | number | symbol as Key extends keyof PickIndexSignature<
        EmitHandlerProps<E>
      >
        ? never
        : Key]: PickIndexSignature<P>[Key];
    } & PickIndexSignature<EmitHandlerProps<E>> & {
        [Key in
          | string
          | number
          | symbol as Key extends keyof OmitIndexSignature<EmitHandlerProps<E>>
          ? never
          : Key]: OmitIndexSignature<P>[Key];
      } & OmitIndexSignature<EmitHandlerProps<E>>)[KeyType];
  }>;
}

Object containing makeProps and emits functions

NameType
emitsEmitFunctions<E>
makePropsPropFactory<{ [KeyType in string | number | symbol]: ({ [Key in string | number | symbol as Key extends keyof PickIndexSignature<EmitHandlerProps<E>> ? never : Key]: PickIndexSignature<P>[Key] } & PickIndexSignature<EmitHandlerProps<E>> & { [Key in string | number | symbol as Key extends keyof OmitIndexSignature<EmitHandlerProps<E>> ? never : Key]: OmitIndexSignature<P>[Key] } & OmitIndexSignature<EmitHandlerProps<E>>)[KeyType] }>

Example

typescript
// Define your component props and emits
const componentProps = {
  value: String,
  disabled: Boolean,
};

const componentEmits = {
  "update:modelValue": (value: string) => typeof value === "string",
  "item:selected": (item: Item) => item && typeof item.id === "string",
};

// Create factories
const { makeProps, emits } = propsAndEmitsFactory(
  componentProps,
  componentEmits,
  "MyComponent",
);

// makeProps() returns props with full TypeScript intellisense for:
// - Original props: value, disabled
// - Generated emit handlers: onUpdate:modelValue, onUpdateModelValue, onItem:selected, onItemSelected
export default defineComponent({
  props: makeProps(),
  emits,
  setup(props, { emit }) {
    // All props are properly typed including emit handlers
    props.onUpdateModelValue?.(newValue);
    emit("update:modelValue", newValue);
  },
});

// Template supports both syntaxes:
// <MyComponent :onUpdate:modelValue="handler" />
// <MyComponent :onUpdate:model-value="handler" />
// <MyComponent :onItem:selected="handler" />
// <MyComponent :onItem:item-selected="handler" />