feat: add zod (#17277)

This commit is contained in:
Joel
2025-04-01 18:10:11 +08:00
committed by GitHub
parent 713902dc47
commit b4aa1900e2
3 changed files with 237 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import { z } from 'zod'
import withValidation from '.'
describe('withValidation HOC', () => {
// schema for validation
const schema = z.object({ name: z.string() })
type Props = z.infer<typeof schema> & {
age: number
}
const TestComponent = ({ name, age }: Props) => (
<div>{name} - {age}</div>
)
const WrappedComponent = withValidation(TestComponent, schema)
beforeAll(() => {
jest.spyOn(console, 'error').mockImplementation(() => { })
})
afterAll(() => {
jest.restoreAllMocks()
})
it('renders the component when validation passes', () => {
render(<WrappedComponent name='Valid Name' age={30} />)
expect(screen.getByText('Valid Name - 30')).toBeInTheDocument()
})
it('renders the component when props is invalid but not in schema ', () => {
render(<WrappedComponent name='Valid Name' age={'aaa' as any} />)
expect(screen.getByText('Valid Name - aaa')).toBeInTheDocument()
})
it('does not render the component when validation fails', () => {
render(<WrappedComponent name={123 as any} age={30} />)
expect(screen.queryByText('123 - 30')).toBeNull()
})
})

View File

@@ -0,0 +1,24 @@
'use client'
import React from 'react'
import type { ZodSchema } from 'zod'
function withValidation<T extends Record<string, unknown>, K extends keyof T>(
WrappedComponent: React.ComponentType<T>,
schema: ZodSchema<Pick<T, K>>,
) {
return function EnsuredComponent(props: T) {
const partialProps = Object.fromEntries(
Object.entries(props).filter(([key]) => key in (schema._def as any).shape),
) as Pick<T, K>
const checkRes = schema.safeParse(partialProps)
if (!checkRes.success) {
console.error(checkRes.error)
// Maybe there is a better way to handle this, like error logic placeholder
return null
}
return <WrappedComponent {...props} />
}
}
export default withValidation