From 165a9da8dc84be6754e4f23e4391eade0c8e4408 Mon Sep 17 00:00:00 2001 From: Marco Solazzi Date: Fri, 11 Feb 2022 18:58:36 +0900 Subject: [PATCH 1/5] wip: null type --- examples/shared/validators.ts | 6 ++++++ examples/vue3/test-components/template.vue | 2 ++ src/index.ts | 6 ++++++ src/validators/native.ts | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/examples/shared/validators.ts b/examples/shared/validators.ts index 085f4549..dd9f71c5 100644 --- a/examples/shared/validators.ts +++ b/examples/shared/validators.ts @@ -15,6 +15,7 @@ import { shape, toType, fromType, + isNull, } from 'vue-types' /** @@ -23,6 +24,11 @@ import { export const anyType = any() export const anyTypeCast = any() +/** + * `any` validator examples + */ +export const nullType = isNull() + /** * `func` validator examples */ diff --git a/examples/vue3/test-components/template.vue b/examples/vue3/test-components/template.vue index 3f37af5c..3903a0f3 100644 --- a/examples/vue3/test-components/template.vue +++ b/examples/vue3/test-components/template.vue @@ -20,6 +20,7 @@ import { anyType, objectOfTuple, oneOfTuple, + nullType, } from '../../shared/validators' export default defineComponent({ @@ -27,6 +28,7 @@ export default defineComponent({ user: userType, message: messageType, age: ageType, + sometng: nullType, hobbies: arrayOfStringsType, randomData: arrayOfMultipleType, score: scoreType, diff --git a/src/index.ts b/src/index.ts index 90c14a53..583231e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ import { integer, symbol, object, + isNull, } from './validators/native' import custom from './validators/custom' import oneOf from './validators/oneof' @@ -75,6 +76,10 @@ const BaseVueTypes = /*#__PURE__*/ (() => return symbol() } + static get isNull() { + return isNull() + } + static readonly custom = custom static readonly oneOf = oneOf static readonly instanceOf = instanceOf @@ -211,6 +216,7 @@ export { instanceOf, objectOf, shape, + isNull, createTypes, toType, toValidableType, diff --git a/src/validators/native.ts b/src/validators/native.ts index 4a14bc3b..c50eefd3 100644 --- a/src/validators/native.ts +++ b/src/validators/native.ts @@ -47,3 +47,7 @@ export const symbol = () => return typeof value === 'symbol' }, }) + +export const isNull = () => ({ + type: null as unknown as PropType, +}) From a726c3e027fc38922a1229bd925bb36dac1af17d Mon Sep 17 00:00:00 2001 From: dwightjack Date: Mon, 14 Feb 2022 22:04:19 +0900 Subject: [PATCH 2/5] update examples --- examples/shared/validators.ts | 7 ++----- examples/tsconfig.json | 2 +- examples/vue2/test-components/single.ts | 2 ++ examples/vue3/test-components/single.ts | 2 ++ examples/vue3/test-components/template.vue | 7 ++++--- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/examples/shared/validators.ts b/examples/shared/validators.ts index dd9f71c5..4c5b7e80 100644 --- a/examples/shared/validators.ts +++ b/examples/shared/validators.ts @@ -24,11 +24,6 @@ import { export const anyType = any() export const anyTypeCast = any() -/** - * `any` validator examples - */ -export const nullType = isNull() - /** * `func` validator examples */ @@ -128,6 +123,8 @@ export const castedStringOrCastedObject = oneOfType([ object(), ]).def('one') +export const stringOrNull = oneOfType([string(), isNull()]).def('one') + /** * `arrayOf` validator examples */ diff --git a/examples/tsconfig.json b/examples/tsconfig.json index 21baa029..88e2bba9 100644 --- a/examples/tsconfig.json +++ b/examples/tsconfig.json @@ -16,5 +16,5 @@ "vue-types/*": ["../src/*"] } }, - "include": ["**/*.ts", "../src/**/*.ts"] + "include": ["**/*.ts", "**/*.vue", "../src/**/*.ts"] } diff --git a/examples/vue2/test-components/single.ts b/examples/vue2/test-components/single.ts index 0bdbb167..46d0758b 100644 --- a/examples/vue2/test-components/single.ts +++ b/examples/vue2/test-components/single.ts @@ -10,6 +10,7 @@ import { anyType, objectOfTuple, oneOfTuple, + stringOrNull, } from '../../shared/validators' const UserComponent = Vue.extend({ @@ -20,6 +21,7 @@ const UserComponent = Vue.extend({ hobbies: arrayOfStringsType, randomData: arrayOfMultipleType, score: scoreType, + maybeStr: stringOrNull, }, }) diff --git a/examples/vue3/test-components/single.ts b/examples/vue3/test-components/single.ts index 8fd07ef7..13a63bd0 100644 --- a/examples/vue3/test-components/single.ts +++ b/examples/vue3/test-components/single.ts @@ -11,6 +11,7 @@ import { anyType, objectOfTuple, oneOfTuple, + stringOrNull, } from '../../shared/validators' const UserComponent = defineComponent({ @@ -21,6 +22,7 @@ const UserComponent = defineComponent({ hobbies: arrayOfStringsType, randomData: arrayOfMultipleType, score: scoreType, + maybeStr: stringOrNull, }, }) diff --git a/examples/vue3/test-components/template.vue b/examples/vue3/test-components/template.vue index 3903a0f3..1e3c7af9 100644 --- a/examples/vue3/test-components/template.vue +++ b/examples/vue3/test-components/template.vue @@ -2,7 +2,8 @@
  • User: {{ user.ID }}: {{ user.name }} - {{ age }}
  • -
  • Hobbies: {{ hobbies.join(', ') }}
  • +
  • Hobbies: {{ hobbies?.join(', ') }}
  • +
  • {{ maybeStr ?? 'hello' }}
@@ -20,7 +21,7 @@ import { anyType, objectOfTuple, oneOfTuple, - nullType, + stringOrNull, } from '../../shared/validators' export default defineComponent({ @@ -28,7 +29,7 @@ export default defineComponent({ user: userType, message: messageType, age: ageType, - sometng: nullType, + maybeStr: stringOrNull, hobbies: arrayOfStringsType, randomData: arrayOfMultipleType, score: scoreType, From 90b167394368d6f5286f254ff2f5fc8f7cf62924 Mon Sep 17 00:00:00 2001 From: dwightjack Date: Sat, 19 Feb 2022 18:20:16 +0900 Subject: [PATCH 3/5] tests and docs --- __tests__/index.test.ts | 7 +++++++ __tests__/validators/native.test.ts | 10 ++++++++++ docs/guide/namespaced.md | 1 + docs/guide/validators.md | 22 ++++++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/__tests__/index.test.ts b/__tests__/index.test.ts index 6165e11e..f1245b3c 100644 --- a/__tests__/index.test.ts +++ b/__tests__/index.test.ts @@ -90,6 +90,13 @@ describe('VueTypes', () => { }) }) + describe('`.isNull`', () => { + it('should proxy the `isNull` validator', () => { + const expected = getExpectDescriptors(native.isNull()) + expect(getDescriptors(VueTypes.isNull)).toEqual(expected) + }) + }) + describe('`.custom`', () => { it('should proxy the `custom` validator', () => { const fn = () => true diff --git a/__tests__/validators/native.test.ts b/__tests__/validators/native.test.ts index cd941e23..02f01af7 100644 --- a/__tests__/validators/native.test.ts +++ b/__tests__/validators/native.test.ts @@ -192,4 +192,14 @@ describe('Native validators', () => { } }) }) + + describe('isNull', () => { + it('should return a validator for null', () => { + expect(native.isNull().type).toBe(null) + }) + it('should not have any flag', () => { + expect((native.isNull() as any).isRequired).toBe(undefined) + expect((native.isNull() as any).def).toBe(undefined) + }) + }) }) diff --git a/docs/guide/namespaced.md b/docs/guide/namespaced.md index 7c08cac1..eb9b5ef2 100644 --- a/docs/guide/namespaced.md +++ b/docs/guide/namespaced.md @@ -39,6 +39,7 @@ The main difference between namespaced native validators and those directly impo | integer | `0` | - | | symbol | - | - | | object | `{}` | yes | +| isNull | - | - | diff --git a/docs/guide/validators.md b/docs/guide/validators.md index 0f78a5e4..d7954418 100644 --- a/docs/guide/validators.md +++ b/docs/guide/validators.md @@ -274,6 +274,28 @@ props: { } ``` +### isNull + +Validates that a prop is null. + +```js +props: { + uniq: isNull() +} +``` + +::: warning +This validator **does not come with any flag or method**. It can be used with [`oneOfType`](#oneoftype) to make a **non required** prop nullable. + +```js +props: { + stringOrNull: oneOfType([string(), isNull()]) +} +``` + +**Use this validator sparingly.** Nullable props are not encouraged in Vue components, so please consider reviewing your strategy. +::: + ## Custom Validators Custom validators are a special kind of factory function useful to describe complex validation requirements. By design custom validators: From 1e361cecb2d6e03f041d8237cbe7edb1504f036c Mon Sep 17 00:00:00 2001 From: dwightjack Date: Wed, 2 Mar 2022 18:51:21 +0900 Subject: [PATCH 4/5] rename isNull to nullable --- __tests__/index.test.ts | 8 ++++---- __tests__/shim.test.ts | 6 ++++++ __tests__/validators/native.test.ts | 8 ++++---- docs/guide/namespaced.md | 2 +- docs/guide/validators.md | 6 +++--- examples/shared/validators.ts | 4 ++-- src/index.ts | 8 ++++---- src/shim.ts | 6 ++++++ 8 files changed, 30 insertions(+), 18 deletions(-) diff --git a/__tests__/index.test.ts b/__tests__/index.test.ts index f1245b3c..1098ab4c 100644 --- a/__tests__/index.test.ts +++ b/__tests__/index.test.ts @@ -90,10 +90,10 @@ describe('VueTypes', () => { }) }) - describe('`.isNull`', () => { - it('should proxy the `isNull` validator', () => { - const expected = getExpectDescriptors(native.isNull()) - expect(getDescriptors(VueTypes.isNull)).toEqual(expected) + describe('`.nullable`', () => { + it('should proxy the `nullable` validator', () => { + const expected = getExpectDescriptors(native.nullable()) + expect(getDescriptors(VueTypes.nullable)).toEqual(expected) }) }) diff --git a/__tests__/shim.test.ts b/__tests__/shim.test.ts index f20a356d..7b146daa 100644 --- a/__tests__/shim.test.ts +++ b/__tests__/shim.test.ts @@ -311,6 +311,12 @@ describe('SHIM: VueTypes', () => { }) }) + describe('`.nullable`', () => { + it('should proxy the `nullable` validator', () => { + expect(VueTypes.nullable).toEqual({ type: null }) + }) + }) + describe('SHIM: `.custom`', () => { it('should exist', () => { expect(VueTypes.custom).toBeInstanceOf(Function) diff --git a/__tests__/validators/native.test.ts b/__tests__/validators/native.test.ts index 02f01af7..b8134ff6 100644 --- a/__tests__/validators/native.test.ts +++ b/__tests__/validators/native.test.ts @@ -193,13 +193,13 @@ describe('Native validators', () => { }) }) - describe('isNull', () => { + describe('nullable', () => { it('should return a validator for null', () => { - expect(native.isNull().type).toBe(null) + expect(native.nullable().type).toBe(null) }) it('should not have any flag', () => { - expect((native.isNull() as any).isRequired).toBe(undefined) - expect((native.isNull() as any).def).toBe(undefined) + expect((native.nullable() as any).isRequired).toBe(undefined) + expect((native.nullable() as any).def).toBe(undefined) }) }) }) diff --git a/docs/guide/namespaced.md b/docs/guide/namespaced.md index eb9b5ef2..18be3d84 100644 --- a/docs/guide/namespaced.md +++ b/docs/guide/namespaced.md @@ -39,7 +39,7 @@ The main difference between namespaced native validators and those directly impo | integer | `0` | - | | symbol | - | - | | object | `{}` | yes | -| isNull | - | - | +| nullable | - | - | diff --git a/docs/guide/validators.md b/docs/guide/validators.md index d7954418..bc422fc0 100644 --- a/docs/guide/validators.md +++ b/docs/guide/validators.md @@ -274,13 +274,13 @@ props: { } ``` -### isNull +### nullable Validates that a prop is null. ```js props: { - uniq: isNull() + uniq: nullable() } ``` @@ -289,7 +289,7 @@ This validator **does not come with any flag or method**. It can be used with [` ```js props: { - stringOrNull: oneOfType([string(), isNull()]) + stringOrNull: oneOfType([string(), nullable()]) } ``` diff --git a/examples/shared/validators.ts b/examples/shared/validators.ts index 4c5b7e80..00772217 100644 --- a/examples/shared/validators.ts +++ b/examples/shared/validators.ts @@ -15,7 +15,7 @@ import { shape, toType, fromType, - isNull, + nullable, } from 'vue-types' /** @@ -123,7 +123,7 @@ export const castedStringOrCastedObject = oneOfType([ object(), ]).def('one') -export const stringOrNull = oneOfType([string(), isNull()]).def('one') +export const stringOrNull = oneOfType([string(), nullable()]).def('one') /** * `arrayOf` validator examples diff --git a/src/index.ts b/src/index.ts index 583231e6..bac27b3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,7 +29,7 @@ import { integer, symbol, object, - isNull, + nullable, } from './validators/native' import custom from './validators/custom' import oneOf from './validators/oneof' @@ -76,8 +76,8 @@ const BaseVueTypes = /*#__PURE__*/ (() => return symbol() } - static get isNull() { - return isNull() + static get nullable() { + return nullable() } static readonly custom = custom @@ -216,7 +216,7 @@ export { instanceOf, objectOf, shape, - isNull, + nullable, createTypes, toType, toValidableType, diff --git a/src/shim.ts b/src/shim.ts index 20283b4a..6010bdaf 100644 --- a/src/shim.ts +++ b/src/shim.ts @@ -86,6 +86,9 @@ export const shape: TypeShim = (a: any) => return this }, }) +export const nullable: TypeShim = () => ({ + type: null, +}) /* eslint-enable @typescript-eslint/no-unused-vars */ function createValidator( @@ -153,6 +156,9 @@ const BaseVueTypes = /*#__PURE__*/ (() => static get integer() { return integer().def(this.defaults.integer) } + static get nullable() { + return nullable() + } static oneOf = oneOf static custom = custom static instanceOf = instanceOf From c84dd7375ba9879e4edcb7f2cd41709ad28c45e9 Mon Sep 17 00:00:00 2001 From: dwightjack Date: Wed, 2 Mar 2022 18:55:55 +0900 Subject: [PATCH 5/5] rename isNull to nullable --- src/validators/native.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validators/native.ts b/src/validators/native.ts index c50eefd3..73382cdb 100644 --- a/src/validators/native.ts +++ b/src/validators/native.ts @@ -48,6 +48,6 @@ export const symbol = () => }, }) -export const isNull = () => ({ +export const nullable = () => ({ type: null as unknown as PropType, })