Skip to content

Commit

Permalink
Merge branch 'next'
Browse files Browse the repository at this point in the history
  • Loading branch information
dwightjack committed Sep 6, 2021
2 parents 82aa0e5 + 749f5b8 commit 9026f26
Show file tree
Hide file tree
Showing 55 changed files with 1,949 additions and 1,883 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist
node_modules
shim
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ Icon
.Spotlight-V100
.Trashes
dist
shim/*.*
!shim/package.json
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.17.4
14.17.5
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.17.4
14.17.5
4 changes: 4 additions & 0 deletions __tests__/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
/* eslint-env jest */
console.log = jest.fn()
console.warn = jest.fn()
console.error = jest.fn()
console.debug = jest.fn()
console.info = jest.fn()
44 changes: 43 additions & 1 deletion __tests__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import * as utils from '../src/utils'
import { VueTypeDef } from '../src/types'
import { VueTypeDef } from '../src'
import { config } from '../src'

beforeEach(() => {
config.logLevel = 'warn'
config.silent = false
})

describe('`getType()`', () => {
it('return the type constructor as a string', () => {
Expand Down Expand Up @@ -331,3 +337,39 @@ describe('`fromType()`', () => {
expect(validatorCopy.mock.instances[0]).toBe(copy as any)
})
})

describe('`warn()`', () => {
it('calls `console.warn` by default', () => {
const message = 'message'
utils.warn(message)
expect(console.warn).toHaveBeenCalledWith(`[VueTypes warn]: ${message}`)
})

it('calls `console.log` if `config.logLevel` is `log`', () => {
config.logLevel = 'log'
const message = 'message'
utils.warn(message)
expect(console.log).toHaveBeenCalledWith(`[VueTypes warn]: ${message}`)
})

it('calls `console.error` if `config.logLevel` is `error`', () => {
config.logLevel = 'error'
const message = 'message'
utils.warn(message)
expect(console.error).toHaveBeenCalledWith(`[VueTypes warn]: ${message}`)
})

it('calls `console.debug` if `config.logLevel` is `debug`', () => {
config.logLevel = 'debug'
const message = 'message'
utils.warn(message)
expect(console.debug).toHaveBeenCalledWith(`[VueTypes warn]: ${message}`)
})

it('calls `console.info` if `config.logLevel` is `info`', () => {
config.logLevel = 'info'
const message = 'message'
utils.warn(message)
expect(console.info).toHaveBeenCalledWith(`[VueTypes warn]: ${message}`)
})
})
7 changes: 6 additions & 1 deletion __tests__/validators/oneoftype.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { string, integer } from '../../src/validators/native'
import { string, integer, any } from '../../src/validators/native'
import oneOf from '../../src/validators/oneof'
import shape from '../../src/validators/shape'
import oneOfType from '../../src/validators/oneoftype'
Expand Down Expand Up @@ -65,4 +65,9 @@ describe('`.oneOfType`', () => {

expect(validator({ id: 2 })).toBe(false)
})

it('should validate edge cases with null and true', () => {
expect(oneOfType([any()]).type).toBe(null)
expect(oneOfType([{ type: true }]).type).toBe(null)
})
})
1 change: 1 addition & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module.exports = {
children: [
'/advanced/extending-vue-types',
'/advanced/custom-instance',
'/advanced/typescript',
],
},
],
Expand Down
239 changes: 239 additions & 0 deletions docs/advanced/typescript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
# TypeScript Usage

VueTypes is written in TypeScript and comes with full builtin types support.

Most of the validators can infer the prop type from their configuration:

```ts
props: {
// prop type is `string`
name: string(),
// ERROR: Argument of type 'boolean' is not assignable to parameter of type 'string'
surname: string().def(false),
}
```

## Optional type constraint

Some validators accepts an optional type argument to refine their TS typing.

### any<T = any>

```ts
props: {
unknownProp: any<unknown>()
}
```

### string<T = string>

Accepts both strings and enums.

```ts
props: {
// use a union type to constrain the string type
color: string<'red' | 'green'>()
}

enum Colors {
red = 'red'
green = 'green'
}

props: {
// same as above, but with an enum
color: string<Colors>()
}
```

::: tip
The same prop type can be expressed using `oneOf` which will also perform a validation at runtime:

```ts
props: {
genre: oneOf(['red', 'green'] as const)
}
```

:::

### number<T = number> and integer<T = number>

```ts
props: {
// use a union type to constrain the number type
count: number<1 | 2>()

countInt: integer<1 | 2>()
}
```

### func<T = (...args: any[]) => any>

Useful to type event handlers and function return types.

```ts
type EventFn = (e: Event) => void
type AsyncFn = () => Promise<string[]>

props: {
onClick: fn<EventFn>()
loadStrings: fn<AsyncFn>()
}
```

### object<T = { [key: string]: any }>

```ts
interface User {
name: string
// ...
}

props: {
user: object<User>()
}
```

::: tip
To have both compile-time and runtime validation, you can use `shape`:

```ts
interface User {
name: string
// ...
}

props: {
user: shape<User>({
name: string().isRequired,
})
}
```

:::

### array<T = unknown>

The validator accepts an argument defining the contained items type.

```ts
interface User {
name: string
// ...
}

props: {
// array of numbers
sizes: array<number>()
// array of users
users: array<User>()
}
```

::: tip
The same prop types can be expressed using `arrayOf` which will also perform a validation at runtime:

```ts
interface User {
name: string
// ...
}

props: {
sizes: arrayOf(Number)
// set the object() validator type to User
users: arrayOf(object<User>())
}
```

:::

### OneOfType\<T>

You can use a union type to specify the expected types.

```ts
interface User {
name: string
// ...
}

props: {
// string or instance of User
theProp: oneOfType<string | User>([String, Object])
}
```

::: tip
The same prop types can be expressed composing VueTypes validators:

```ts
interface User {
name: string
// ...
}

props: {
// same as above
theProp: oneOfType([String, object<User>()])
}
```

:::

### shape\<T>

Setting the type argument provides type checking on top of runtime validation:

```ts
interface User {
name: string
id?: string
}

props: {
user: shape<User>({
name: string().isRequired,
id: string(),
})
}
```

### custom\<T>

You can define the type of the value received by the validator function.

```ts
props: {
// function argument is of type string
nonEmptyString: custom<string>((v) => typeof v === 'string' && v.length > 0)
}
```

::: tip
This validator can be used for tuple props:

```ts
type Pair = [string, number]

props: {
tuple: custom<Pair>(
([a, b]) => typeof a === 'string' && typeof b === 'number',
)
}
```

:::

### oneOf

This validator does not support type arguments, but you can use [const assertions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) on the expected values to constrain the validators type:

```ts
props: {
// ERROR: Argument of type '"small"' is not assignable
// to parameter of type '"large" | "medium"'.
sizes: oneOf(['large', 'medium'] as const).def('small')
}
```
4 changes: 2 additions & 2 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ VueTypes.config === config

## Configuration Options

At the moment, there is only one configuration option:

- `silent`: (boolean, default `false`) set to `true` to prevent VueTypes from logging validation warnings.

::: tip
Expand All @@ -37,3 +35,5 @@ config.silent = Vue.config.silent
```

:::

- `logLevel`: (string, default `warn`) allows choosing which console method will be used to display validation errors. Available options are `log`, `warn`, `error`, `debug` and`info`.
Loading

0 comments on commit 9026f26

Please sign in to comment.