Tipos mapeados homomórficos e não homomórficos
type type User = {
readonly name: string;
age?: number;
}
User = {
readonly name: stringname: string
age?: number | undefinedage?: number
}
type type Mapped = {
readonly name: string;
age?: number | undefined;
}
Mapped = { [function (type parameter) KeyKey in keyof type User = {
readonly name: string;
age?: number;
}
User]: type User = {
readonly name: string;
age?: number;
}
User[function (type parameter) KeyKey] } Então quer dizer que nunca te contaram sobrehomomorphic mapped typesenon homomorphic mapped types? Esses conceitos existem dentro de mapped types e são extremamente importantes, vamos explorar o motivo por trás de comportamentos que, à primeira vista, parecem estranhos, onde às vezes os modificadores('readonly'e'?')são mantidos em mapped types, e às vezes não.
Observação: antes de continuarmos, é importante que você já saiba o que são mapped types, fechou?
O que é um homomorphic mapped type?
Um homomorphic mapped type é um mapped type onde o compilador consegue saber que você está mapeando as propriedades de um objeto já existente, sendo assim, o compilador consegue manter os modificadores dessas propriedades.
Agora na prática, bora ver um exemplo de um mapped type que é homomórfico:
type type User = {
readonly name: string;
age?: number;
}
User = {
readonly name: stringname: string
age?: number | undefinedage?: number
}
type type Homomorphic = {
readonly name: string;
age?: number | undefined;
}
Homomorphic = { [function (type parameter) KeyKey in keyof type User = {
readonly name: string;
age?: number;
}
User]: type User = {
readonly name: string;
age?: number;
}
User[function (type parameter) KeyKey] }
// o compilador consegue reconhecer as keys
// de User, e manter seus modificadores (readonly e ?)
// {
// readonly name: string;
// age?: number | undefined;
// }O que é um non homomorphic mapped type
Um mapped type não homomórfico é o contrário de um mapped type homomórfico, é quando o mapped type não mantém os modificadores, vejamos um exemplo:
type type User = {
readonly name: string;
age?: number;
}
User = {
readonly name: stringname: string
age?: number | undefinedage?: number
}
type type UserKeys = keyof UserUserKeys = keyof type User = {
readonly name: string;
age?: number;
}
User // "name" | "age"
type type NonHomomorphic = {
name: string;
age: number | undefined;
}
NonHomomorphic = { [function (type parameter) KeyKey in type UserKeys = keyof UserUserKeys]: type User = {
readonly name: string;
age?: number;
}
User[function (type parameter) KeyKey] }
// aqui o compilador não consegue estabelecer
// esse vínculo, o que ele enxerga é apenas
// a union "name" | "age", sendo assim, os
// modificadores não são mantidos
// {
// name: string;
// age: number | undefined;
// }Após ver o código acima, talvez a seguinte dúvida possa surgir:"você disse que os modificadores não são mantidos, e realmente não foram, mas por qual motivo a propriedade age teve o tipo inferido como number | undefined, se o modificador "?" não foi mantido?"
Playground com os exemplos