Skip to content

Instantly share code, notes, and snippets.

@tannerlinsley
Last active January 22, 2021 19:28
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 tannerlinsley/18198fe6c478956d1033b0495d36eaaa to your computer and use it in GitHub Desktop.
Save tannerlinsley/18198fe6c478956d1033b0495d36eaaa to your computer and use it in GitHub Desktop.
Generic Mapping in Typescript Example
import { Merge } from 'type-fest'
type MergeGenerics<TDefaultGenerics, TUserGenerics> = Merge<
Required<TDefaultGenerics>,
TUserGenerics
>
interface Person {
name: string
}
interface DefaultGenerics {
User?: Person
Friend?: Person
Frienemy?: Person
}
interface NewUser<TGenerics extends DefaultGenerics> {
user: TGenerics['User']
friend: TGenerics['Friend']
frienemy: TGenerics['Frienemy']
}
interface User<TGenerics extends DefaultGenerics> extends NewUser<TGenerics> {
created: number
}
function createUser<
TUserGenerics extends DefaultGenerics = DefaultGenerics,
TGenerics extends MergeGenerics<
DefaultGenerics,
TUserGenerics
> = MergeGenerics<DefaultGenerics, TUserGenerics>
>(user: NewUser<TGenerics>): User<TGenerics> {
return { ...user, created: Date.now() }
}
// Usage
interface MyFrienemy extends Person {
age?: number
}
const user = createUser<{ Frienemy: MyFrienemy }>({
user: { name: 'tanner' },
friend: { name: 'Derek' },
frienemy: { name: 'Matt', age: 21 },
})
console.log(user.frienemy.age) // 21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment