Skip to content

Instantly share code, notes, and snippets.

@aiya000
Created March 14, 2025 17:29
Show Gist options
  • Save aiya000/a4d5b06e495afd1e0db54791c5595033 to your computer and use it in GitHub Desktop.
Save aiya000/a4d5b06e495afd1e0db54791c5595033 to your computer and use it in GitHub Desktop.
zodにも限界がある例
import { toRaw } from 'vue'
import { z } from 'zod'
/**
* ```typescript
* import { ref } from 'vue'
* const x = ref({ a: { b: 42 } })
* // const y = structureClone(toRaw(x.value)) // 深いProxy(x.value.a.b)を除去できずに例外が出る
* const y = structureClone(toRawDeep(x.value)) // OK
* ```
*/
export const toRawDeep = <T>(ref: T, schema: z.ZodType<T>): T => {
const raw = toRaw(ref)
if (Array.isArray(raw)) {
// return raw.map(toRawDeep) as T // `as`を使いたくないのでzodを使おうとするが…
return schema.parse(
raw.map((x) => toRawDeep(x, schema.element())) // schemaがZodArrayであることを正当化できない
)
}
if (raw === null) {
return null as T
}
if (raw === undefined) {
return undefined as T
}
if (typeof raw === 'object') {
const entries = Object.entries(raw).map(([key, raw]) => [
key,
toRawDeep(raw),
])
return Object.fromEntries(entries)
}
return raw
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment