Vue 3 DefineEmits 破坏了 DefineProps 类型

Sim*_*leJ 2 javascript typescript vue.js vuejs3

我正在使用 Vue 3 和 TS 4.4。我有一个用 定义其 prop 类型的组件defineProps。当我添加对 的调用时defineEmits,VS Code 开始告诉我props组件模板中不存在我的变量。这是源代码:

<script setup lang="ts">
import { defineProps, defineEmits, VueElement, defineComponent } from "vue";

const emit = defineEmits<{
  "update:checked": boolean;
}>();

const props = defineProps<{
  label?: VueElement | string;
  checked?: boolean;
}>();
</script>

<template>
  <label>
    <input
      type="checkbox"
      :checked="props.checked"
      @change="(event) => emit('update:checked', (event.target as any)?.checked)"
    />
    {{ props.label }}
  </label>
</template>
Run Code Online (Sandbox Code Playgroud)

还有一些屏幕截图,可以更好地展示我在 VS Code 中看到的内容。这是添加后的defineEmits

VS Code TS 错误

这是没有defineEmits

VS Code 无 TS 错误

定义属性和发射类型的正确方法是什么?

ton*_*y19 18

defineEmits<T>()泛型参数本质上是一个 TypeScript 接口,它仅定义了函数,它接收特定的事件名称和可选参数:

interface Emits {
  (e: __EVENT1_NAME__ [, arg1: __ARG1_TYPE__ [, arg2: __ARG2_TYPE__]]...): void
  (e: __EVENT2_NAME__ [, arg1: __ARG1_TYPE__ [, arg2: __ARG2_TYPE__]]...): void
}
Run Code Online (Sandbox Code Playgroud)

例子:

// as inline type
const emits = defineEmits<{
  (eventName: 'hover', hovering: boolean): void
  (eventName: 'changed', newValue: number, id: string): void
}>()
Run Code Online (Sandbox Code Playgroud)
// as interface
interface Emits {
  (eventName: 'hover', hovering: boolean): void
  (eventName: 'changed', newValue: number, id: string): void
}
const emits = defineEmits<Emits>()
Run Code Online (Sandbox Code Playgroud)
// as type alias
type Emits = {
  (eventName: 'hover', hovering: boolean): void
  (eventName: 'changed', newValue: number, id: string): void
}
const emits = defineEmits<Emits>()
Run Code Online (Sandbox Code Playgroud)

对于您的update:checked活动,代码应类似于以下内容:

// as inline type
const emits = defineEmits<{
  (e: 'update:checked', checked: boolean): void
}>()
Run Code Online (Sandbox Code Playgroud)
// as interface
interface Emits {
  (e: 'update:checked', checked: boolean): void
}
const emits = defineEmits<Emits>()
Run Code Online (Sandbox Code Playgroud)
// as type alias
type Emits = {
  (e: 'update:checked', checked: boolean): void
}
const emits = defineEmits<Emits>()
Run Code Online (Sandbox Code Playgroud)