diff --git a/codegen.yml b/codegen.yml
index f56baf9b..00f78617 100644
--- a/codegen.yml
+++ b/codegen.yml
@@ -9,6 +9,7 @@ generates:
       - ./dist/main/index.js:
           schema: yup
           importFrom: ../types
+          useObjectTypes: true
           directives:
             required:
               msg: required
@@ -42,6 +43,7 @@ generates:
       - ./dist/main/index.js:
           schema: zod
           importFrom: ../types
+          useObjectTypes: true
           directives:
             # Write directives like
             #
@@ -62,6 +64,7 @@ generates:
       - ./dist/main/index.js:
           schema: myzod
           importFrom: ../types
+          useObjectTypes: true
           directives:
             constraint:
               minLength: min
diff --git a/example/myzod/schemas.ts b/example/myzod/schemas.ts
index b953fa98..8cac6fdb 100644
--- a/example/myzod/schemas.ts
+++ b/example/myzod/schemas.ts
@@ -1,5 +1,5 @@
 import * as myzod from 'myzod'
-import { AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, HttpInput, HttpMethod, LayoutInput, PageInput, PageType } from '../types'
+import { AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types'
 
 export const definedNonNullAnySchema = myzod.object({});
 
@@ -77,3 +77,15 @@ export function PageInputSchema(): myzod.Type<PageInput> {
 }
 
 export const PageTypeSchema = myzod.enum(PageType);
+
+export function UserSchema(): myzod.Type<User> {
+  return myzod.object({
+    __typename: myzod.literal('User').optional(),
+    createdAt: definedNonNullAnySchema.optional().nullable(),
+    email: myzod.string().optional().nullable(),
+    id: myzod.string().optional().nullable(),
+    name: myzod.string().optional().nullable(),
+    password: myzod.string().optional().nullable(),
+    updatedAt: definedNonNullAnySchema.optional().nullable()
+  })
+}
diff --git a/example/test.graphql b/example/test.graphql
index b5c4cfe7..93cf53b8 100644
--- a/example/test.graphql
+++ b/example/test.graphql
@@ -5,6 +5,15 @@ enum PageType {
   BASIC_AUTH
 }
 
+type User {
+  id: ID
+  name: String
+  email: String
+  password: String
+  createdAt: Date
+  updatedAt: Date
+}
+
 input PageInput {
   id: ID!
   title: String!
diff --git a/example/types.ts b/example/types.ts
index 62283b3c..b0b5bd10 100644
--- a/example/types.ts
+++ b/example/types.ts
@@ -86,3 +86,13 @@ export enum PageType {
   Restricted = 'RESTRICTED',
   Service = 'SERVICE'
 }
+
+export type User = {
+  __typename?: 'User';
+  createdAt?: Maybe<Scalars['Date']>;
+  email?: Maybe<Scalars['String']>;
+  id?: Maybe<Scalars['ID']>;
+  name?: Maybe<Scalars['String']>;
+  password?: Maybe<Scalars['String']>;
+  updatedAt?: Maybe<Scalars['Date']>;
+};
diff --git a/example/yup/schemas.ts b/example/yup/schemas.ts
index f77b3545..59d9dbd6 100644
--- a/example/yup/schemas.ts
+++ b/example/yup/schemas.ts
@@ -1,5 +1,5 @@
 import * as yup from 'yup'
-import { AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, HttpInput, HttpMethod, LayoutInput, PageInput, PageType } from '../types'
+import { AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types'
 
 export function AttributeInputSchema(): yup.SchemaOf<AttributeInput> {
   return yup.object({
@@ -75,3 +75,15 @@ export function PageInputSchema(): yup.SchemaOf<PageInput> {
 }
 
 export const PageTypeSchema = yup.mixed().oneOf([PageType.BasicAuth, PageType.Lp, PageType.Restricted, PageType.Service]);
+
+export function UserSchema(): yup.SchemaOf<User> {
+  return yup.object({
+    __typename: yup.mixed().oneOf(['User', undefined]),
+    createdAt: yup.mixed(),
+    email: yup.string(),
+    id: yup.string(),
+    name: yup.string(),
+    password: yup.string(),
+    updatedAt: yup.mixed()
+  })
+}
diff --git a/example/zod/schemas.ts b/example/zod/schemas.ts
index 7592f8e0..4f842608 100644
--- a/example/zod/schemas.ts
+++ b/example/zod/schemas.ts
@@ -1,5 +1,5 @@
 import { z } from 'zod'
-import { AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, HttpInput, HttpMethod, LayoutInput, PageInput, PageType } from '../types'
+import { AttributeInput, ButtonComponentType, ComponentInput, DropDownComponentInput, EventArgumentInput, EventInput, EventOptionType, HttpInput, HttpMethod, LayoutInput, PageInput, PageType, User } from '../types'
 
 type Properties<T> = Required<{
   [K in keyof T]: z.ZodType<T[K], any, T[K]>;
@@ -85,3 +85,15 @@ export function PageInputSchema(): z.ZodObject<Properties<PageInput>> {
 }
 
 export const PageTypeSchema = z.nativeEnum(PageType);
+
+export function UserSchema(): z.ZodObject<Properties<User>> {
+  return z.object({
+    __typename: z.literal('User').optional(),
+    createdAt: definedNonNullAnySchema.nullish(),
+    email: z.string().nullish(),
+    id: z.string().nullish(),
+    name: z.string().nullish(),
+    password: z.string().nullish(),
+    updatedAt: definedNonNullAnySchema.nullish()
+  })
+}
diff --git a/src/config.ts b/src/config.ts
index 36ff9fd7..bc5790d4 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -37,7 +37,7 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
    * @description import types from generated typescript type path
    * if not given, omit import statement.
    *
-   * @exampeMarkdown
+   * @exampleMarkdown
    * ```yml
    * generates:
    *   path/to/types.ts:
@@ -193,4 +193,22 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
    * ```
    */
   directives?: DirectiveConfig;
+  /**
+   * @description Converts the regular graphql type into a zod validation function.
+   *
+   * @exampleMarkdown
+   * ```yml
+   * generates:
+   *   path/to/types.ts:
+   *     plugins:
+   *       - typescript
+   *   path/to/schemas.ts:
+   *     plugins:
+   *       - graphql-codegen-validation-schema
+   *     config:
+   *       schema: yup
+   *       useObjectTypes: true
+   * ```
+   */
+  useObjectTypes?: boolean;
 }
diff --git a/src/myzod/index.ts b/src/myzod/index.ts
index e3bd7f97..9730fcf0 100644
--- a/src/myzod/index.ts
+++ b/src/myzod/index.ts
@@ -6,7 +6,9 @@ import {
   TypeNode,
   GraphQLSchema,
   InputObjectTypeDefinitionNode,
+  ObjectTypeDefinitionNode,
   EnumTypeDefinitionNode,
+  FieldDefinitionNode,
 } from 'graphql';
 import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
 import { TsVisitor } from '@graphql-codegen/typescript';
@@ -38,7 +40,7 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
       importTypes.push(name);
 
       const shape = node.fields
-        ?.map(field => generateInputObjectFieldMyZodSchema(config, tsVisitor, schema, field, 2))
+        ?.map(field => generateFieldMyZodSchema(config, tsVisitor, schema, field, 2))
         .join(',\n');
 
       return new DeclarationBlock({})
@@ -47,6 +49,27 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
         .withName(`${name}Schema(): myzod.Type<${name}>`)
         .withBlock([indent(`return myzod.object({`), shape, indent('})')].join('\n')).string;
     },
+    ObjectTypeDefinition: (node: ObjectTypeDefinitionNode) => {
+      if (!config.useObjectTypes) return;
+      const name = tsVisitor.convertName(node.name.value);
+      importTypes.push(name);
+
+      const shape = node.fields
+        ?.map(field => generateFieldMyZodSchema(config, tsVisitor, schema, field, 2))
+        .join(',\n');
+
+      return new DeclarationBlock({})
+        .export()
+        .asKind('function')
+        .withName(`${name}Schema(): myzod.Type<${name}>`)
+        .withBlock(
+          [
+            indent(`return myzod.object({`),
+            `    __typename: myzod.literal('${node.name.value}').optional(),\n${shape}`,
+            indent('})'),
+          ].join('\n')
+        ).string;
+    },
     EnumTypeDefinition: (node: EnumTypeDefinitionNode) => {
       const enumname = tsVisitor.convertName(node.name.value);
       importTypes.push(enumname);
@@ -69,27 +92,27 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
   };
 };
 
-const generateInputObjectFieldMyZodSchema = (
+const generateFieldMyZodSchema = (
   config: ValidationSchemaPluginConfig,
   tsVisitor: TsVisitor,
   schema: GraphQLSchema,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   indentCount: number
 ): string => {
-  const gen = generateInputObjectFieldTypeMyZodSchema(config, tsVisitor, schema, field, field.type);
+  const gen = generateFieldTypeMyZodSchema(config, tsVisitor, schema, field, field.type);
   return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount);
 };
 
-const generateInputObjectFieldTypeMyZodSchema = (
+const generateFieldTypeMyZodSchema = (
   config: ValidationSchemaPluginConfig,
   tsVisitor: TsVisitor,
   schema: GraphQLSchema,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   type: TypeNode,
   parentType?: TypeNode
 ): string => {
   if (isListType(type)) {
-    const gen = generateInputObjectFieldTypeMyZodSchema(config, tsVisitor, schema, field, type.type, type);
+    const gen = generateFieldTypeMyZodSchema(config, tsVisitor, schema, field, type.type, type);
     if (!isNonNullType(parentType)) {
       const arrayGen = `myzod.array(${maybeLazy(type.type, gen)})`;
       const maybeLazyGen = applyDirectives(config, field, arrayGen);
@@ -98,7 +121,7 @@ const generateInputObjectFieldTypeMyZodSchema = (
     return `myzod.array(${maybeLazy(type.type, gen)})`;
   }
   if (isNonNullType(type)) {
-    const gen = generateInputObjectFieldTypeMyZodSchema(config, tsVisitor, schema, field, type.type, type);
+    const gen = generateFieldTypeMyZodSchema(config, tsVisitor, schema, field, type.type, type);
     return maybeLazy(type.type, gen);
   }
   if (isNamedType(type)) {
@@ -125,7 +148,7 @@ const generateInputObjectFieldTypeMyZodSchema = (
 
 const applyDirectives = (
   config: ValidationSchemaPluginConfig,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   gen: string
 ): string => {
   if (config.directives && field.directives) {
diff --git a/src/yup/index.ts b/src/yup/index.ts
index 32adde70..08bd20d5 100644
--- a/src/yup/index.ts
+++ b/src/yup/index.ts
@@ -7,6 +7,8 @@ import {
   GraphQLSchema,
   InputObjectTypeDefinitionNode,
   EnumTypeDefinitionNode,
+  ObjectTypeDefinitionNode,
+  FieldDefinitionNode,
 } from 'graphql';
 import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
 import { TsVisitor } from '@graphql-codegen/typescript';
@@ -31,9 +33,7 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
       const name = tsVisitor.convertName(node.name.value);
       importTypes.push(name);
 
-      const shape = node.fields
-        ?.map(field => generateInputObjectFieldYupSchema(config, tsVisitor, schema, field, 2))
-        .join(',\n');
+      const shape = node.fields?.map(field => generateFieldYupSchema(config, tsVisitor, schema, field, 2)).join(',\n');
 
       return new DeclarationBlock({})
         .export()
@@ -41,6 +41,25 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
         .withName(`${name}Schema(): yup.SchemaOf<${name}>`)
         .withBlock([indent(`return yup.object({`), shape, indent('})')].join('\n')).string;
     },
+    ObjectTypeDefinition: (node: ObjectTypeDefinitionNode) => {
+      if (!config.useObjectTypes) return;
+      const name = tsVisitor.convertName(node.name.value);
+      importTypes.push(name);
+
+      const shape = node.fields?.map(field => generateFieldYupSchema(config, tsVisitor, schema, field, 2)).join(',\n');
+
+      return new DeclarationBlock({})
+        .export()
+        .asKind('function')
+        .withName(`${name}Schema(): yup.SchemaOf<${name}>`)
+        .withBlock(
+          [
+            indent(`return yup.object({`),
+            `    __typename: yup.mixed().oneOf(['${node.name.value}', undefined]),\n${shape}`,
+            indent('})'),
+          ].join('\n')
+        ).string;
+    },
     EnumTypeDefinition: (node: EnumTypeDefinitionNode) => {
       const enumname = tsVisitor.convertName(node.name.value);
       importTypes.push(enumname);
@@ -92,14 +111,14 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
   };
 };
 
-const generateInputObjectFieldYupSchema = (
+const generateFieldYupSchema = (
   config: ValidationSchemaPluginConfig,
   tsVisitor: TsVisitor,
   schema: GraphQLSchema,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   indentCount: number
 ): string => {
-  let gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, field.type);
+  let gen = generateFieldTypeYupSchema(config, tsVisitor, schema, field.type);
   if (config.directives && field.directives) {
     const formatted = formatDirectiveConfig(config.directives);
     gen += buildApi(formatted, field.directives);
@@ -107,7 +126,7 @@ const generateInputObjectFieldYupSchema = (
   return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount);
 };
 
-const generateInputObjectFieldTypeYupSchema = (
+const generateFieldTypeYupSchema = (
   config: ValidationSchemaPluginConfig,
   tsVisitor: TsVisitor,
   schema: GraphQLSchema,
@@ -115,14 +134,14 @@ const generateInputObjectFieldTypeYupSchema = (
   parentType?: TypeNode
 ): string => {
   if (isListType(type)) {
-    const gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, type.type, type);
+    const gen = generateFieldTypeYupSchema(config, tsVisitor, schema, type.type, type);
     if (!isNonNullType(parentType)) {
       return `yup.array().of(${maybeLazy(type.type, gen)}).optional()`;
     }
     return `yup.array().of(${maybeLazy(type.type, gen)})`;
   }
   if (isNonNullType(type)) {
-    const gen = generateInputObjectFieldTypeYupSchema(config, tsVisitor, schema, type.type, type);
+    const gen = generateFieldTypeYupSchema(config, tsVisitor, schema, type.type, type);
     const nonNullGen = maybeNonEmptyString(config, tsVisitor, gen, type.type);
     return maybeLazy(type.type, nonNullGen);
   }
diff --git a/src/zod/index.ts b/src/zod/index.ts
index e9e7ee68..15ebd960 100644
--- a/src/zod/index.ts
+++ b/src/zod/index.ts
@@ -6,7 +6,9 @@ import {
   TypeNode,
   GraphQLSchema,
   InputObjectTypeDefinitionNode,
+  ObjectTypeDefinitionNode,
   EnumTypeDefinitionNode,
+  FieldDefinitionNode,
 } from 'graphql';
 import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
 import { TsVisitor } from '@graphql-codegen/typescript';
@@ -53,9 +55,7 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
       const name = tsVisitor.convertName(node.name.value);
       importTypes.push(name);
 
-      const shape = node.fields
-        ?.map(field => generateInputObjectFieldZodSchema(config, tsVisitor, schema, field, 2))
-        .join(',\n');
+      const shape = node.fields?.map(field => generateFieldZodSchema(config, tsVisitor, schema, field, 2)).join(',\n');
 
       return new DeclarationBlock({})
         .export()
@@ -63,6 +63,25 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
         .withName(`${name}Schema(): z.ZodObject<Properties<${name}>>`)
         .withBlock([indent(`return z.object({`), shape, indent('})')].join('\n')).string;
     },
+    ObjectTypeDefinition: (node: ObjectTypeDefinitionNode) => {
+      if (!config.useObjectTypes) return;
+      const name = tsVisitor.convertName(node.name.value);
+      importTypes.push(name);
+
+      const shape = node.fields?.map(field => generateFieldZodSchema(config, tsVisitor, schema, field, 2)).join(',\n');
+
+      return new DeclarationBlock({})
+        .export()
+        .asKind('function')
+        .withName(`${name}Schema(): z.ZodObject<Properties<${name}>>`)
+        .withBlock(
+          [
+            indent(`return z.object({`),
+            `    __typename: z.literal('${node.name.value}').optional(),\n${shape}`,
+            indent('})'),
+          ].join('\n')
+        ).string;
+    },
     EnumTypeDefinition: (node: EnumTypeDefinitionNode) => {
       const enumname = tsVisitor.convertName(node.name.value);
       importTypes.push(enumname);
@@ -84,27 +103,27 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
   };
 };
 
-const generateInputObjectFieldZodSchema = (
+const generateFieldZodSchema = (
   config: ValidationSchemaPluginConfig,
   tsVisitor: TsVisitor,
   schema: GraphQLSchema,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   indentCount: number
 ): string => {
-  const gen = generateInputObjectFieldTypeZodSchema(config, tsVisitor, schema, field, field.type);
+  const gen = generateFieldTypeZodSchema(config, tsVisitor, schema, field, field.type);
   return indent(`${field.name.value}: ${maybeLazy(field.type, gen)}`, indentCount);
 };
 
-const generateInputObjectFieldTypeZodSchema = (
+const generateFieldTypeZodSchema = (
   config: ValidationSchemaPluginConfig,
   tsVisitor: TsVisitor,
   schema: GraphQLSchema,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   type: TypeNode,
   parentType?: TypeNode
 ): string => {
   if (isListType(type)) {
-    const gen = generateInputObjectFieldTypeZodSchema(config, tsVisitor, schema, field, type.type, type);
+    const gen = generateFieldTypeZodSchema(config, tsVisitor, schema, field, type.type, type);
     if (!isNonNullType(parentType)) {
       const arrayGen = `z.array(${maybeLazy(type.type, gen)})`;
       const maybeLazyGen = applyDirectives(config, field, arrayGen);
@@ -113,7 +132,7 @@ const generateInputObjectFieldTypeZodSchema = (
     return `z.array(${maybeLazy(type.type, gen)})`;
   }
   if (isNonNullType(type)) {
-    const gen = generateInputObjectFieldTypeZodSchema(config, tsVisitor, schema, field, type.type, type);
+    const gen = generateFieldTypeZodSchema(config, tsVisitor, schema, field, type.type, type);
     return maybeLazy(type.type, gen);
   }
   if (isNamedType(type)) {
@@ -140,7 +159,7 @@ const generateInputObjectFieldTypeZodSchema = (
 
 const applyDirectives = (
   config: ValidationSchemaPluginConfig,
-  field: InputValueDefinitionNode,
+  field: InputValueDefinitionNode | FieldDefinitionNode,
   gen: string
 ): string => {
   if (config.directives && field.directives) {