Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/floedelmann/vue-ts-types
Lightweight TypeScript-first Vue prop type definitions
https://github.com/floedelmann/vue-ts-types
hacktoberfest prop-types props proptype-validators proptypes typescript vue vue2 vue3 vuejs vuejs2 vuejs3
Last synced: 3 days ago
JSON representation
Lightweight TypeScript-first Vue prop type definitions
- Host: GitHub
- URL: https://github.com/floedelmann/vue-ts-types
- Owner: FloEdelmann
- License: mit
- Created: 2022-04-28T23:10:57.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-06-11T12:45:28.000Z (4 months ago)
- Last Synced: 2024-06-11T18:59:57.039Z (4 months ago)
- Topics: hacktoberfest, prop-types, props, proptype-validators, proptypes, typescript, vue, vue2, vue3, vuejs, vuejs2, vuejs3
- Language: TypeScript
- Homepage:
- Size: 1.83 MB
- Stars: 6
- Watchers: 3
- Forks: 3
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# vue-ts-types
> Lightweight TypeScript-first [Vue prop type](https://vuejs.org/guide/components/props.html#prop-validation) definitions
[![npm][badge-npm]][npm] [![GitHub][badge-github]][github] [![GitHub tests workflow][badge-actions]][actions]
[npm]: https://www.npmjs.com/package/vue-ts-types
[github]: https://github.com/FloEdelmann/vue-ts-types
[actions]: https://github.com/FloEdelmann/vue-ts-types/actions/workflows/test.yaml?query=branch%3Amain
[badge-npm]: https://img.shields.io/npm/v/vue-ts-types?logo=npm&logoColor=white&color=red
[badge-github]: https://img.shields.io/github/package-json/v/FloEdelmann/vue-ts-types?logo=github&color=blue
[badge-actions]: https://img.shields.io/github/actions/workflow/status/FloEdelmann/vue-ts-types/test.yaml?logo=github&label=Tests## Example
```ts
import { defineComponent } from 'vue';
import {
arrayProp,
booleanProp,
functionProp,
isPositive,
numberProp,
oneOfProp,
stringProp,
} from 'vue-ts-types';defineComponent({
props: {
disabled: booleanProp().withDefault(false),
// resulting prop type: booleantitle: stringProp().optional,
// resulting prop type: string | undefineddescription: stringProp().nullable,
// resulting prop type: string | nullitems: arrayProp().required,
// resulting prop type: string[]callback: functionProp<() => void>().optional,
// resulting prop type: (() => void) | undefinedcolor: oneOfProp(['red', 'green', 'blue'] as const).withDefault('red'),
// resulting prop type: 'red' | 'green' | 'blue'timeout: numberProp(isPositive).required,
// resulting prop type: number
},
});
```## Motivation
Prop declarations are verbose
Declaring props is quite verbose, especially if you are using TypeScript and want to annotate more complex types (with `PropType`).
```ts
options: {
type: Object as PropType,
required: true,
}// with vue-ts-types:
options: objectProp().required
```Annotating optional complex props is error-prone
It's easy to forget using a union type with `undefined` or `null` when the prop is not required.
```ts
options: {
type: Object as PropType, // wrong, it should be `Options | undefined`
required: false,
}// with vue-ts-types:
options: objectProp().optional // automatically typed as `Options | undefined`
```Specifying both
default
andrequired
can be contradictoryBy specifying a prop's default value, the prop is automatically optional, even when `required` is set to `true`. See also the [`vue/no-required-prop-with-default` ESLint rule](https://eslint.vuejs.org/rules/no-required-prop-with-default.html).
```ts
disabled: {
type: Boolean,
required: true,
default: false, // contradictory to `required: true`
}// with vue-ts-types:
disabled: booleanProp().required // either required without default
disabled: booleanProp().withDefault(false) // or optional with default
```Custom validation errors are not helpful
Since prop validators return only a boolean validation result, the reason why a value failed to validate is not printed in the console error.
```ts
age: {
type: Number,
required: true,
validator: (age: unknown) => {
return typeof age === 'number' && Number.isInteger(age) && age >= 18
},
}// with vue-ts-types:
age: integerProp((age: unknown) => {
if (typeof age !== 'number' || age < 18) {
return 'age should be a number of at least 18'
}
return undefined
}).required
```## Installation
```bash
npm install vue-ts-types
````vue-ts-types` has no dependencies and is tested to be compatible with [Vue.js](https://vuejs.org/) `v2.6`, `v2.7` and `v3.2`.
## Usage
Each of the prop functions returns an object with the following properties:
- `.optional`: Use this to mark the prop as not required with a default value of `undefined`. Also includes `undefined` in the resulting prop type.
- `.nullable`: Use this to mark the prop as not required with a default value of `null`. Also includes `null` in the resulting prop type.
- `.required`: Use this to mark the prop as required without a default value.
- `.withDefault(value)`: Use this to set a default value for the prop. Note that the value has to fit the prop type. For non-primitive types, the value has to be a function that returns the default value.> ℹ️ **Note:**
> Due to the way Vue props work, a prop's default value will only be used when passing `undefined`, not for `null`.
> See [issue #3135 in vuejs/vue](https://github.com/vuejs/vue/issues/3135).### Custom validator functions
Custom validator functions can be passed to any of the prop types. They are called with the value of the prop (type `unknown`) and should return a validation error message, or undefined if the value is valid. Validator functions do not influence type inference.
```ts
import { numberProp } from 'vue-ts-types';type Validator = (value: unknown) => string | undefined;
const isPositive: Validator = (value) => {
if (typeof value !== 'number' || value <= 0 || Number.isNaN(value)) {
return 'value should be a positive number';
}
return undefined;
};numberProp(isPositive).optional;
// → prop type: number | undefined
```For convenience, some common validator functions are included in the library and can be imported just like prop types:
- `isNegative`: only allows negative numbers (`< 0`)
- `isPositive`: only allows positive numbers (`> 0`)
- `isNonNegative`: only allows non-negative numbers (`>= 0`)
- `isNonPositive`: only allows non-positive numbers (`<= 0`)### `stringProp(validator?: Validator)`
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. (Consider using [`oneOfProp`](#oneofproptallowedvalues-readonly-any-validator-validator) in this case.)```ts
stringProp().optional;
// → prop type: string | undefined
stringProp().nullable;
// → prop type: string | null
stringProp().required;
// → prop type: string
stringProp().withDefault('foo');
// → prop type: stringtype Foo = 'a' | 'b' | 'c';
stringProp().optional;
// → prop type: Foo | undefined
stringProp().nullable;
// → prop type: Foo | null
stringProp().required;
// → prop type: Foo
stringProp().withDefault('a');
// → prop type: Foo
```### `booleanProp(validator?: Validator)`
Allows any boolean (validated at runtime and compile time).
```ts
booleanProp().optional;
// → prop type: boolean | undefined
booleanProp().nullable;
// → prop type: boolean | null
booleanProp().required;
// → prop type: boolean
booleanProp().withDefault(false);
// → prop type: boolean
```### `numberProp(validator?: Validator)`
Allows any number (validated at runtime and compile time).
Type parameter `T` can be used to restrict the type at compile time with a union type. (Consider using [`oneOfProp`](#oneofproptallowedvalues-readonly-any-validator-validator) in this case.)```ts
numberProp().optional;
// → prop type: number | undefined
numberProp().nullable;
// → prop type: number | null
numberProp().required;
// → prop type: number
numberProp().withDefault(3.1415);
// → prop type: numbertype Foo = 1 | 2 | 3;
numberProp().optional;
// → prop type: Foo | undefined
numberProp().nullable;
// → prop type: Foo | null
numberProp().required;
// → prop type: Foo
numberProp().withDefault(1);
// → prop type: Foo
```### `integerProp(validator?: Validator)`
Allows any integer (validated at runtime).
```ts
integerProp().optional;
// → prop type: number | undefined
integerProp().nullable;
// → prop type: number | null
integerProp().required;
// → prop type: number
integerProp().withDefault(42);
// → prop type: number
```### `symbolProp(validator?: Validator)`
Allows any symbol (validated at runtime and compile time).
```ts
symbolProp().optional;
// → prop type: symbol | undefined
symbolProp().nullable;
// → prop type: symbol | null
symbolProp().required;
// → prop type: symbol
symbolProp().withDefault(Symbol('foo'));
// → prop type: symbol
```### `vueComponentProp(validator?: Validator)`
Allows any Vue component instance, name or options object. No built-in runtime validation is performed by default.
```ts
vueComponentProp().optional;
// → prop type: VueComponent | undefined
vueComponentProp().nullable;
// → prop type: VueComponent | null
vueComponentProp().required;
// → prop type: VueComponent
vueComponentProp().withDefault('close-icon');
// → prop type: VueComponent
```> ℹ️ **Note:**
> The type `VueComponent` is defined to be `object | string`. It has to be so broad to allow Vue 2 and Vue 3 component options or instances.
> If you are able to narrow the type without pulling in heavy dependencies, please open an issue or pull request!### `anyProp(validator?: Validator)`
Allows any type. No built-in runtime validation is performed by default.
Type parameter `T` can be used to restrict the type at compile time.```ts
anyProp().optional;
// → prop type: any
anyProp().nullable;
// → prop type: any
anyProp().required;
// → prop type: any
anyProp().withDefault('foo');
// → prop type: anyanyProp().optional;
// → prop type: string | undefined
anyProp().nullable;
// → prop type: string | null
anyProp().required;
// → prop type: string
anyProp().withDefault('foo');
// → prop type: string
```### `arrayProp(validator?: Validator)`
Allows any array. No further runtime validation is performed by default.
Type parameter `T` can be used to restrict the type of the array items at compile time.```ts
arrayProp().optional;
// → prop type: unknown[] | undefined
arrayProp().nullable;
// → prop type: unknown[] | null
arrayProp().required;
// → prop type: unknown[]
arrayProp().withDefault(() => []);
// → prop type: unknown[]arrayProp().optional;
// → prop type: string[] | undefined
arrayProp().nullable;
// → prop type: string[] | null
arrayProp().required;
// → prop type: string[]
arrayProp().withDefault(() => ['foo', 'bar']);
// → prop type: string[]
```### `objectProp(validator?: Validator)`
Allows any object. No further runtime validation is performed by default.
Type parameter `T` can be used to restrict the type at compile time.```ts
objectProp().optional;
// → prop type: object | undefined
objectProp().nullable;
// → prop type: object | null
objectProp().required;
// → prop type: object
objectProp().withDefault(() => ({}));
// → prop type: objectinterface User {
name: string;
}objectProp().optional;
// → prop type: User | undefined
objectProp().nullable;
// → prop type: User | null
objectProp().required;
// → prop type: User
objectProp().withDefault(() => ({ name: 'John' }));
// → prop type: User
```### `functionProp(validator?: Validator)`
Allows any function. No further runtime validation is performed by default.
Type parameter `T` can be used to restrict the type to a specific function signature at compile time.> ℹ️ **Note:**
> There is no `.withDefault()` function for this prop type.```ts
functionProp().optional;
// → prop type: Function | undefined
functionProp().nullable;
// → prop type: Function | null
functionProp().required;
// → prop type: Functiontype MyFunc = (a: number, b: string) => boolean;
functionProp().optional;
// → prop type: MyFunc | undefined
functionProp().nullable;
// → prop type: MyFunc | null
functionProp().required;
// → prop type: MyFunc
```### `oneOfProp(allowedValues: readonly any[], validator?: Validator)`
Allows any of the specified allowed values (validated at runtime and compile time).
Type parameter `T` can be used to adjust the inferred type at compile time, this is usually not necessary.> ℹ️ **Note:**
> Proper type checking is only possible if the allowed values are readonly, usually through `as const`.```ts
oneOfProp(['foo', 'bar'] as const).optional;
// → prop type: 'foo' | 'bar' | undefined
oneOfProp(['foo', 'bar'] as const).nullable;
// → prop type: 'foo' | 'bar' | null
oneOfProp(['foo', 'bar'] as const).required;
// → prop type: 'foo' | 'bar'
oneOfProp(['foo', 'bar'] as const).withDefault('foo');
// → prop type: 'foo' | 'bar'
```### `oneOfObjectKeysProp(object: object, validator?: Validator)`
Allows any of the keys of the specified object (validated at runtime and compile time).
Type parameter `T` can be used to adjust the inferred type at compile time, this is usually not necessary.```ts
oneOfObjectKeysProp({ foo: 1, bar: 2 }).optional;
// → prop type: 'foo' | 'bar' | undefined
oneOfObjectKeysProp({ foo: 1, bar: 2 }).nullable;
// → prop type: 'foo' | 'bar' | null
oneOfObjectKeysProp({ foo: 1, bar: 2 }).required;
// → prop type: 'foo' | 'bar'
oneOfObjectKeysProp({ foo: 1, bar: 2 }).withDefault('foo');
// → prop type: 'foo' | 'bar'
```### `oneOfTypesProp(type: PropType, validator?: Validator)`
Allows any of the passed constructor types (validated at runtime).
Type parameter `T` has to be used to adjust the type at compile time.```ts
oneOfTypesProp([Number, String]).optional;
// → prop type: string | number | undefined
oneOfTypesProp([Number, String]).nullable;
// → prop type: string | number | null
oneOfTypesProp([Number, String]).required;
// → prop type: string | number
oneOfTypesProp([Number, String]).withDefault(42);
// → prop type: string | number
```### `instanceOfProp(parent: T, validator?: Validator)`
Allows instances of the given constructor (validated at runtime and compile time).
Type parameter `T` can be used to adjust the inferred type at compile time.```ts
instanceOfProp(Date).optional;
// → prop type: Date | undefined
instanceOfProp(Date).nullable;
// → prop type: Date | null
instanceOfProp(Date).required;
// → prop type: Date
instanceOfProp(Date).withDefault(() => new Date());
// → prop type: Date
```## Contributing
Please see [CONTRIBUTING.md](./CONTRIBUTING.md).
## Similar packages
- [vue-types](https://www.npmjs.com/package/vue-types/), which this project took heavy inspiration from
- [vue-prop](https://www.npmjs.com/package/vue-prop)
- [vuept](https://www.npmjs.com/package/vuept)## License
Unless otherwise noted, all source code is licensed under the MIT License.
Copyright (c) 2022 Flo Edelmann