Saltar al contenido principal

Manejo de valores null y undefined en condiciones WHERE

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

En condiciones 'WHERE', los valores null y undefined no son estrictamente válidos en TypeORM.

Pasar un valor null explícito es bloqueado por TypeScript (al tener strictNullChecks habilitado en tsconfig.json) en tiempo de compilación. Pero el comportamiento predeterminado es ignorar valores null en tiempo de ejecución. De manera similar, TypeScript permite valores undefined que también se ignoran en ejecución.

Esta aceptación de null y undefined puede generar resultados inesperados y requiere precaución. Especialmente cuando se reciben valores de entrada de usuario sin validación adecuada.

Por ejemplo, llamar Repository.findOneBy({ id: undefined }) devuelve la primera fila de la tabla, mientras que Repository.findBy({ userId: null }) no aplica filtros y retorna todas las filas.

El manejo de valores null y undefined puede personalizarse mediante la opción invalidWhereValuesBehavior en la configuración de tu fuente de datos. Esto aplica a todas las operaciones con condiciones WHERE: búsquedas, query builders y métodos de repositorio.

nota

El comportamiento actual cambiará en futuras versiones de TypeORM. Recomendamos configurar ambos comportamientos (null y undefined) como throw para prepararse.

Comportamiento predeterminado

Por defecto, TypeORM omite valores null y undefined en condiciones WHERE. Si incluyes una propiedad con valor null o undefined en tu cláusula WHERE, se ignorará:

// Both queries will return all posts, ignoring the text property
const posts1 = await repository.find({
where: {
text: null,
},
})

const posts2 = await repository.find({
where: {
text: undefined,
},
})

La forma correcta de buscar valores nulos es usando el operador IsNull (detalles en Opciones de búsqueda):

const posts = await repository.find({
where: {
text: IsNull(),
},
})

Configuración

Personaliza el manejo de valores nulos e indefinidos usando invalidWhereValuesBehavior en tu conexión:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "ignore" | "sql-null" | "throw",
undefined: "ignore" | "throw",
},
})

Opciones para null

El comportamiento para null admite tres valores:

'ignore' (predeterminado)

Los valores null de JavaScript se ignoran y la propiedad se omite:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "ignore",
},
})

// This will return all posts, ignoring the text property
const posts = await repository.find({
where: {
text: null,
},
})

'sql-null'

Los valores null de JavaScript se transforman en condiciones SQL NULL:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "sql-null",
},
})

// This will only return posts where the text column is NULL in the database
const posts = await repository.find({
where: {
text: null,
},
})

'throw'

Los valores null de JavaScript lanzan un TypeORMError:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "throw",
},
})

// This will throw an error
const posts = await repository.find({
where: {
text: null,
},
})
// Error: Null value encountered in property 'text' of a where condition.
// To match with SQL NULL, the IsNull() operator must be used.
// Set 'invalidWhereValuesBehavior.null' to 'ignore' or 'sql-null' in connection options to skip or handle null values.

Opciones para undefined

El comportamiento para undefined admite dos valores:

'ignore' (predeterminado)

Los valores undefined de JavaScript se ignoran y la propiedad se omite:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
undefined: "ignore",
},
})

// This will return all posts, ignoring the text property
const posts = await repository.find({
where: {
text: undefined,
},
})

'throw'

Los valores undefined de JavaScript lanzan un TypeORMError:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
undefined: "throw",
},
})

// This will throw an error
const posts = await repository.find({
where: {
text: undefined,
},
})
// Error: Undefined value encountered in property 'text' of a where condition.
// Set 'invalidWhereValuesBehavior.undefined' to 'ignore' in connection options to skip properties with undefined values.

Nota: Esto aplica solo a valores undefined explícitos, no a propiedades omitidas.

Uso combinado de opciones

Puedes configurar ambos comportamientos de forma independiente:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "sql-null",
undefined: "throw",
},
})

Esta configuración:

  1. Transformará valores null de JavaScript a SQL NULL

  2. Lanzará errores al encontrar valores undefined

  3. Seguirá ignorando propiedades no proporcionadas en WHERE

Esta combinación es útil cuando necesitas:

  • Ser explícito al buscar valores NULL en la base de datos

  • Detectar errores de programación donde valores undefined podrían filtrarse en tus consultas

Aplica a todas las operaciones WHERE

La configuración invalidWhereValuesBehavior aplica a todas las operaciones TypeORM con condiciones WHERE, no solo métodos find:

Query Builders

// UpdateQueryBuilder
await dataSource
.createQueryBuilder()
.update(Post)
.set({ title: "Updated" })
.where({ text: null }) // Respects invalidWhereValuesBehavior
.execute()

// DeleteQueryBuilder
await dataSource
.createQueryBuilder()
.delete()
.from(Post)
.where({ text: null }) // Respects invalidWhereValuesBehavior
.execute()

// SoftDeleteQueryBuilder
await dataSource
.createQueryBuilder()
.softDelete()
.from(Post)
.where({ text: null }) // Respects invalidWhereValuesBehavior
.execute()

Métodos del Repositorio

// Repository.update()
await repository.update({ text: null }, { title: "Updated" }) // Respects invalidWhereValuesBehavior

// Repository.delete()
await repository.delete({ text: null }) // Respects invalidWhereValuesBehavior

// EntityManager.update()
await manager.update(Post, { text: null }, { title: "Updated" }) // Respects invalidWhereValuesBehavior

// EntityManager.delete()
await manager.delete(Post, { text: null }) // Respects invalidWhereValuesBehavior

// EntityManager.softDelete()
await manager.softDelete(Post, { text: null }) // Respects invalidWhereValuesBehavior

Todas estas operaciones aplicarán consistentemente la configuración de invalidWhereValuesBehavior que hayas definido.