https://github.com/socialaccess-network/isa
A simple and lightweight library for creating and validating javascript variables. It is designed to be used with typescript, but can also be used with plain javascript.
https://github.com/socialaccess-network/isa
javascript type-guards typescript validation validation-library
Last synced: 2 months ago
JSON representation
A simple and lightweight library for creating and validating javascript variables. It is designed to be used with typescript, but can also be used with plain javascript.
- Host: GitHub
- URL: https://github.com/socialaccess-network/isa
- Owner: socialaccess-network
- License: unlicense
- Created: 2023-03-23T19:54:59.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2023-12-05T23:20:11.000Z (over 2 years ago)
- Last Synced: 2025-12-27T09:56:08.969Z (6 months ago)
- Topics: javascript, type-guards, typescript, validation, validation-library
- Language: TypeScript
- Homepage:
- Size: 25.1 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @sa-net/isa
A simple and lightweight library for creating and validating javascript variables. It is designed to be used with [typescript](https://www.typescriptlang.org/), but can also be used with plain javascript.
If using typescript, it requires version 5.0 or higher as it makes heavy use of `const` generics.
## Installation
```bash
yarn add @sa-net/isa
# or
npm install @sa-net/isa
```
## Examples
### Basic usage
```typescript
import { isa } from '@sa-net/isa';
const isaUser = isa.record({
name: isa.string
age: isa.number
})
// ...
const user: unknown = {
name: 'John Doe',
age: 42
}
if (isaUser(user)) {
// user is now of type { name: string, age: number }
console.log(user.name, user.email)
}
```
### Unions and Intersections
isa checks can be combined using `isa.union` and `isa.intersection` to create more complex checks.
```typescript
const hasName = isa.record({
name: isa.string,
})
const hasAge = isa.record({
age: isa.number,
})
// has type { name: string } | { age: number }
const hasNameOrAge = isa.union(hasName, hasAge)
// has type
// { name: string, age: number }
const hasNameAndAge = isa.intersection(hasName, hasAge)
```
### Optional and Nullable
isa checks can be made optional or nullable using `isa.optional` and `isa.nullable`.
```typescript
// has type { name: Optional, age: Nullable }
const isUser = isa.record({
name: isa.optional(isa.string),
age: isa.nullable(isa.number),
})
```
Notice with optional how the `name` property in the previous example does not have a `?:`. This means typescript is expecting the `name` property to exist on the object, but it can be `undefined`.
`isa.record` will still validate records missing a `name` property provided the check for it allows `undefined` as a value.
This is a current limitation of isa, but hopefully will be fixed in the future by looking for properties with the `Optional` type.
To get around this currently, you can provide a type to the `isa.record` function.
```typescript
// has type { name?: Optional }
const isUser = isa.record<{ name?: Optional }>({
name: isa.optional(isa.string),
})
```
### Combining isa checks
```typescript
const hasName = isa.record({
name: isa.string
})
const hasAge = isa.record({
age: isa.number
})
// has type { name: string, age: number }
const hasNameAndAge = isa.intersection(hasName, hasAge)
// has type
// { name: string, age: number, roles: Array<'admin' | 'user'> }
const isUser = isa.intersection(hasNameAndAge, isa.record({
roles: isa.array(isa.exact('admin'), isa.exact('user'))
}))
// has type
// { msgs: Array | string, user: Nullable<{ name: string, age: number, roles: Array<'admin' | 'user'> }> }
const isData = isa.record({
msgs: isa.union(isa.array(isa.string), isa.string)
user: isa.nullable(isUser)
})
```
## Custom isa functions
isa functions are just typescript type guards. However, a utility function is provided that can be used to create type guards with a additional `@` type-only property that can be used to get the type of what the type guard is checking for.
```typescript
import { checkFor, IsaType } from '@sa-net/isa'
class User {
declare name: string
}
export const isaUser = checkFor(value => value instanceof User)
// User
type ExtractedType = IsaType
```