## 事象 [[値オブジェクト]]を実装した[[クラス (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]]の場合)