## 事象
[[値オブジェクト]]を実装した[[クラス (JavaScript)|クラス]] `ValueObject` が存在し、`<script setup>`内に以下の実装がされているとき
```ts
interface State {
id: number,
vo: ValueObject,
}
const state = reactive<State>({
id: 1,
vo: ValueObject.of(),
});
```
`<template>`内で以下のようなコードを書くと型エラーになる。
```html
<some-component :value="state.vo" />
```
## 原因
`reactive<T>`で指定した`T`は、`reactive<T>(...)`の戻り値ではないから。戻り値は`UnwrapNestedRefs<T>`であり、定義は以下の通り。
```ts
export declare type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>;
export declare interface Ref<T = any> {
value: T;
[RefSymbol]: true;
}
declare type UnwrapRefSimple<T> = T extends Function | CollectionTypes | BaseTypes | Ref | RefUnwrapBailTypes[keyof RefUnwrapBailTypes] | {
[RawSymbol]?: true;
} ? T : T extends ReadonlyArray<any> ? {
[K in keyof T]: UnwrapRefSimple<T[K]>;
} : T extends object & {
[ShallowReactiveMarker]?: never;
} ? {
[P in keyof T]: P extends symbol ? T[P] : UnwrapRef<T[P]>;
} : T;
```
簡潔に言うと `unwrap()` すなわち、`value`の[[プロパティ (TypeScript)|プロパティ]]を持つものの値をひっぺがえすような型定義。
## 解決方法
[[型アサーション (TypeScript)|型アサーション]]で明示する。
```ts
const state = reactive<State>({
id: 1,
vo: ValueObject.of(),
}) as State;
```
> [!warning]
> 今のところ、この型判定で実行時の挙動が問題になったことはないが、保証はされない。自己判断で利用すること。
> [!warning]
> この方法を使うと`<template>`内で補完が表示されなくなる (少なくとも[[IntelliJ IDEA]]の場合)