I'm migrating some Vue3 code from javascript to typescript, and I just can't seem to understand what's going on with the unwrapping of a ref/computed value in the template.
It was my understanding that the template would always auto-unwrap reactive properties, but it doesn't seem to be the case anymore.

下面是我的代码:

<script setup lang="ts">
import { ref } from 'vue';

class BaseBlock {
  style = ref('color: black')
}

interface IRefBlockKey {
  [key: string]: BaseBlock;
}

let Block = new BaseBlock();
let refBlock = ref(new BaseBlock());
let refWithKeyBlock = ref({ myBlock: new BaseBlock() });
let refWithInterface = ref<IRefBlockKey>({ myBlock: new BaseBlock() });
</script>

<template>
  <div :style="Block.style">Error in IDE</div>
  <div :style="Block.style.value">No Error</div>
  <div :style="refBlock.style">No Error</div>
  <div :style="refWithKeyBlock['myBlock'].style">No Error (ok...?)</div>
  <div :style="refWithInterface['myBlock'].style">Error in IDE (why now!!)</div>
</template>

In both the first and the last div, I get an IDE error Type 'Ref<string>' is not assignable to type 'StyleValue | undefined'..
The first div not working is already making me feel very disoriented, but the last one is really a huge "???" for me.

谁能给我指个正确的方向,让我明白发生了什么事?

推荐答案

因此,有三种可能的解决方案来解决这个问题.

最好的一个:

使用可组合对象而不是类来重构一切.使用与之前相同的代码,它将变为:

<script setup lang="ts">
import { ref } from 'vue';

function useBaseBlock() {
  style = ref<string>('color: black')
  return { style }
}

type IRefBlockKey = {
  [key: string]: {style: Ref<string> | string};
}

let refWithInterface = ref<IRefBlockKey>({ myBlock: useBaseBlock()});
</script>

<template>
  <div :style="refWithInterface['myBlock'].style">This works now</div>
</template>

请注意,类型现在是Ref<string> | string-如果您想使用Reactive而不是ref来包装"块",string就足够了.

肮脏的那个

Simply wrap refWithInterface['myBlock'].style using unref:
unref(refWithInterface['myBlock'].style) White this works, it's certainly not ideal.

他们不能在家里这样做,一:

style属性接受三种类型:CSSProperty(从技术上讲,它的变体,取决于元素),string和undefined.你可以在这里添加你的类型,例如Ref<string>,这样IDE就很高兴了,但这是一个可怕的解决方案,所以... don't do it!

Typescript相关问答推荐

创建一个将任意命名类型映射到其他类型的TypScript通用类型

将对象属性路径描述为字符串数组的类型

TypeScript泛型参数抛出错误—?&#"' 39;预期"

JS Redux Devtools扩展不工作

基于平台的重定向,Angular 为16

在类型脚本中的泛型类上扩展的可选参数

如何将泛型对象作为返回类型添加到类型脚本中

如何调整对象 struct 复杂的脚本函数的泛型类型?

为什么我的一个合成函数不能推断类型?

如何使用Geojson模块和@Types/Geojson类型解析TypeScrip中的GeoJSON?

类型TTextKey不能用于索引类型 ;TOption

在HighChats列时间序列图中,十字准线未按预期工作

垫表页脚角v15

如何通过属性名在两个泛型数组中找到匹配的对象?

创建一个TypeScrip对象并基于来自输入对象的约束定义其类型

有没有一种简单的方法可以访问Keyboard Shortcuts JSON文件中列出的每个命令的显示名称(标题)?

如何限定索引值必须与相应属性的id字段相同

具有枚举泛型类型的 Typescript 对象数组

Typescript 确保通用对象不包含属性

有没有办法从不同长度的元组的联合中提取带有类型的最后一个元素?