Subscribe on changes!

typescript use the interface to define prop and emit

avatar
Sep 11th 2021

What problem does this feature solve?

component.d.ts

import {
  DefineComponent,
  RenderFunction,
  SetupContext,
} from '@vue/runtime-core';

export declare type Emits<T> = {
  [K in keyof T as `on${Capitalize<K & string>}`]?: T[K];
};

export declare type KeyNames<T> = {
  [K in keyof T]: `${K & string}`;
}[keyof T];

export declare interface DefineComponentOption<P, E, R> {
  name?: string;
  props?: Array<KeyNames<P>> | Record<KeyNames<P>, any>;
  emits?: Array<KeyNames<E>> | Record<KeyNames<P>, any>;
  setup?: (
    props: Readonly<P>,
    ctx: SetupContext<Required<E>>,
  ) => R | RenderFunction;
}

export declare function defineComponent<P, E, R = Record<string, unknown>>(
  options: DefineComponentOption<P, E, R>,
): DefineComponent<P & Emits<E>, R>;

What does the proposed API look like?

example Button.tsx

export interface ButtonProps  {
  label?: string;
}

export interface ButtonEmits {
  click: (value?: string) => void;
  close: () => void;
}

export  default defineComponent({
  name: 'Button',
  props: ['label'],
  emits: ['click', 'close'],
  setup(props: ButtonProps, { emit }: SetupContext<ButtonEmits>) {
    return () => (<></>);
  },
});

VButton.tsx

import { ButtonProps , ButtonEmits } form './Button';

export interface VButtonProps extends ButtonProps  {
  color?: string;
}

export interface VButtonEmits extends Omit<ButtonEmits, 'close'> {}

export default defineComponent({
  name: 'VButton',
  props: ['label','color'],
  emits: ['click'],
  setup(props: VButtonProps, { emit }: SetupContext<VButtonEmits>) {
    return () => (<></>);
  },
});
avatar
Sep 11th 2021

duplicate of #4294 ?

avatar
Sep 11th 2021

not script-setup

avatar
Sep 12th 2021

Duplicate of https://github.com/vuejs/vue-next/issues/4408

Please, take the time to explain what you are trying to achieve instead of just copy-pasting big chunks or code and letting maintainers try to guess.