Skip to content

Instantly share code, notes, and snippets.

@migrap
Created July 2, 2021 17:45
Show Gist options
  • Select an option

  • Save migrap/89e64153c894c46974146a4455f72681 to your computer and use it in GitHub Desktop.

Select an option

Save migrap/89e64153c894c46974146a4455f72681 to your computer and use it in GitHub Desktop.
union-types.ts
interface SystemAuthenticationDetails {
accountType: "system";
systemId: number;
}
interface UserAuthenticationDetails {
accountType: "user";
userId: string;
}
type AuthenticationDetails = SystemAuthenticationDetails | UserAuthenticationDetails;
type AuthenticationDetailsAccountType = AuthenticationDetails["accountType"];
const getSystemAccount = (id: number) => {
return `getSystemAccount(${id})`;
};
const getUserAccount = (id: string) => {
return `getUserAccount(${id})`;
};
type PatternMap<U extends { accountType: string }> = {
[K in U["accountType"]]: U extends { accountType: K } ? U : never;
};
type Pattern<T, R> = {
[K in keyof T]: (message: T[K]) => R;
};
const matcher = function<T extends { accountType: string }, R>(pattern: Pattern<PatternMap<T>, R>): (value: AuthenticationDetails) => R {
return value => pattern[value["accountType"]](value);
};
const getAccount = (authenticationDetails: AuthenticationDetails): string => {
return matcher<AuthenticationDetails, string>({
system: ({ systemId }) => getSystemAccount(systemId),
user: ({ userId }) => getUserAccount(userId)
})(authenticationDetails);
};
console.log(`sys => ${getAccount({ accountType: "system", systemId: 111 })}`);
console.log(`usr => ${getAccount({ accountType: "user", userId: "one" })}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment