Alias de Claves con @QAlias
@QAlias mapea una propiedad del modelo a un nombre de clave externo que se usa tanto en la entrada (create(), new, fromJSON()) como en la salida (serialize(), toJSON()). Esto facilita trabajar con APIs en snake_case manteniendo camelCase en el código del modelo.
Ejemplo Básico
import { Quick, QModel, QAlias } from 'quickmodel';
interface IUsuario {
firstName: string;
lastName: string;
emailAddress: string;
}
type IUsuarioAliasMap = {
firstName: 'first_name';
lastName: 'last_name';
emailAddress: 'email_address';
};
@Quick()
class UsuarioModel extends QModel<IUsuario, IUsuarioAliasMap> {
@QAlias('first_name')
declare firstName: string;
@QAlias('last_name')
declare lastName: string;
@QAlias('email_address')
declare emailAddress: string;
}Entrada: create() con payload en snake_case
// Funciona con claves alias (p. ej. desde una API REST) — tipado completo, sin `as any`:
const usuario = UsuarioModel.create({
first_name: 'Alice',
last_name: 'Smith',
email_address: 'alice@ejemplo.com',
});
console.log(usuario.firstName); // 'Alice' ✅ camelCase dentro del modelo
console.log(usuario.emailAddress); // 'alice@ejemplo.com'TIP
Pasar las claves camelCase originales (firstName, etc.) también funciona como fallback. Cuando están ambas — la clave alias y la clave de propiedad — en el payload, la alias tiene prioridad.
Salida: serialize() emite claves alias
const salida = usuario.$qSerialize();
// {
// first_name: 'Alice',
// last_name: 'Smith',
// email_address: 'alice@ejemplo.com'
// }
const json = usuario.toJSON();
// '{"first_name":"Alice","last_name":"Smith","email_address":"alice@ejemplo.com"}'Los campos sin @QAlias conservan su nombre de propiedad original en la salida.
Roundtrip Completo
Dado que tanto la entrada como la salida usan las claves alias, el resultado serializado puede pasarse directamente de vuelta a create():
const serializado = usuario.$qSerialize();
const restaurado = UsuarioModel.create(serializado);
restaurado.firstName === 'Alice'; // ✅
restaurado.emailAddress === 'alice@ejemplo.com'; // ✅fromJSON() también soporta el roundtrip:
const json = usuario.toJSON();
const restaurado = UsuarioModel.fromJSON(json);
restaurado.firstName === 'Alice'; // ✅Campos Mixtos
Solo las propiedades decoradas con @QAlias son remapeadas. Los demás campos conservan sus claves originales.
type IPerfilAliasMap = { nombreCompleto: 'nombre_completo' };
@Quick({ fechaNacimiento: Date })
class PerfilModel extends QModel<IPerfil, IPerfilAliasMap> {
@QAlias('nombre_completo')
declare nombreCompleto: string;
declare fechaNacimiento: Date; // sin alias
}
const p = PerfilModel.create({
nombre_completo: 'Jane Doe',
fechaNacimiento: '1990-01-01',
});
p.nombreCompleto; // 'Jane Doe' ✅
p.fechaNacimiento; // objeto Date ✅
p.$qSerialize();
// { nombre_completo: 'Jane Doe', fechaNacimiento: '1990-01-01T00:00:00.000Z' }Herencia
Las subclases heredan los @QAlias del padre. Los alias adicionales se pueden declarar en la subclase.
@Quick()
class AdminModel extends UsuarioModel {
@QAlias('numero_telefono')
declare numeroTelefono: string;
}
const admin = AdminModel.create({
first_name: 'Dan',
last_name: 'Lee',
email_address: 'dan@ejemplo.com',
numero_telefono: '555-1234',
});
admin.firstName; // 'Dan'
admin.numeroTelefono; // '555-1234'
admin.$qSerialize(); // { first_name: 'Dan', ..., numero_telefono: '555-1234' }Referencia de API
@QAlias(alias: string)
| Parámetro | Tipo | Descripción |
|---|---|---|
alias | string | Nombre de la clave externa (p. ej. 'first_name', 'user_id') |
Comportamiento:
- Remapping de entrada: si la clave
aliasestá presente en el payload al crear, se renombra al nombre de propiedad antes de la deserialización. La clave camelCase sigue aceptándose como fallback. - Remapping de salida:
serialize()ytoJSON()emitenaliasen lugar del nombre de propiedad. - Herencia: las subclases heredan los alias mediante recorrido de la cadena prototipo.
Casos de Uso Comunes
| Escenario | Ejemplo |
|---|---|
| API REST con campos en snake_case | @QAlias('created_at') en createdAt |
| Mapeo de modelos externos | @QAlias('user_id') en userId |
| Nombres de columnas de DB | @QAlias('phone_number') en phoneNumber |
| Nombres de campo legacy | @QAlias('e_mail') en email |
Rendimiento
⚡ Comparativa de rendimiento
Pasa el ratón sobre las barras para ver detalles
2k instanciaciones — payload API en snake_case → modelo camelCase. Plain JS: el más rápido pero requiere mapper hardcoded que se rompe con cada cambio de schema. class-transformer: copia a instancia de clase pero mantiene las claves snake_case originales sin configuración @Expose+@Transform. QuickModel @QAlias: renombrado sin boilerplate al instanciar, compatible con coerción de tipos y validación.