Skip to main content

Type Inference

DynamoDB-Toolbox exposes several generic types to infer custom types from your schemas.

Which one you should use depends on your usage context, for instance, whether it’s within a write or a read operation.

Writes​

For write operations, DynamoDB-Toolbox exposes the following generic types:

  • ValidValue: A valid schema item
  • InputValue: Similar to ValidValue, but with defaulted and linked attributes optional
  • TransformedValue: A valid schema item after transformation
import type {
InputValue,
ValidValue,
TransformedValue
} from 'dynamodb-toolbox/schema'

type Input = InputValue<typeof pokemonSchema>
type Valid = ValidValue<typeof pokemonSchema>
type Transformed = TransformedValue<typeof pokemonSchema>

By default, those generics use the put write mode, but you can switch to the key or update modes with the mode option. This impacts which the presence and requiredness of attributes:

type ValidKey = ValidValue<
typeof pokemonSchema,
{ mode: 'key' }
>
type ValidUpdate = ValidValue<
typeof pokemonSchema,
{ mode: 'update' }
>
Example

Here are step-by-step examples:

☝️ Schema
const now = () => new Date().toISOString()

const pokemonSchema = schema({
// key attributes
pokemonClass: string()
.key()
.transform(prefix('POKEMON'))
.savedAs('partitionKey'),
pokemonId: string().key().savedAs('sortKey'),

// timestamps
created: string().default(now),
updated: string()
.required('always')
.putDefault(now)
.updateDefault(now),

// other attributes
name: string().optional(),
level: number().default(1)
}).and(prevSchema => ({
levelPlusOne: number().link<typeof prevSchema>(
({ level }) => level + 1
)
}))
πŸ”Ž 'put' mode
{
"pokemonClass": "pikachu",
"pokemonId": "123",
"name": "Pikachu"
}
πŸ”Ž 'key' mode
{
"pokemonClass": "pikachu",
"pokemonId": "123",
}
+ (Only key attributes are required)
πŸ”Ž 'update' mode
{
"pokemonClass": "bulbasaur",
"pokemonId": "123",
"name": "PlantyDino",
}

Reads​

For read operations, DynamoDB-Toolbox exposes the following generic types:

  • ReadValue: A valid schema item (differs from ValidValue as options are different, see below)
  • FormattedValue: Similar to ReadValue, but with hidden attributes omitted
import type {
ReadValue,
FormattedValue
} from 'dynamodb-toolbox/schema'

type Read = ReadValue<typeof pokemonSchema>
type Formatted = FormattedValue<typeof pokemonSchema>

By default, those generics return complete items, but you can filter attributes and/or apply Partial (deeply) with the attributes and partial options:

type Filtered = FormattedValue<
typeof pokemonSchema,
{ attributes: 'level' | 'name' | 'deep.attr[0].path' }
>
type Partial = FormattedValue<
typeof pokemonSchema,
{ partial: true }
>