1
resposta

Dúvida sobre serialização e Typescript

Bom dia!

Se eu seguir o exemplo apresentado nos vídeos, funciona tudo conforme o esperado.

No entanto, supondo que eu quisesse atribuir um ID à entidade Usuario. Ela seria assim:

export class Usuario {
  id: string;

  @Expose({ name: 'username' })
  @IsString({ message: 'Nome de usuário é obrigatório.' })
  nome: string;

  @Exclude({ toPlainOnly: true })
  @Exclude()
  @Expose({ name: 'password' })
  @IsNotEmpty({ message: 'senha é obrigatório.' })
  senha: string;

  @IsLoginUnico({ message: 'Já existe esse login cadastrado.' })
  @IsString({ message: 'Login é obrigatório.' })
  login: string;

  @Expose({ name: 'age' })
  @IsNumber(
    { allowNaN: false, maxDecimalPlaces: 0 },
    { message: 'Idade é obrigatória.' },
  )
  @Min(18, { message: 'Idade mínima deve ser 18 anos.' })
  @Max(90, { message: 'Idade máxima deve ser 90 anos.' })
  idade: number;
}

No service, ficaria mais ou menos assim o método de criação:

create(usuario: Usuario): Usuario {
  const usuarioCriado = {
    id: randomUUID(),
    ...usuario,
  } as Usuario;

  this.usuarios.push(usuario);

  return usuarioCriado;
}

constructor.name do usuario é Usuario; e dousuarioCriado é object.

Se eu reotrnar o usuario, ou seja, o modelo que veio nos argumentos da função, a serialização funciona (são apresentados, somente, os campos age, username e login). Mas se eu retornar o usuarioCriado (objeto do argumento + id), a serialização não funciona.

Eu entendo o motivo. Na documentação do NestJS isso fica bem claro:

Note that we must return an instance of the class. If you return a plain JavaScript object, for example, { user: new UserEntity() }, the object won't be properly serialized.

Aí eu fiquei na dúvida do motivo do usuarioCriado não ser do tipo Usuario. Mesmo se eu instanciar ele de outra forma, acontece a mesma coisa.

Pq isso acontece?

1 resposta

Oi, André! Tudo bem?

Desculpa a demora por um retorno.

A razão pela qual o usuarioCriado não é do tipo Usuario nesse caso é porque o objeto retornado não é uma instância da classe Usuario, mas sim um objeto JavaScript plano.

No código podemos notar a criação do objeto usuarioCriado usando a sintaxe { id: randomUUID(), ...usuario } as Usuario, no entanto, o operador as Usuario apenas fornece uma inferência de tipo ao compilador do TypeScript, mas não garante que o objeto seja uma instância da classe Usuario em tempo de execução.

Para garantir que o objeto usuarioCriado seja uma instância da classe Usuario, precisamos criar uma nova instância explicitamente, atribuindo os valores correspondentes, como no exemplo abaixo:

const usuarioCriado = new Usuario();
usuarioCriado.id = randomUUID();
usuarioCriado.nome = usuario.nome;
usuarioCriado.senha = usuario.senha;
usuarioCriado.login = usuario.login;
usuarioCriado.idade = usuario.idade;

Dessa forma, o objeto usuarioCriado será uma instância da classe Usuario e a serialização funcionará corretamente ao retorná-lo.

Espero ter ajudado na compreensão do problema. Caso tenha ficado alguma dúvida, sinta-se à vontade em comunicar, estou à disposição!

Um forte abraço e bons estudos!

Caso este post tenha te ajudado, por favor, marcar como solucionado ✓

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software