使用TypeScript在Vue.js 3中输入 prop

kwvwclae  于 2023-03-03  发布在  Vue.js
关注(0)|答案(7)|浏览(357)

我尝试在Vue3组件中输入提示我的 prop ,使用组合API.
所以,我这么做:

<script lang="ts">
import FlashInterface from '@/interfaces/FlashInterface';
import { ref } from 'vue';
import { useStore } from 'vuex';

export default {
    props: {
        message: {
            type: FlashInterface,
            required: true
        }
    },
    setup(props): Record<string, unknown> {
        // Stuff
    }
};

我的FlashInterface如下所示:

export default interface FlashInterface {
    level: string,
    message: string,
    id?: string
}

这个接口工作正常,除了在这种情况下,我得到了这个错误:

ERROR in src/components/Flash.vue:20:10
TS2693: 'FlashInterface' only refers to a type, but is being used as a value here.
    18 |    props: {
    19 |        message: {
  > 20 |            type: FlashInterface,
       |                  ^^^^^^^^^^^^^^
    21 |            required: true
    22 |        }
    23 |    },

我不明白为什么TypeScript认为这是一个值。
我错过了什么?

jljoyd4f

jljoyd4f1#

您应该将其与从vue导入的PropType一起使用,例如Object as PropType<FlashInterface>

import FlashInterface from '@/interfaces/FlashInterface';
import { ref,PropType, defineComponent } from 'vue';
import { useStore } from 'vuex';

export default defineComponent({
    props: {
        message: {
            type: Object as PropType<FlashInterface>,
            required: true
        }
    },
    setup(props) {
            // Stuff
        }
});

**注意:**您应该使用defineComponent创建组件,以便获得类型推断。
脚本设置

您可以使用defineProps函数以两种方式定义props,但您应该在脚本设置中声明类型/接口,如下所述:

<script setup lang="ts">

import { ref,PropType, defineComponent , defineProps} from 'vue';
interface FlashInterface {
    level: string,
    message: string,
    id?: string
}
interface IProps{
   message : FlashInterface
}
const props = defineProps<IProps>()

<script setup lang="ts">
...
interface FlashInterface {
    level: string,
    message: string,
    id?: string
}
const props = defineProps({
        message: {
            type: Object as PropType<FlashInterface>,
            required: true
        }
    })
s1ag04yj

s1ag04yj2#

编译器抱怨在类型检查过程中缺少对(自定义)构造函数的引用(链接到遗留文档,但与最新版本的Vue工作方式相同)。
在Typescript中,您可能希望将接口视为实体应该遵守的契约,因此它们不是真正的构造函数,因此,我们需要提供这些接口的实现
由于您使用的是Typescript,因此如果需要保留接口,请考虑使用等效的类:

// Name the constructor whatever you like,
// but I would personally prefix interfaces with an "I"
// to distinguish them with the constructors

class Flash implements FlashInterface {
  level: string;
  message: string;
  id?: string

  constructor() {
    // Be sure to initialize the values for non-nullable props
    this.level = '';
    this.message = '';
  }
}

export default {
  name: 'Home',

  props: {
    message: Flash
  }
}

摘自该文档:
此外,type也可以是自定义构造函数,并且将使用instanceof检查进行Assert。例如,假设存在以下构造函数:

props: {
  message: {
    type: function Person(firstName, lastName) {
      this.firstName = firstName
      this.lastName = lastName
    }
  }
}

当然,另一种选择是在PropType的另一篇文章中建议的,任何一种都可以,我想这只是一个偏好的问题。

wqsoz72f

wqsoz72f3#

两个内衬

<script setup lang="ts">
import FlashInterface from '@/interfaces/FlashInterface';
defineProps<{flash: FlashInterface;}>();
</script>
wfsdck30

wfsdck304#

我们应该使用'vue'中的PropType作为开发人员手动创建的接口并定义默认值!

import FlashInterface from '@/interfaces/FlashInterface';
import { ref,PropType, defineComponent } from 'vue';
import { useStore } from 'vuex';

export default defineComponent({
   props: {
       message: {
           type: Object as PropType<FlashInterface>,
           default: {}
       }
   },
// stuff
});
enxuqcxy

enxuqcxy5#

您可以使用设置脚本来定义您的 prop

<script setup lang="ts">
import { ref } from 'vue';
import { useStore } from 'vuex';
interface FlashInterface {
    level: string,
    message: string,
    id?: string
}
interface Props{
   message:FlashInterface
}
const props = defineProps<Props>()

有关详细信息:Vue文档

velaa5lx

velaa5lx6#

我有一个想法,可以通过引入一个通用的props类型和一个函数来强制正确实现props来解决这个问题。

type TypedProps<T> = {
  [key in keyof T]: {
     type: PropType<T[key]>
     required?: boolean
  } | PropType<T[key]>
}

function typedProps<T extends object>(props: TypedProps<T>): TypedProps<T> {
  return props
}

我会像这样在defineComponents中使用它

interface MyProps {
  prop1: string
  prop2: CustomInterface
}
export default defineComponent({
  props: typedProps<MyProps>({
    prop1: String,
    prop2: Object as PropType<CustomInterface>
  })
})

虽然,它并不能像预期的那样与required键一起工作。也许有人可以解释原因或提出更正。

2fjabf4q

2fjabf4q7#

Object as PropType给我的印象是古怪的、几乎无法记忆的语法。输入属性的一个更好的方法是在defineProps调用中内联一个泛型类型参数,因此,使用<script setup lang="ts"> ...

const props = defineProps<{ message: FlashInterface }>()

相关问题