GithubHelp home page GithubHelp logo

export type classes about valita HOT 6 CLOSED

badrap avatar badrap commented on May 18, 2024
export type classes

from valita.

Comments (6)

jviide avatar jviide commented on May 18, 2024

What would the use case for this be, and what would valitaLib contain?

from valita.

dimatakoy avatar dimatakoy commented on May 18, 2024

Related #29

What would the use case for this be, and what would valitaLib contain?

It should contain exports for ObjectType, UnionType, OptionalType, StringType and etc.

import { v } from './app/lib/core/schema-utils';

// I have 2-3 schemas for my entities: Domain, FormValidation/FormData, Database/ExternalApi

// domain entity
v.object({ id: v.number() });

// formValidation / FormData validation
// But this validation will fail if we pass data from api (schema above) as is.
v.object({
	id: v
		.string()
		.map(Number.parseInt)
		.assert((value) => value > 0),
});

// Lets you duplicate schema for working with incoming (form api) data too
v.object({
	id: v.union(
		v
			.string()
			.map(Number.parseInt)
			.assert((value) => value > 0),
		v.number(),
	),
});

// What if api can return null/undefined? I need to convert this to `''`:
v.object({
	id: v.union(
		v
			.string()
			.nullable()
			.chain((value) => {
				if (!value) return v.ok(Number.NaN); // pseudocode here, not covers all cases. numbers, booleans, unions is pretty funny for handling null/undefined/booleanish values 
				return v.ok(Number.parseInt(value)) ?? '';
			}),
		v.number(), // fallback to value from API
	),
});

// Finally, I decided to write a helper utility.
function field<T extends v.Type>(fieldType: T) {
	// pseudocode heres
	// returns v.union(inputType.chain((value) => fieldType.try(value)), fieldTyoe)
}

// We are here. I need a function that resolves original type and generates mapper from `inputType` to `fieldType if possible
// Resolves is a common function used in form libraries on the frontend (vee-validate, react-hook-forms, etc).

const fieldType = v.string().optional();
// ATM, I was forced to use constructions like, but I don't like it.
const resolveOriginalType = <T extends v.Type>(t: T) => (t.name === 'optional' ? t.type : null;

from valita.

dimatakoy avatar dimatakoy commented on May 18, 2024

Probably the main and shortest point is that it will help users write smarter/safer utility functions or schema transformers.

Now, of course, it is also possible to write one and I did so. But inside the function there are a lot of @ts-expect-error and as any, which is pretty unsafe without additional testing.

types structure feels like implementation detail, but I need to rely on them. But because they're not exported, I feel like I'm relying on them and things can break.

If it's possible at the type level inside the library to fix this, that's ok too. In that case, I want to get some kind of union that would allow me to rely on name and x prop. With this solution I can avoid class exoption.

const SafeType = { name: 'optional'; type: Type } | { name: 'union'; options: Type[] } | {name: 'object', shape?: ... }

from valita.

jviide avatar jviide commented on May 18, 2024

What I gather from this is that you want to define a type that's used internally in the system (the domain entity) and then use that to generate different input validators for different contexts (with typesafe type transformers).

If that is correct, then exposing the types wouldn't be enough in itself without some significant supporting type machinery (e.g. to ensure that v.number() is always transformed to something that produces a number etc.) In some previous discussions we had to rule these use-cases to be out of scope for this library, as it's not something we will ourselves use and thus can't commit to supporting.

from valita.

dimatakoy avatar dimatakoy commented on May 18, 2024

Yes, you got me right. Just a few comments:

I've already written a library that works in my case. However, internally it relies on private and protected instance fields. This looks like a bit of a mess.

To be honest, the idea of making classes public doesn't seem so straightforward. The internals can still change.

What if we write a function that resolves the type and returns a type tree? Then you can keep the classes private, but users will be able to write their own transformers, and you as the library author will be able to change the implementation.

For example:

const name = v.string().nullable()

const tree = resolve(name)

console.log(tree)

// {name: 'string', nullable: true }

// or simpler, as types works
// {name: 'union', options: [ {name: 'null' }, {name: 'string'} ] }

from valita.

jviide avatar jviide commented on May 18, 2024

In the example Valita would be used as a general data definition language (to define the domain entity types from which the input validators are generated) which we have outlined to be outside the scope of this library. I recommend skipping the validator -> JSON conversion phase, and start from the JSON ({name: 'union', options: [ {name: 'null' }, {name: 'string'} ] }) in your example) and generate the validators from that.

from valita.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.