How to use yup's object.shape with typescript?
Asked Answered
Z

3

31

I'm currently converting a piece of code to TypeScript and running into a few type issues with yup types. I've tried multiple ways and referenced yup's documentation on TypeScript support to tackle this issue to no avail.

https://github.com/jquense/yup/blob/master/docs/typescript.md

Here is a sample of my code:

import { object, Asserts, string } from 'yup';

interface BaseBootstrapSchema {  
  APPLICATION_NAME: string;
  LOG_PATH: string;
}

const bootstrapValidationSchema = object<BaseBootstrapSchema>().shape({ // error 1 here
  LOG_PATH: string().required("The 'LOG_PATH' ENV variable is required"),
  APPLICATION_NAME: string().required("The 'APPLICATION_NAME' ENV variable is required"),
});

interface BootstrapSchema extends Asserts<typeof bootstrapValidationSchema> {}

module.exports = (schema: BootstrapSchema) =>
  new Promise((resolve, reject) =>
    schema
      .validate(process.env, { abortEarly: false }) // error 2 here
      .then(() => resolve(true))
      .catch((error: any) => {
        if (error.errors.length > 1) {
          reject(new Error(`${error.message},\n${error.errors.join(',\n')}`));
        } else {
          reject(new Error(error.message));
        }
      })
  );

I get the following errors:

Error 1:

Type 'BaseBootstrapSchema' does not satisfy the constraint 'Record<string, AnySchema<any, any, any> | Reference | Lazy<any, any>>'. Index signature is missing in type 'BaseBootstrapSchema'.

Error 2:

Property 'validate' does not exist on type 'BootstrapSchema'.

I'm tried a few ways to rectify this issue but none really work.

Assistance appreciated.

Zinovievsk answered 12/2, 2021 at 11:38 Comment(2)
did you found solution to this problem? I am having same issue.Whitening
@daehaai just use 0.29.1Ferrell
N
30

following the yup guide here you should change your code as follows:

import { object, SchemaOf, string } from 'yup';

interface BaseBootstrapSchema {  
  APPLICATION_NAME: string;
  LOG_PATH: string;
}

const bootstrapValidationSchema: SchemaOf<BaseBootstrapSchema> = object({
  LOG_PATH: string().required("The 'LOG_PATH' ENV variable is required"),
  APPLICATION_NAME: string().required("The 'APPLICATION_NAME' ENV variable is required"),
});

module.exports = (schema: SchemaOf<BaseBootstrapSchema>) =>
  new Promise((resolve, reject) =>
    schema
      .validate(process.env, { abortEarly: false })
      .then(() => resolve(true))
      .catch((error: any) => {
        if (error.errors.length > 1) {
          reject(new Error(`${error.message},\n${error.errors.join(',\n')}`));
        } else {
          reject(new Error(error.message));
        }
      })
  );

Actually you don't need the const bootstrapValidationSchema at all, since you will pass it to the node module you are exporting, but I could've misunderstood what you are trying to achieve here. Try it.

Nonillion answered 12/5, 2021 at 9:47 Comment(3)
What happens if a property on the interface is optional? I can't to get it to play nicely with yupBrisk
The guide link you shared isn't working anymore.Stephan
thx @anas-latique, link fixedNonillion
I
3

If a property of the schema is optional, use OptionalObjectSchema and AnySchema types.

import { object, string, AnySchema } from 'yup';
import { OptionalObjectSchema } from 'yup/lib/object'

interface BaseBootstrapSchema {  
  APPLICATION_NAME: string;
  LOG_PATH: string;
}

const bootstrapValidationSchema: OptionalObjectSchema<Record<keyof BaseBootstrapSchema, AnySchema>> = object({
  LOG_PATH: string(),
  APPLICATION_NAME: string(),
});
Ingeingeberg answered 14/12, 2022 at 1:1 Comment(0)
P
0

@catruzz answer with SchemaOf is outdated, as you can see here and here. Use Schema now.

import { object, Schema, string } from 'yup';

interface BaseBootstrapSchema {  
  APPLICATION_NAME: string;
  LOG_PATH: string;
}

const bootstrapValidationSchema: Schema<BaseBootstrapSchema> = object({
  LOG_PATH: string().required("The 'LOG_PATH' ENV variable is required"),
  APPLICATION_NAME: string().required("The 'APPLICATION_NAME' ENV variable is required"),
});
Pulver answered 24/5 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.