Skip to main content

List

Defines a list attribute, containing elements of any type:

import { list } from 'dynamodb-toolbox/attributes/list';
import { string } from 'dynamodb-toolbox/attributes/string';

const pokeTypeSchema = string().enum('fire', ...)

const pokemonSchema = schema({
...
pokeTypes: list(pokeTypeSchema),
});

type FormattedPokemon = FormattedItem<typeof PokemonEntity>;
// => {
// ...
// pokeTypes: ('fire' | ...)[]
// }

List elements must respect some constraints:

  • They cannot be optional or always required
  • They cannot be hidden or key (tagging the list itself as key is enough)
  • They cannot have default or links
// ❌ Raises a type AND a run-time error
const strList = list(string().optional())
const strList = list(string().hidden())
const strList = list(string().key())
const strList = list(string().default('foo'))

Options

.required()

string | undefined

Tags the attribute as required (at root level or within Maps). Possible values are:

  • 'atLeastOnce' (default): Required (starting value)
  • 'always': Always required (including updates)
  • 'never': Optional
// Equivalent
const pokeTypesSchema = list(pokeTypeSchema)
const pokeTypesSchema = list(pokeTypeSchema).required()
const pokeTypesSchema = list(
pokeTypeSchema,
// Options can be provided as 2nd argument
{ required: 'atLeastOnce' }
)

// shorthand for `.required('never')`
const pokeTypesSchema = list(pokeTypeSchema).optional()
const pokeTypesSchema = list(..., { required: 'never' })

.hidden()

boolean | undefined

Skips the attribute when formatting items:

const pokeTypesSchema = list(pokeTypeSchema).hidden()
const pokeTypesSchema = list(..., { hidden: true })

.key()

boolean | undefined

Tags the attribute as needed to compute the primary key:

// Note: The method also sets the `required` property to 'always'
// (it is often the case in practice, you can still use `.optional()` if needed)
const pokeTypesSchema = list(pokeTypeSchema).key()
const pokeTypesSchema = list(..., {
key: true,
required: 'always'
})

.savedAs(...)

string

Renames the attribute during the transformation step (at root level or within Maps):

const pokeTypesSchema = list(pokeTypeSchema).savedAs('pt')
const pokeTypesSchema = list(..., { savedAs: 'pt' })

.default(...)

ValueOrGetter<ELEMENTS[]>

Specifies default values for the attribute. See Defaults and Links for more details:

Examples
const now = () => new Date().toISOString()

const timestampsSchema = list(string())
.default(() => [now()])
.updateDefault(() => $append(now()))
// 👇 Similar to
const timestampsSchema = list(...)
.putDefault(() => [now()])
.updateDefault(() => $append(now()))
// 👇 ...or
const timestampsSchema = list(..., {
defaults: {
key: undefined,
put: () => [now()],
update: () => $append(now())
}
})
info

☝️ On key attributes, .default(...) should be applied after .key().

.link<Schema>(...)

Link<SCHEMA, ELEMENTS[]>

Similar to .default(...) but allows deriving the default value from other attributes. See Defaults and Links for more details:

const pokemonSchema = schema({
pokeTypeSet: set(pokeTypeSchema)
}).and(prevSchema => ({
pokeTypeList: set(pokeTypeSchema).link<typeof prevSchema>(
// 🙌 Correctly typed!
({ pokeTypeSet }) => [...pokeTypeSet.values()]
)
}))
info

☝️ On key attributes, .link(...) should be applied after .key().

.validate(...)

Validator<ELEMENTS[]>

Adds custom validation to the attribute. See Custom Validation for more details:

Examples
const nonEmptyListSchema = list(string()).validate(
input => input.length > 0
)
// 👇 Similar to
const nonEmptyListSchema = list(string()).putValidate(
input => input.length > 0
)
// 👇 ...or
const nonEmptyListSchema = list(string(), {
validators: {
key: undefined,
put: input => input.length > 0,
update: undefined
}
})