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

How to enforce exact type schema in v1? #1913

Closed
12evgen opened this issue Feb 11, 2023 · 8 comments
Closed

How to enforce exact type schema in v1? #1913

12evgen opened this issue Feb 11, 2023 · 8 comments

Comments

@12evgen
Copy link

12evgen commented Feb 11, 2023

According to the documentation, the scheme can be described as follows

import { object, number, string, ObjectSchema } from 'yup';

interface Person {
  name: string;
  age?: number;
  sex: 'male' | 'female' | 'other' | null;
}

// will raise a compile-time type error if the schema does not produce a valid Person
const schema: ObjectSchema<Person> = object({
  name: string().defined(),
  age: number().optional(),
  sex: string<'male' | 'female' | 'other'>().nullable().defined();
});

but if a new property is added to the validation scheme, then the typescript does not throw an error

const schema: ObjectSchema<Person> = object({
  name: string().defined(),
  age: number().optional(),
  sex: string<'male' | 'female' | 'other'>().nullable().defined();
  newProperty: number().optional(),
})

How to strongly-type schema in v1?

@jquense
Copy link
Owner

jquense commented Feb 11, 2023

This is more of a typescript limitation than a yup issue. Typescript doesn't have a way of specifying "exact types"

if an interface is a subset of another then an object of one can be assigned to the other.

interface Person {
  name: string
  age?: number
  sex: 'male' | 'female' | 'other' | null
}

interface PersonWithExtraProperty {
  name: string
  age?: number
  sex: 'male' | 'female' | 'other' | null
  newProperty: number
}

const personWithExtraProperty: PersonWithExtraProperty = {
  name: 'James',
  age: 23,
  sex: null,
  newProperty: 4,
}

const person: Person = personWithExtraProperty // no error

@12evgen
Copy link
Author

12evgen commented Feb 12, 2023

const person: Person = personWithExtraProperty // no error
this typescript behavior is correct since you are overriding the Person type

I think it would be more correct to add typing for a more strict schema definition, especially since developers had such a request before @types/yup: How to strongly-type ObjectSchema

@jquense
Copy link
Owner

jquense commented Feb 12, 2023

this typescript behavior is correct since you are overriding the Person type

That is not what that code segment is doing. It's not overriding the type, if it was this would work: const Person: { name: string } = { age: 1 } as { age: number }, it's Saying that PersonWithExtraProperty is assignable to Person, which is exactly what the yup version is doing.

In any case i'm not sure what you want me to do or say. This is how typescript types work, i can't change that.

@12evgen
Copy link
Author

12evgen commented Feb 13, 2023

I want to say that we need to find a way so that we can strict type the validation scheme. I spent some time on this but didn't find a solution.

type LoginRequest = {
   username: string
   password: string
}
type Schema = ObjectSchema<LoginRequest>

object<Schema>({
    username: string().email().required(),
    password: string().min(8).max(32).required(),
})

I tried to define Schema scheme through the ObjectShape, but due to the complex typing of the object, I could not get the desired result

@jquense jquense changed the title How to strongly-type schema in v1? How to enforce exact type schema in v1? Feb 14, 2023
@ErikPilsits-RJW
Copy link

Typescript 4.9 has the satisfies operator which can enforce this. See the 4th example here: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator

@jquense jquense closed this as completed Feb 24, 2023
@gmonitoring
Copy link

Any updates on this topic? Why is there no answer to all such questions, is it not possible to protyp the schema using a pre-written interface?

@jquense
Copy link
Owner

jquense commented Sep 5, 2023

The answer is in the documentation. You can use a predefined interface just fine. The real question here is why does types riot lot have exact types, which is something I don't know the answer to nor can I control it. I can only work inside the typesystem

@gmonitoring
Copy link

gmonitoring commented Nov 5, 2023

Ответ есть в документации. Вы можете использовать предопределенный интерфейс. Настоящий вопрос здесь заключается в том, почему у множества типов бунта есть точные типы, на который я не знаю ответа и не могу это контролировать. Я могу работать только внутри системы типов

image
It worked like that before, but not now. yup 1.1 ts 5.2

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