Już to robiliśmy wcześniej, ale teraz chciałbym to jeszcze raz pokazać i zwrócić uwagę jak to robimy. Czyli dodawanie nowych pól do już istniejącego typu. Zaczynamy.

Utworzymy sobie jakiś typ:

type ExampleType0 = {
    firstName: string;
    lastName: string;
    age: number;
}

Ok, teraz przemapujemy sobie pola tego typu, nic nie zmieniając:

type WithTimestamp<T> = {
    [P in keyof T]: T[P];
};

type ExWithTime = WithTimestamp<ExampleType0>

// type ExWithTime = {
//     firstName: string;
//     lastName: string;
//     age: number;
// }

I teraz dodajemy coś nowego za pomocą operatora &:

type WithTimestamp<T> = {
    [P in keyof T]: T[P];
} & { timestamp: Date};

type ExWithTime = WithTimestamp<ExampleType0>

// type ExWithTime = {
//     firstName: string;
//     lastName: string;
//     age: number;
// } & {
//     timestamp: Date;
// }

Tak to się robi w TS. Inny przykład:

type ExampleType0 = {
    firstName: string;
    lastName: string;
    age: number;
}

type Flags<T> = {
    [P in keyof T]: boolean;
};

type ExampleFlags = Flags<ExampleType0>

// type ExampleFlags = {
//     firstName: boolean;
//     lastName: boolean;
//     age: boolean;
// }

Ok, teraz zabawimy się nieco:

type ExampleType0 = {
    firstName: string;
    lastName: string;
    age: number;
}

type WithFlags<T> = {
    [P in keyof T]: T[P];
} & {
    [P in keyof T as `required${Capitalize<string & P>}`] : boolean;
}

type ExampleFlags = WithFlags<ExampleType0>

// type ExampleFlags = {
//     firstName: string;
//     lastName: string;
//     age: number;
// } & {
//     requiredFirstName: boolean;
//     requiredLastName: boolean;
//     requiredAge: boolean;
// }

Ok, to by było na tyle, więcej TSa niedługo!