aviso:este site está em construção, então algumas coisas estão quebradas

Tipos mapeados homomórficos e não homomórficos

3 min de leitura
read in english
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