From a59066f235caddcdd2c3938d9ce3f5493fd3fcd6 Mon Sep 17 00:00:00 2001 From: ealush Date: Sun, 21 May 2023 14:14:47 +0300 Subject: [PATCH] types(vest): Set Callback as the last suite generic --- .../integration.stateful-async.test.ts | 4 +- packages/vest/src/suite/SuiteTypes.ts | 9 ++-- .../src/suite/__tests__/typedSuite.test.ts | 5 +-- packages/vest/src/suite/createSuite.ts | 18 ++++---- packages/vest/src/suite/staticSuite.ts | 12 +++--- packages/vest/testUtils/TVestMock.ts | 2 +- website/docs/typescript_support.md | 41 +++++++++++-------- 7 files changed, 50 insertions(+), 41 deletions(-) diff --git a/packages/vest/src/__tests__/integration.stateful-async.test.ts b/packages/vest/src/__tests__/integration.stateful-async.test.ts index 2d8caee5b..0f935b111 100644 --- a/packages/vest/src/__tests__/integration.stateful-async.test.ts +++ b/packages/vest/src/__tests__/integration.stateful-async.test.ts @@ -34,9 +34,9 @@ const suite = () => }); let validate: vest.Suite< - ({ skip, skipGroup }: SuiteParams) => void, TFieldName, - TGroupName + TGroupName, + ({ skip, skipGroup }: SuiteParams) => void >; let callback_1 = jest.fn(), callback_2 = jest.fn(), diff --git a/packages/vest/src/suite/SuiteTypes.ts b/packages/vest/src/suite/SuiteTypes.ts index c6d4d854b..3763e23c1 100644 --- a/packages/vest/src/suite/SuiteTypes.ts +++ b/packages/vest/src/suite/SuiteTypes.ts @@ -9,10 +9,11 @@ import { import { TTypedMethods } from 'getTypedMethods'; import { SuiteSelectors } from 'suiteSelectors'; -export type Suite = (( - ...args: Parameters -) => SuiteRunResult) & - SuiteMethods; +export type Suite< + F extends TFieldName, + G extends TGroupName, + T extends CB = CB +> = ((...args: Parameters) => SuiteRunResult) & SuiteMethods; export type SuiteMethods = { get: () => SuiteResult; diff --git a/packages/vest/src/suite/__tests__/typedSuite.test.ts b/packages/vest/src/suite/__tests__/typedSuite.test.ts index d163f7d67..3d8eccf31 100644 --- a/packages/vest/src/suite/__tests__/typedSuite.test.ts +++ b/packages/vest/src/suite/__tests__/typedSuite.test.ts @@ -1,11 +1,10 @@ -import { TTestSuiteCallback } from 'testUtils/TVestMock'; import * as vest from 'vest'; type TestFields = 'F1' | 'F2' | 'F3'; type TestGroups = 'G1' | 'G2' | 'G3'; describe('typed suite', () => { - let suite: vest.Suite; + let suite: vest.Suite; beforeEach(() => { suite = vest.create(() => {}); @@ -70,7 +69,7 @@ describe('typed suite', () => { describe('typed methods', () => { it('should run the typed suite normally', () => { - const suite = vest.create<() => void, 'USERNAME' | 'PASSWORD'>(() => { + const suite = vest.create<'USERNAME' | 'PASSWORD'>(() => { only('PASSWORD'); test('PASSWORD', 'password is too short', () => false); diff --git a/packages/vest/src/suite/createSuite.ts b/packages/vest/src/suite/createSuite.ts index b58252940..fdd14e4c4 100644 --- a/packages/vest/src/suite/createSuite.ts +++ b/packages/vest/src/suite/createSuite.ts @@ -24,23 +24,23 @@ import { bindSuiteSelectors } from 'suiteSelectors'; import { validateSuiteCallback } from 'validateSuiteParams'; function createSuite< - T extends CB, F extends TFieldName = string, - G extends TGroupName = string ->(suiteName: SuiteName, suiteCallback: T): Suite; + G extends TGroupName = string, + T extends CB = CB +>(suiteName: SuiteName, suiteCallback: T): Suite; function createSuite< - T extends CB, F extends TFieldName = string, - G extends TGroupName = string ->(suiteCallback: T): Suite; + G extends TGroupName = string, + T extends CB = CB +>(suiteCallback: T): Suite; // @vx-allow use-use function createSuite< - T extends CB, F extends TFieldName = string, - G extends TGroupName = string + G extends TGroupName = string, + T extends CB = CB >( ...args: [suiteName: SuiteName, suiteCallback: T] | [suiteCallback: T] -): Suite { +): Suite { const [suiteCallback, suiteName] = args.reverse() as [T, SuiteName]; validateSuiteCallback(suiteCallback); diff --git a/packages/vest/src/suite/staticSuite.ts b/packages/vest/src/suite/staticSuite.ts index 7ee16be1c..f8295428f 100644 --- a/packages/vest/src/suite/staticSuite.ts +++ b/packages/vest/src/suite/staticSuite.ts @@ -5,12 +5,12 @@ import { createSuite } from 'createSuite'; import { TTypedMethods, getTypedMethods } from 'getTypedMethods'; export function staticSuite< - T extends CB, F extends TFieldName = string, - G extends TGroupName = string ->(suiteCallback: T): StaticSuite { + G extends TGroupName = string, + T extends CB = CB +>(suiteCallback: T): StaticSuite { return assign( - (...args: Parameters) => createSuite(suiteCallback)(...args), + (...args: Parameters) => createSuite(suiteCallback)(...args), { ...getTypedMethods(), } @@ -18,7 +18,7 @@ export function staticSuite< } type StaticSuite< - T extends CB, F extends TFieldName = string, - G extends TGroupName = string + G extends TGroupName = string, + T extends CB = CB > = ((...args: Parameters) => SuiteRunResult) & TTypedMethods; diff --git a/packages/vest/testUtils/TVestMock.ts b/packages/vest/testUtils/TVestMock.ts index fd90eb2a8..9d7770654 100644 --- a/packages/vest/testUtils/TVestMock.ts +++ b/packages/vest/testUtils/TVestMock.ts @@ -4,4 +4,4 @@ import * as vest from 'vest'; export type TVestMock = typeof vest; export type TTestSuiteCallback = (...args: any[]) => void; -export type TTestSuite = vest.Suite; +export type TTestSuite = vest.Suite; diff --git a/website/docs/typescript_support.md b/website/docs/typescript_support.md index 89c9f7933..ea4357725 100644 --- a/website/docs/typescript_support.md +++ b/website/docs/typescript_support.md @@ -11,20 +11,23 @@ Vest is written fully in TypeScript, and as such, it provides extensive TypeScri ## Suite Generics -The Suite's `create` function takes three generic types - `Callback`, `FieldName`, `GroupName`. +The Suite's `create` function takes three **optional** generic types - `FieldName`, `GroupName` and `Callback`. -- `Callback`: The type for the suite callback. This type is propagated into the suite callback, and can be used to defined the shape of the data for the suite callback. -- `FieldName`: A union of the allowed field names in the suite. This type is propagated to all the suite and suite response methods. -- `GroupName`: A union of the allowed group names in the suite. This type is propagated to all the suite and suite response methods. +| Name | Type | Optional? | Default | Description | +| ----------- | ---------- | --------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `FieldName` | `string` | Yes | `string` | A union of the allowed field names in the suite. This type is propagated to all the suite and suite response methods. | +| `GroupName` | `string` | Yes | `string` | A union of the allowed group names in the suite. This type is propagated to all the suite and suite response methods. | +| `Callback` | `Function` | Yes | `Function` | The type for the suite callback. This type is propagated into the suite callback, and can be used to defined the shape of the data for the suite callback. | ```typescript import { create } from 'vest'; -type Callback = (data: {username: string, password: string}) => void; -type FieldName = "username" | "password"; -type GroupName = "SignIn" | "ChangePassword"; +type FieldName = 'username' | 'password'; +type GroupName = 'SignIn' | 'ChangePassword'; +type Callback = (data: { username: string; password: string }) => void; -const suite = create((data) => { // data is now typed +const suite = create(data => { + // data is now typed // ... }); @@ -71,18 +74,24 @@ To do so, you can type your suite as mentioned in the previous section, and dest ```typescript import { create } from 'vest'; -type TData = {username: string, password: string}; -type Callback = (data: TData) => void; +type TData = { username: string; password: string }; type FieldName = keyof TData; -type GroupName = "SignIn" | "ChangePassword"; +type GroupName = 'SignIn' | 'ChangePassword'; +type Callback = (data: TData) => void; -const suite = create((data) => { +const suite = create(data => { only('username'); - test('username', 'Password is required' ,() => {/*...*/}); // ✅ - test('password', 'Password is too required' ,() => {/*...*/}); // ✅ + test('username', 'Password is required', () => { + /*...*/ + }); // ✅ + test('password', 'Password is too required', () => { + /*...*/ + }); // ✅ - test('confirm', 'Passwords do not match' ,() => {/*...*/}); // 🚨 Will throw a compilation error + test('confirm', 'Passwords do not match', () => { + /*...*/ + }); // 🚨 Will throw a compilation error }); const { test, group, only } = suite; @@ -92,7 +101,7 @@ const { test, group, only } = suite; Vest exports the following types so you can use them to annotate your functions and variables: -- `Suite`
+- `Suite`
A single suite instance. - `SuiteRunResult`