Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pluginZod: Type x is not assignable to type x #1471

Open
nimo23 opened this issue Dec 16, 2024 · 3 comments
Open

pluginZod: Type x is not assignable to type x #1471

nimo23 opened this issue Dec 16, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@nimo23
Copy link

nimo23 commented Dec 16, 2024

What version of kubb is running?

3.3.3

What kind of platform do you use?

MacOS

How does your kubb.config.ts config look like

..
pluginTs({
..
    syntaxType: 'type',
    enumType: "enum",
    enumSuffix: '',
    dateType: 'date',
    unknownType: 'unknown',
    oasType: false,
}),
pluginZod({
..
    typed: true,
    dateType: 'stringOffset',
    unknownType: 'unknown',
}),

Swagger/OpenAPI file?

A task object:

{
	"type" : "object",
	"properties" : {
		"id" : {
			"type" : "string",
			"readOnly" : true
		},
		"beginTime" : {
			"type" : "string",
			"format" : "date-time",
			"examples" : [
				"2022-03-10T16:15:50Z"
			],
			"x-readme-ref-name" : "Instant",
			"readOnly" : true
		},
		"taskStatus" : {
			"type" : "string",
			"enum" : [
				"STARTED",
				"STOPPED",
				"PAUSED"
			],
			"x-readme-ref-name" : "TaskStatus"
		}
	},
	"x-readme-ref-name" : "Task"
}

with a TaskStatus:

{
	"type" : "string",
	"enum" : [
		"STARTED",
		"STOPPED",
		"PAUSED"
	],
	"x-readme-ref-name" : "TaskStatus"
}

What version of external packages are you using(@tanstack-query, MSW, React, Vue, ...)

"react": "^19.0.0",
"zod": "^3.24.1"

What steps can reproduce the bug?

  1. create the Zod schema of the task object with pluginZod
  2. look into the taskSchema.ts
  3. the typescript compiler will return an error on props which are an object type (in this case: Date) or an enum type (primitive types, e.g. task.id works as usual)

How often does this bug happen?

Every time

What is the expected behavior?

No compiler errors in zod schemas.

Additional information

These are the ts files generated by pluginTs:

Task.ts:

import type { Instant } from './Instant.ts'
import type { TaskStatus } from './TaskStatus.ts'

export type Task = {
  /**
   * @type string
   */
  readonly id: string
  /**
   * @type string | undefined, date-time
   */
  beginTime?: Instant
  /**
   * @type string | undefined
   */
  taskStatus?: TaskStatus
}

TaskStatus.ts:

export enum TaskStatus {
  'STARTED' = 'STARTED',
  'STOPPED' = 'STOPPED',
  'PAUSED' = 'PAUSED'
}

Instant.ts:

export type Instant = Date

and these are the zod schemas generated by pluginZod:

taskStatusSchema.ts:

import { z } from 'zod'

export const taskStatusSchema = z.enum(['STARTED', 'STOPPED', 'PAUSED'])

instantSchema.ts:

import { z } from 'zod'

export const instantSchema = z.string().datetime({ offset: true })

taskSchema.ts:

import type { Task } from '../types/Task.ts'
import type { ToZod } from '@kubb/plugin-zod/utils'
import { instantSchema } from './instantSchema.ts'
import { taskStatusSchema } from './taskStatusSchema.ts'
import { z } from 'zod'

export const taskSchema = z.object({
  id: z.string(),
  beginTime: z.lazy(() => instantSchema).optional(),
  taskStatus: z.lazy(() => taskStatusSchema).optional(),
} satisfies ToZod<Task>)

For taskSchema.beginTime, I get the following typescript compiler error:

Type 'ZodOptional<ZodLazy<ZodString>>' is not assignable to type 'ZodWithEffects<ZodOptional<ZodType<Date, ZodTypeDef, Date>>> | ZodWithEffects<ZodDefault<ZodType<Date, ZodTypeDef, Date>>>'.
  Type 'ZodOptional<ZodLazy<ZodString>>' is not assignable to type 'ZodOptional<ZodType<Date, ZodTypeDef, Date>>'.
    Type 'ZodLazy<ZodString>' is not assignable to type 'ZodType<Date, ZodTypeDef, Date>'.
      Types of property '_type' are incompatible.
        Type 'string' is not assignable to type 'Date'. [2322]

For taskSchema.taskStatus, I get the following typescript compiler error:

Type 'ZodOptional<ZodLazy<ZodEnum<["STARTED", "STOPPED", "PAUSED"]>>>' is not assignable to type 'ZodWithEffects<ZodOptional<ZodType<TaskStatus, ZodTypeDef, TaskStatus>>> | ZodWithEffects<ZodDefault<ZodType<TaskStatus, ZodTypeDef, TaskStatus>>>'.
  Type 'ZodOptional<ZodLazy<ZodEnum<["STARTED", "STOPPED", "PAUSED"]>>>' is not assignable to type 'ZodOptional<ZodType<TaskStatus, ZodTypeDef, TaskStatus>> | ZodEffects<ZodOptional<ZodType<TaskStatus, ZodTypeDef, TaskStatus>>, any, any> | ZodEffects<...>'.
    Type 'ZodOptional<ZodLazy<ZodEnum<["STARTED", "STOPPED", "PAUSED"]>>>' is not assignable to type 'ZodOptional<ZodType<TaskStatus, ZodTypeDef, TaskStatus>>'.
      Type 'ZodLazy<ZodEnum<["STARTED", "STOPPED", "PAUSED"]>>' is not assignable to type 'ZodType<TaskStatus, ZodTypeDef, TaskStatus>'.
        Types of property '_type' are incompatible.
          Type '"STARTED" | "STOPPED" | "PAUSED"' is not assignable to type 'TaskStatus'.
            Type '"STARTED"' is not assignable to type 'TaskStatus'. [2322]
@nimo23 nimo23 added the bug Something isn't working label Dec 16, 2024
@stijnvanhulle
Copy link
Collaborator

When you use typed: true,, Kubb will add satisfies ToZod<TYPE>. But if dateType for pluginTs is different from the one in pluginZod, then TypeScript will complain. We could make it as a cast but that will probably give another type then it should be. Could you try by using the samedateType?

@stijnvanhulle stijnvanhulle self-assigned this Dec 16, 2024
@nimo23
Copy link
Author

nimo23 commented Dec 16, 2024

But if dateType for pluginTs is different from the one in pluginZod,

Yes, for the dateTime-issue it works. I changed it to:

pluginTs({
    dateType: 'string'
    ..
})
pluginZod({
    dateType: 'stringOffset' // stringOffset is also string
    ..
})

The taskSchema.beginTime property no longer causes a Typescript compiler error. I wonder if it would make sense to support Date() (and not just strings) for pluginZod.dateType:

pluginTs({
    dateType: 'date'
    ..
})
pluginZod({
    // Currently not possible - Are there any disadvantages to be expected?
    dateType: 'date' 
    ..
})

@stijnvanhulle
Copy link
Collaborator

@nimo23 Normally dateType: date should be possible, see https://www.kubb.dev/plugins/plugin-zod/#datetype. If set to date, Zod will use z.date()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants