Skip to content

Imported refs used in v-if trigger "Object is possibly 'undefined'" error #4663

@amw

Description

@amw

Version

3.2.14

Reproduction link

github.com/amw/vue-repro

Steps to reproduce

I needed to paste link to separate reproduction repository, because the SFC Playground does not seem to be performing type-checking. It's probably running in transpile-only mode.

I'm not sure whether this is problem with Vue compiler or TypeScript type checking, but there is a difference whether you assign a Ref const inside <script lang="ts" setup> directly or via some function's return value.

const titled1 = ref<Titled>()
const titled2 = innerSetup() as Ref<Titled | undefined>

In theory they both have the same type, but Vue compiler treats them differently when used in template like:

    <h1 v-if="titled1">{{ titled1.title }}</h1>
    <h1 v-if="titled2">{{ titled2.title }}</h1>

The resulting TypeScript is:

    (titled1.value)
      ? (_openBlock(), _createElementBlock("h1", _hoisted_1, _toDisplayString(titled1.value.title), 1 /* TEXT */))
      : _createCommentVNode("v-if", true),
    (_unref(titled2))
      ? (_openBlock(), _createElementBlock("h1", _hoisted_2, _toDisplayString(_unref(titled2).title), 1 /* TEXT */))
      : _createCommentVNode("v-if", true)

The first conditional is correctly understood by tsc, but the second one yields error:

src/App.ts:38:79 - error TS2532: Object is possibly 'undefined'.

38       ? (_openBlock(), _createElementBlock("h1", _hoisted_2, _toDisplayString(_unref(titled2).title), 1 /* TEXT */))
                                                                                 ~~~~~~~~~~~~~~~


Found 1 error.

Now, this might be a bug of TypeScript, because it should understand that if _unref(titled2) is truthy then it is an instance of Titled just like it does for titled1.value. But whether it's TS bug or not it is a Vue problem. I have found no workaround for this other than using titled2?.title in the template, but that kills the benefit of the type check.

What is expected?

We should be able to use const a = f() as Ref<Type | undefined> in template conditions.

What is actually happening?

Compiling template fails.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions