如何使用 Typescript 在 Composition API 中正确声明静态引用?
How to correctly declare static refs in Composition API using Typescript?
我正在使用组合 API(使用 <script setup lang='ts'>
)创建一个引用,用于我的模板:
const searchRef = ref(null)
onMounted(() => { searchRef.value.focus() })
它确实有效,我的代码编译没有错误。然而,IDE(JetBrains Goland 或 Webstorm)抱怨 TS2531: Object is possibly 'null'.
。
核心解决方案是使用
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Object is possibly 'null'.
但是想了解一下有没有更好的办法
我希望 optional chaining 成为一个解决方案:
const searchRef = ref(null)
onMounted(() => { searchRef.value?.focus() })
代码仍然可以编译,应用程序仍然可以运行,但我现在 TS2339: Property 'focus' does not exist on type 'never'.
解决这个问题的正确方法是什么?
解决此问题的一种可能方法是手动添加正确的类型:
const searchRef: Ref<HTMLElement | null> = ref(null);
onMounted(() => { searchRef.value?.focus() });
注意:如果 ref 以 Vue 组件为目标(例如 Ref<HTMLElement | Vue | null>
),HTMLElement 可能会有所不同。
对于模板引用,在初始化时将通用类型参数传递给 ref
。通用类型应与模板引用的目标元素的类型相匹配。
以下是本机 HTML 元素上模板引用的一些示例:
const htmlElemRef = ref<HTMLElement>() // => type: HTMLElement | undefined
const inputRef = ref<HTMLInputElement>() // => type: HTMLInputElement | undefined
const textareaRef = ref<HTMLTextAreaElement>() // => type: HTMLTextAreaElement | undefined
null
初始化是可选的,我经常省略它以获得更简洁的代码。结果类型是 <T | undefined>
,它比 null
更正确,因为如果模板中不存在元素,ref
实际上是 undefined
。 ref
的值仍然需要可选链接(假设它可能是 undefined
)。
示例:
const searchRef = ref<HTMLInputElement>()
onMounted(() => { searchRef.value?.focus() })
正如@Kurt 所指出的,Vue 组件上的模板引用需要不同的类型。 ref
的通用类型是 InstanceType
of the component's type (from a .vue
import) (docs):
InstanceType<typeof MyComponentDefinition>
示例:
import HelloWorld from '@/components/HelloWorld.vue'
const helloRef = ref<InstanceType<typeof HelloWorld>>()
注意:要在 TypeScript 文件中使用 Volar 而不是 Vue SFC,请确保启用 Volar's Takeover Mode.
我正在使用组合 API(使用 <script setup lang='ts'>
)创建一个引用,用于我的模板:
const searchRef = ref(null)
onMounted(() => { searchRef.value.focus() })
它确实有效,我的代码编译没有错误。然而,IDE(JetBrains Goland 或 Webstorm)抱怨 TS2531: Object is possibly 'null'.
。
核心解决方案是使用
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Object is possibly 'null'.
但是想了解一下有没有更好的办法
我希望 optional chaining 成为一个解决方案:
const searchRef = ref(null)
onMounted(() => { searchRef.value?.focus() })
代码仍然可以编译,应用程序仍然可以运行,但我现在 TS2339: Property 'focus' does not exist on type 'never'.
解决这个问题的正确方法是什么?
解决此问题的一种可能方法是手动添加正确的类型:
const searchRef: Ref<HTMLElement | null> = ref(null);
onMounted(() => { searchRef.value?.focus() });
注意:如果 ref 以 Vue 组件为目标(例如 Ref<HTMLElement | Vue | null>
),HTMLElement 可能会有所不同。
对于模板引用,在初始化时将通用类型参数传递给 ref
。通用类型应与模板引用的目标元素的类型相匹配。
以下是本机 HTML 元素上模板引用的一些示例:
const htmlElemRef = ref<HTMLElement>() // => type: HTMLElement | undefined
const inputRef = ref<HTMLInputElement>() // => type: HTMLInputElement | undefined
const textareaRef = ref<HTMLTextAreaElement>() // => type: HTMLTextAreaElement | undefined
null
初始化是可选的,我经常省略它以获得更简洁的代码。结果类型是 <T | undefined>
,它比 null
更正确,因为如果模板中不存在元素,ref
实际上是 undefined
。 ref
的值仍然需要可选链接(假设它可能是 undefined
)。
示例:
const searchRef = ref<HTMLInputElement>()
onMounted(() => { searchRef.value?.focus() })
正如@Kurt 所指出的,Vue 组件上的模板引用需要不同的类型。 ref
的通用类型是 InstanceType
of the component's type (from a .vue
import) (docs):
InstanceType<typeof MyComponentDefinition>
示例:
import HelloWorld from '@/components/HelloWorld.vue'
const helloRef = ref<InstanceType<typeof HelloWorld>>()
注意:要在 TypeScript 文件中使用 Volar 而不是 Vue SFC,请确保启用 Volar's Takeover Mode.