Type 'MyType' does not satisfy the constraint 'ObjectShape'. Index signature for type 'string' is missing in type 'MyType'
Asked Answered
S

4

14

So, I recently upgraded

  • "yup": "^0.29.1" => "yup": "^0.32.11"
  • "@types/yup": "^0.29.3" => "@types/yup": "^0.29.13",

And now all of my Schemas are broken. I'll provide one example, which typescript is crying about:

export interface MyType {
  id: number;
  name: string;
  description: string | null;
}

export const mySchema = yup
  .object<MyType>({
    id: yup.number().required(),
    name: yup.string().trim().required().max(50),
    description: yup.string().trim().max(200).defined(),
  })
  .required();

Error from typescript:

TS2344: Type 'MyType' does not satisfy the constraint 'ObjectShape'. Index signature for type 'string' is missing in type 'MyType'.

What am I missing here?

Spencerspencerian answered 16/3, 2022 at 16:28 Comment(3)
Have you gone to the yup project and look if there were any upgrade instructions or BC breaks?Histochemistry
@Histochemistry I've found something in the change log, saying "BREAKING CHANGE: plain objects and arrays are no long cast to strings automatically", but I doubt that it's related to problem I'm facingSpencerspencerian
Looks like a known issue. Fixed in 1.x beta: github.com/jquense/yup/issues/1510Premeditate
I
4

This seems to work for me

interface MyInterface {
  foo: string;
}

const validationSchema: SchemaOf<MyInterface> = Yup.object().shape({
  foo: Yup.string().required(),
});

Imelda answered 3/12, 2022 at 15:49 Comment(0)
L
2

Instead of specifying the interface to the object, do it to the shape with a Record - <Record<keyof MyType, yup.AnySchema>>. So your code would look like this:

export const mySchema = yup
  .object().shape<Record<keyof MyType, yup.AnySchema>>({
    id: yup.number().required(),
    name: yup.string().trim().required().max(50),
    description: yup.string().trim().max(200).defined(),
  })
  .required();

I haven't found a better solution so far.

Lilah answered 5/10, 2022 at 13:24 Comment(0)
C
1

I had to set "strictNullChecks": true, to get rid of nonsensical type errors. Also, I'm using the most recent beta release rather than the default.

Having that set, this syntax works for me:

type MyType = {
  id: string;
};

export const schema: yup.ObjectSchema<MyType> = yup.object({
  id: yup.string().defined(),
});
Carricarriage answered 1/12, 2022 at 23:5 Comment(0)
F
1

It took me a while, but I got the working solution. This is working perfectly for me. I hope it helps.

interface RowInterface {
    id: number,
    female: string,
    male: string,
    total: number

}

interface GroupInterface {
    code: string;
    description: string;
    rows: RowInterface[];
}


Yup.object().shape < Record < keyof GroupInterface, Yup.AnySchema >> ({
    code: Yup.string(),
    description: Yup.string(),
    rows: Yup.array()
        .of(
            Yup.object().shape({

                id: Yup.number(),
                female: Yup.string(),
                male: Yup.string(),
                total: Yup.number()
            })
        )
        .test(
            'group',
            t('At least one needs to be filled'),
            (rows) => {

                return rows ? false : rows.some(
                    (row) =>
                    Number(row.male) > 0 ||
                    Number(row.female) > 0
                );
            }
        )

})
Fraise answered 4/5, 2023 at 5:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.