TS permite um objeto de outro "tipo" por parâmetro, além daquele que se espera.
No cód abaixo, estava vendo um pouco sobre objetos no ts, e acabei notando que a função sendMessage aceitou um objeto diferente do especificado.
const message: string = "Hello";
let user: {
name: string;
emailAddress: string;
age: number;
};
user = {
name: "Gabriel",
emailAddress: "biel46288@gmail.com",
age: 10,
};
class UserSender {
public name: string = "";
public emailAddress: string = "";
public constructor(name: string, emailAddress: string) {
this.name = name;
this.emailAddress = emailAddress;
}
}
function sendMessage(msg: string, user: UserSender): void {
console.log(
`Sended For: name: ${user.name},emailAddress: ${user.emailAddress}Message Sent: ${msg}`
);
}
sendMessage(message, new UserSender("Galvão", "gg@gmail.com")); // funciona
sendMessage(message, user); // tmb funciona
Ao pesquisar, notei que o ts faz a análise de validação, baseada na estrutura do objeto
, e não estritamente pelo seu tipo
, pq afinal, tanto UserSender
, quanto user
são do tipo object
.
Isso não seria um comportamento altamente indesejável?
Na realidade não é por ser objeto. Mas por ter as mesmas propriedades. Ou seja, como ambos tem as mesmas name e emailAddress, e o age não existe em UserSend, que é a definição, tá tudo certo. Basicamente nao falta nada, então ele aceita.
Tenha em mente que typescript é só javascript. E javascript não tem tipagem. Ou seja, quando você compila, vira tudo javascript e os dados estarão lá, ou seja, o esperado é que funcione depois de compilado. Só lembrando que typescript só existe durante o desenvolvimento. Após converter, é tudo js.
Ah, mas você deve pensar: Ok, mas é outra tipagem, mesmo que compatível. Isso é desejável? sim. É a forma como typescript foi pensado. Acho que chamam de Duck Type. É aquela piada do pato: se anda como um pato, voa como um pato e nada como um pato, então é um pato.