Skip to content

Conversation

@synapseradio
Copy link
Collaborator

If merged, will lead to a minor release as it should be backwards compatible

feat(formal):

  • replace eslint with rome
  • add better typings that allow for explicit markup when provided

Rationale

Why is this PR necessary?

This PR adds type annotations so that formal can infer better types for createRule and all other related functions.

It does not introduce mandatory types in new places ( unless you are manually instantiating Success or Fail classes, which you probably aren't )

these annotations can lead to typescript helping you out a lot more as you create custom rules, and in some cases, not have to run to see if things failed when you're using pipeValidators or validateObject.

They still fall back to very forgiving types that are effectively the same as before ( when most types were casted to any without the ability to specify ).

consider the examples below, pulled from the tests:

const hasExactlyTwoNameObjects = createRule({
	condition: (arr: string[]) => arr.length === 2,
	message: 'Exactly two names must exist',
})

because the condition is marked with a param type, this rule will now correctly infer if you're trying to use it on some known other type by mistake, without having to wait until a failure at runtime to be certain.

it still works without complaint the way it did before if the annotation is gone. ( the same augmentation has happened with the optional transform fn )

const overwriteText = withMessage<number>('Whoa')

Same effect with withMessage.

Since rules cascade over a single value with a single type, you can now put the type into the Validator class and the pipeValidators util.

Validator.of<string, OptionalOnSuccessReturnType, OptionalOnFailReturnType>(isNonEmptyString).validate('wow').then({
  onSuccess: (v: string) => OptionalOnSuccessReturnType, // string value is inferred, you don't have to type it out
  onFail: (errors: string[]) => OptionalOnFailReturnType // onFail will Always have the errors as the argument rather than the value, but this was the same as before
})

with these optional type annotations ( they all default to any ) you can get better guarantees of what will happen next with the return from this validator.

Rome has been added as a formatter / linter since it is much lighter and much faster than the eslint rules were. Any CI dealing with this package should be faster on the order of 40-60x. It makes for a messy diff where strings are getting their quotes changed, but it makes linting a whole lot easier and closer to the more standard style of prettier. it's abstracted behind the lint and style commands. Because the eslint dependencies are gone, the installation should take a lot less time and the lockfile is shorter.

Rome has a pretty nice VS code extension as well if you're developing and want it to format on save.

I have used pnpm as a package manager ( which I highly suggest switching to ) but have also updated yarn.lock for compatibility with CI.

@synapseradio synapseradio requested review from a team and lkapt March 13, 2023 20:18
@synapseradio synapseradio force-pushed the feature/better-types branch from f8619a5 to be7ae63 Compare March 13, 2023 20:32
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

Successfully merging this pull request may close these issues.

3 participants