Skip to content

Instantly share code, notes, and snippets.

@mbbx6spp
Last active August 26, 2021 22:09
Show Gist options
  • Save mbbx6spp/574a34cbc9fb2fdad99b222f9b93715b to your computer and use it in GitHub Desktop.
Save mbbx6spp/574a34cbc9fb2fdad99b222f9b93715b to your computer and use it in GitHub Desktop.
A solution to the problem where you want to distinguish identical data payload at both typechecking time and provide a way to inspect that type at runtime via values in TypeScript. Leverages branded parameter types with intersection types.
type Brand<Shared, EventType> = Shared & { readonly __eventType: EventType; };
type SharedCommentEventFields = {
otherField: string;
};
type CommentFlagged = Brand<SharedCommentEventFields, 'CommentFlagged'>;
type CommentRec = Brand<SharedCommentEventFields, 'CommentRec'>;
const makeCommentFlagEvent = (eventFields: SharedCommentEventFields): CommentFlagged => (
{ __eventType: "CommentFlagged", ...eventFields }
);
const makeCommentRecEvent = (eventFields: SharedCommentEventFields): CommentRec => (
{ __eventType: "CommentRec", ...eventFields }
);
const flagEvent = makeCommentFlagEvent({ otherField: "foo" });
const recEvent = makeCommentRecEvent({ otherField: "foo" });
// uncomment to see that this fails to type check
// console.log(flagEvent === recEvent);
console.log(flagEvent.__eventType)
console.log(recEvent.__eventType)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment