Skip to content

Commit

Permalink
Add new dateProp prop type (#774)
Browse files Browse the repository at this point in the history
FloEdelmann authored Jan 13, 2025

Verified

This commit was signed with the committer’s verified signature.
larskuhtz Lars Kuhtz
1 parent 6ca7ac2 commit 5008238
Showing 5 changed files with 205 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -263,6 +263,21 @@ integerProp().withDefault(42);
// → prop type: number
```

### `dateProp(validator?: Validator)`

Allows any `Date` object (validated at runtime and compile time).

```ts
dateProp().optional;
// → prop type: Date | undefined
dateProp().nullable;
// → prop type: Date | null
dateProp().required;
// → prop type: Date
dateProp().withDefault(() => new Date());
// → prop type: Date
```

### `symbolProp(validator?: Validator)`

Allows any symbol (validated at runtime and compile time).
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ export { stringProp } from './prop-types/string';
export { booleanProp } from './prop-types/boolean';
export { numberProp } from './prop-types/number';
export { integerProp } from './prop-types/integer';
export { dateProp } from './prop-types/date';
export { symbolProp } from './prop-types/symbol';
export { vueComponentProp } from './prop-types/vueComponent';

11 changes: 11 additions & 0 deletions src/prop-types/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { PropOptionsGenerator, PropType } from '../types';
import { propOptionsGenerator } from '../util';
import type { Validator } from '../validators';

/**
* Allows any `Date` object (validated at runtime and compile time).
*
* @param validator - Optional function for further runtime validation; should return `undefined` if valid, or an error string if invalid.
*/
export const dateProp = (validator?: Validator): PropOptionsGenerator<Date> =>
propOptionsGenerator(Date as unknown as PropType<Date>, validator);
45 changes: 45 additions & 0 deletions tests/prop-types/date.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, expect, it } from 'vitest';
import { dateProp } from '../../src/prop-types/date';

describe('dateProp().optional', () => {
it('creates the correct prop options', () => {
expect(dateProp().optional).toStrictEqual({
type: Date,
required: false,
default: undefined,
validator: undefined,
});
});
});

describe('dateProp().nullable', () => {
it('creates the correct prop options', () => {
expect(dateProp().nullable).toStrictEqual({
type: Date,
required: false,
default: null,
validator: undefined,
});
});
});

describe('dateProp().withDefault', () => {
it('creates the correct prop options', () => {
expect(dateProp().withDefault(() => new Date())).toStrictEqual({
type: Date,
required: false,
default: expect.any(Function),
validator: undefined,
});
});
});

describe('dateProp().required', () => {
it('creates the correct prop options', () => {
expect(dateProp().required).toStrictEqual({
type: Date,
required: true,
validator: undefined,
});
});
});
133 changes: 133 additions & 0 deletions type-tests/prop-types/date.type.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { describe, expect, test } from 'tstyche';
import type * as Vue2_6 from 'vue2-6/types/options';
import type * as Vue2_7 from 'vue2-7/types/options';
import type * as Vue3 from '@vue/runtime-core/dist/runtime-core';
import { dateProp } from '../../src/prop-types/date';
import { createVue2Component } from '../utils';
import type { Vue2ComponentWithProp } from '../utils';

describe('dateProp().optional', () => {
test('Vue 2.6', () => {
expect<Vue2_6.PropOptions<Date | undefined>>().type.toBeAssignableWith(
dateProp().optional,
);
expect<Vue2_6.PropOptions<Date>>().type.not.toBeAssignableWith(
dateProp().optional,
);

expect(createVue2Component(dateProp().optional)).type.toBe<
Vue2ComponentWithProp<Date | undefined>
>();
});

test('Vue 2.7', () => {
expect<Vue2_7.PropOptions<Date | undefined>>().type.toBeAssignableWith(
dateProp().optional,
);
expect<Vue2_7.PropOptions<Date>>().type.not.toBeAssignableWith(
dateProp().optional,
);
});

test('Vue 3', () => {
expect<Vue3.Prop<Date | undefined>>().type.toBeAssignableWith(
dateProp().optional,
);
expect<Vue3.Prop<Date>>().type.not.toBeAssignableWith(dateProp().optional);
});
});

describe('dateProp().nullable', () => {
test('Vue 2.6', () => {
expect<Vue2_6.PropOptions<Date | null>>().type.toBeAssignableWith(
dateProp().nullable,
);
expect<Vue2_6.PropOptions<Date>>().type.not.toBeAssignableWith(
dateProp().nullable,
);

expect(createVue2Component(dateProp().nullable)).type.toBe<
Vue2ComponentWithProp<Date | null>
>();
});

test('Vue 2.7', () => {
expect<Vue2_7.PropOptions<Date | null>>().type.toBeAssignableWith(
dateProp().nullable,
);
expect<Vue2_7.PropOptions<Date>>().type.not.toBeAssignableWith(
dateProp().nullable,
);
});

test('Vue 3', () => {
expect<Vue3.Prop<Date | null>>().type.toBeAssignableWith(
dateProp().nullable,
);
expect<Vue3.Prop<Date>>().type.not.toBeAssignableWith(dateProp().nullable);
});
});

describe('dateProp().withDefault(false)', () => {
test('Vue 2.6', () => {
expect<Vue2_6.PropOptions<Date>>().type.toBeAssignableWith(
dateProp().withDefault(() => new Date()),
);
expect<Vue2_6.PropOptions<string>>().type.not.toBeAssignableWith(
dateProp().withDefault(() => new Date()),
);

expect(
createVue2Component(dateProp().withDefault(() => new Date())),
).type.toBe<Vue2ComponentWithProp<Date>>();
});

test('Vue 2.7', () => {
expect<Vue2_7.PropOptions<Date>>().type.toBeAssignableWith(
dateProp().withDefault(() => new Date()),
);
expect<Vue2_7.PropOptions<string>>().type.not.toBeAssignableWith(
dateProp().withDefault(() => new Date()),
);
});

test('Vue 3', () => {
expect<Vue3.Prop<Date>>().type.toBeAssignableWith(
dateProp().withDefault(() => new Date()),
);
expect<Vue3.Prop<string>>().type.not.toBeAssignableWith(
dateProp().withDefault(() => new Date()),
);
});
});

describe('dateProp().required', () => {
test('Vue 2.6', () => {
expect<Vue2_6.PropOptions<Date>>().type.toBeAssignableWith(
dateProp().required,
);
expect<Vue2_6.PropOptions<string>>().type.not.toBeAssignableWith(
dateProp().required,
);

expect(createVue2Component(dateProp().required)).type.toBe<
Vue2ComponentWithProp<Date>
>();
});

test('Vue 2.7', () => {
expect<Vue2_7.PropOptions<Date>>().type.toBeAssignableWith(
dateProp().required,
);
expect<Vue2_7.PropOptions<string>>().type.not.toBeAssignableWith(
dateProp().required,
);
});

test('Vue 3', () => {
expect<Vue3.Prop<Date>>().type.toBeAssignableWith(dateProp().required);
expect<Vue3.Prop<string>>().type.not.toBeAssignableWith(
dateProp().required,
);
});
});

0 comments on commit 5008238

Please sign in to comment.