From fe8f42b1f9f3d0b6d2c9ca188af9946da0e6243d Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Wed, 11 May 2022 14:38:31 +0200 Subject: [PATCH] Allow generic type for `stringProp` --- README.md | 14 ++++++++++-- src/prop-types/string.ts | 8 ++++--- type-tests/prop-types/string.type.spec.ts | 26 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 67f9bfd4..b707a2bc 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,10 @@ numberProp(isPositive).optional // → prop type: number | undefined ``` -### `stringProp(validator?: Validator)` +### `stringProp(validator?: Validator)` -Allows any string. No further runtime validation is performed by default. +Allows any string. No further runtime validation is performed by default. +Type parameter `T` can be used to restrict the type at compile time with a union type. ```ts stringProp().optional @@ -73,6 +74,15 @@ stringProp().required // → prop type: string stringProp().withDefault('foo') // → prop type: string + +type Foo = 'a' | 'b' | 'c'; + +stringProp().optional + // → prop type: Foo | undefined +stringProp().required + // → prop type: Foo +stringProp().withDefault('a') + // → prop type: Foo ``` ### `booleanProp(validator?: Validator)` diff --git a/src/prop-types/string.ts b/src/prop-types/string.ts index 8472a82c..8b9ee5b3 100644 --- a/src/prop-types/string.ts +++ b/src/prop-types/string.ts @@ -1,11 +1,13 @@ -import type { PropOptionsGenerator } from '../types'; +import type { PropOptionsGenerator, PropType } from '../types'; import { propOptionsGenerator } from '../util'; import type { Validator } from '../validators'; /** * Allows any string. No further runtime validation is performed by default. * + * Type parameter `T` can be used to restrict the type at compile time with a union type. + * * @param validator - Optional function for further runtime validation; should return `undefined` if valid, or an error string if invalid. */ -export const stringProp = (validator?: Validator): PropOptionsGenerator => - propOptionsGenerator(String, validator); +export const stringProp = (validator?: Validator): PropOptionsGenerator => + propOptionsGenerator(String as unknown as PropType, validator); diff --git a/type-tests/prop-types/string.type.spec.ts b/type-tests/prop-types/string.type.spec.ts index bad32890..1dae9c2a 100644 --- a/type-tests/prop-types/string.type.spec.ts +++ b/type-tests/prop-types/string.type.spec.ts @@ -5,50 +5,76 @@ import { stringProp } from '../../src/prop-types/string'; import { createVue2Component } from '../utils'; import type { Vue2ComponentWithProp } from '../utils'; +type Foo = 'a' | 'b' | 'c'; + describe('stringProp().optional', () => { describe('Vue 2', () => { expectAssignable>(stringProp().optional); + expectAssignable>(stringProp().optional); expectNotAssignable>(stringProp().optional); + expectNotAssignable>(stringProp().optional); expectType>( createVue2Component(stringProp().optional), ); + + expectType>( + createVue2Component(stringProp().optional), + ); }); describe('Composition API', () => { expectAssignable>(stringProp().optional); + expectAssignable>(stringProp().optional); expectNotAssignable>(stringProp().optional); + expectNotAssignable>(stringProp().optional); }); }); describe('stringProp().withDefault', () => { describe('Vue 2', () => { expectAssignable>(stringProp().withDefault('foo')); + expectAssignable>(stringProp().withDefault('a')); expectNotAssignable>(stringProp().withDefault('foo')); + expectNotAssignable>(stringProp().withDefault('a')); expectType>( createVue2Component(stringProp().withDefault('foo')), ); + + expectType>( + createVue2Component(stringProp().withDefault('a')), + ); }); describe('Composition API', () => { expectAssignable>(stringProp().withDefault('foo')); + expectAssignable>(stringProp().withDefault('a')); expectNotAssignable>(stringProp().withDefault('foo')); + expectNotAssignable>(stringProp().withDefault('a')); }); }); describe('stringProp().required', () => { describe('Vue 2', () => { expectAssignable>(stringProp().required); + expectAssignable>(stringProp().required); expectNotAssignable>(stringProp().required); + expectNotAssignable>(stringProp().required); expectType>( createVue2Component(stringProp().required), ); + + expectType>( + createVue2Component(stringProp().required), + ); }); describe('Composition API', () => { expectAssignable>(stringProp().required); + expectAssignable>(stringProp().required); expectNotAssignable>(stringProp().required); + expectNotAssignable>(stringProp().required); }); });