Skip to content

Instantly share code, notes, and snippets.

@nemoinho
Created June 18, 2021 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nemoinho/2283f806ce9cfe677cba839595b3635c to your computer and use it in GitHub Desktop.
Save nemoinho/2283f806ce9cfe677cba839595b3635c to your computer and use it in GitHub Desktop.
Branding and DTOs in typescript
declare const ___brand: unique symbol;
type Branded<A, B> = A & { readonly [___brand]: B };
type UID = Branded<number, User>;
interface User {
id: UID;
name: string;
lastLogin: Date;
items: {
name: string;
creationDate: Date;
}[],
alias: string[]
}
type DtoBaseTypes = number|string|boolean|number[]|string[]|boolean[];
type Dto<T> = {
[P in keyof T]: T[P] extends Date ? string : T[P] extends DtoBaseTypes ? T[P] : Dto<T[P]>
};
function userFromDto(dto: Dto<User>): User {
return {
...dto,
lastLogin: new Date(dto.lastLogin),
items: dto.items.map(item => ({
...item,
creationDate: new Date(item.creationDate)
}))
}
}
const user = userFromDto({
id: 123 as UID,
name: 'Alice',
lastLogin: '2021-05-07T09:49:06.888Z',
items: [{
name: 'A',
creationDate: '2021-05-07T09:49:06.888Z'
}],
alias: ['hello', 'world']
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment