8000 Object with Generic Properties makes the properties optional · Issue #3334 · colinhacks/zod · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Object with Generic Properties makes the properties optional #3334

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

Open
agarwalvaibhav0211 opened this issue Mar 18, 2024 · 5 comments
Open

Comments

@agarwalvaibhav0211
Copy link
agarwalvaibhav0211 commented Mar 18, 2024

In the following code, if I use generic parameters to create some validators, as in ValidatorFactory, this makes all the non static properties optional. Is this a limitation on Typescript or Zod?

import { AnyZodObject, ZodType, z } from "zod";

type allowedStandardStringEnum=Record<string, string>
type EnumValues<Enum extends allowedStandardStringEnum> = Enum[keyof Enum]

function stringEnumValidator<Enum extends allowedStandardStringEnum>(enumParam:Enum):ZodType<EnumValues<Enum>>{
	return z.nativeEnum(enumParam);
}

function ValidatorFactory<StateEnum extends allowedStandardStringEnum, ZodDataObject extends AnyZodObject>(
	states:StateEnum,
	validator:ZodDataObject,
){
	return z.object({
    staticProp: z.string(),
		currentState    : stringEnumValidator(states),
		dataForFunction : z.unknown(),
		stateData       : validator,
	})
}

type FactoryReturn<StateEnum extends allowedStandardStringEnum, ZodDataObject extends AnyZodObject>=z.infer<ReturnType<typeof ValidatorFactory<StateEnum,ZodDataObject>>>


function execution<StateEnum extends allowedStandardStringEnum, ZodDataObject extends AnyZodObject>(instance:FactoryReturn<StateEnum, ZodDataObject>){
  let staticProp=instance.staticProp                // Correct
  let currentState=instance.currentState            // Incorrect
  let dataForFunction=instance.dataForFunction      // Incorrect
  let stateData=instance.stateData                  // Incorrect
}

I believe it may also be similar to #2077

Also believing that it may be caused by #3330, I can verify that "strict":true has been set in tsconfig.json

Thanks in Advance for any help

@YogaLin
Copy link
YogaLin commented Mar 20, 2024

Same here, but then I found out compilerOptions.strictNullChecks was set to false by another tsconfig.json file I extend. Setting "strict": true, "strictNullChecks": true solve my problem. @agarwalvaibhav0211 I hope this helpful.

@agarwalvaibhav0211
Copy link
Author

@YogaLin, While debugging further, I came across something weird, that it's actually the reverse for me. Setting "strict":true causes the data to be optional while setting "strict":false makes it required as expected. I've created 2 live codes you can check below (you can check line 55 on src/index.ts and line 11 of tsconfig.json in both sandboxes). Do you know if there is something wrong with what I'm doing??

strict:true

strict:false

@Charly-xepelin
Copy link

Having similar issue, the following schema (without any generic):

const sample = z.object({
    name: z.string(),
});

export type SampleInfer = z.infer<typeof sample>;

Produces the type with name as optional:
image

Actual:

type SampleInfer {
  name?: string;
}

expected:

type SampleInfer {
  name: string;
}

tsconfig.json:

{
  "$schema": "https://json.schemastore.org/tsconfig",

  "compilerOptions": {
    "composite": false,
    "esModuleInterop": true,
    "isolatedModules": true,
    "moduleResolution": "node",
    "noImplicitAny": true,
    "noImplicitThis": false,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "resolveJsonModule": true,
    "strict": true,
    "baseUrl": "./",
    "paths": {
      "@root/*": ["src/*"],
      "@features/*": ["src/features/*"],
      "@shared/*": ["src/shared/*"]
    },

    "allowSyntheticDefaultImports": true,
    "rootDir": ".",
    "declaration": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": false,
    "incremental": true,
    "module": "commonjs",
    "noFallthroughCasesInSwitch": false,
    "outDir": "./dist",
    "removeComments": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strictBindCallApply": false,
    "strictNullChecks": false,
    "target": "es2022"
  },
  "exclude": ["node_modules", "./dist"]
}

@Charly-xepelin
Copy link

Changing to "strictNullChecks": true solves the issue.

@Sweet-KK
Copy link

strictNullChecks
This has led to another extreme where everything has become mandatory. Even if I add "optional", what is expected to be optional is still mandatory, and vice versa.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
0