Skip to content

Commit

Permalink
add not null assertion site example
Browse files Browse the repository at this point in the history
  • Loading branch information
koskimas committed Mar 23, 2024
1 parent 0e194b0 commit 58ba4ae
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
26 changes: 26 additions & 0 deletions site/docs/examples/SELECT/0051-not-null.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const notNull = `import { NotNull } from 'kysely'
import { jsonObjectFrom } from 'kysely/helpers/postgres'
const persons = db
.selectFrom('person')
.select((eb) => [
'last_name',
// Let's assume we know the person has at least one
// pet. We can use the \`.$notNull()\` method to make
// the expression not null. You could just as well
// add \`pet\` to the \`$narrowType\` call below.
jsonObjectFrom(
eb.selectFrom('pet')
.selectAll()
.limit(1)
.whereRef('person.id', '=', 'pet.owner_id')
).$notNull().as('pet')
])
.where('last_name', 'is not', null)
// $narrowType can be used to narrow the output type.
// The special \`NotNull\` type can be used to make a
// selection not null. You could add \`pet: NotNull\`
// here and omit the \`$notNull()\` call on it.
// Use whichever way you prefer.
.$narrowType<{ last_name: NotNull }>()
.execute()`
37 changes: 37 additions & 0 deletions site/docs/examples/SELECT/0051-not-null.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: 'Not null'
---

# Not null

Sometimes you can be sure something's not null but Kysely isn't able to infer
it. For example calling `where('last_name', 'is not', null)` doesn't make
`last_name` not null in the result type but unless you have other where statements
you can be sure it's never null.

Kysely has a couple of helpers for dealing with these cases: `$notNull()` and `$narrowType`.
Both are used in the following example:

import {
Playground,
exampleSetup,
} from '../../../src/components/Playground'

import {
notNull
} from './0051-not-null'

<div style={{ marginBottom: '1em' }}>
<Playground code={notNull} setupCode={exampleSetup} />
</div>

:::info More examples
The API documentation is packed with examples. The API docs are hosted [here](https://kysely-org.github.io/kysely-apidoc/)
but you can access the same documentation by hovering over functions/methods/classes in your IDE. The examples are always
just one hover away!

For example, check out these sections:
- [select method](https://kysely-org.github.io/kysely-apidoc/interfaces/SelectQueryBuilder.html#select)
- [selectAll method](https://kysely-org.github.io/kysely-apidoc/interfaces/SelectQueryBuilder.html#selectAll)
- [selectFrom method](https://kysely-org.github.io/kysely-apidoc/classes/Kysely.html#selectFrom)
:::
39 changes: 39 additions & 0 deletions src/query-builder/select-query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,45 @@ export interface SelectQueryBuilder<DB, TB extends keyof DB, O>
* In case you use the {@link sql} tag you need to specify the type of the expression
* (in this example `string`).
*
* <!-- siteExample("select", "Not null", 51) -->
*
* Sometimes you can be sure something's not null but Kysely isn't able to infer
* it. For example calling `where('last_name', 'is not', null)` doesn't make
* `last_name` not null in the result type but unless you have other where statements
* you can be sure it's never null.
*
* Kysely has a couple of helpers for dealing with these cases: `$notNull()` and `$narrowType`.
* Both are used in the following example:
*
* ```ts
* import { NotNull } from 'kysely'
* import { jsonObjectFrom } from 'kysely/helpers/postgres'
*
* const persons = db
* .selectFrom('person')
* .select((eb) => [
* 'last_name',
* // Let's assume we know the person has at least one
* // pet. We can use the `.$notNull()` method to make
* // the expression not null. You could just as well
* // add `pet` to the `$narrowType` call below.
* jsonObjectFrom(
* eb.selectFrom('pet')
* .selectAll()
* .limit(1)
* .whereRef('person.id', '=', 'pet.owner_id')
* ).$notNull().as('pet')
* ])
* .where('last_name', 'is not', null)
* // $narrowType can be used to narrow the output type.
* // The special `NotNull` type can be used to make a
* // selection not null. You could add `pet: NotNull`
* // here and omit the `$notNull()` call on it.
* // Use whichever way you prefer.
* .$narrowType<{ last_name: NotNull }>()
* .execute()
* ```
*
* All the examples above assume you know the column names at compile time.
* While it's better to build your code like that (that way you also know
* the types) sometimes it's not possible or you just prefer to write more
Expand Down

0 comments on commit 58ba4ae

Please sign in to comment.