Skip to content

Instantly share code, notes, and snippets.

@despairblue
Last active May 10, 2017 12:17
Show Gist options
  • Save despairblue/571a393d829cc43698f5701217d6c991 to your computer and use it in GitHub Desktop.
Save despairblue/571a393d829cc43698f5701217d6c991 to your computer and use it in GitHub Desktop.
typesafe queue consumer
/**
* Types
*/
export interface I0 {
namespace: Namespaces
}
export interface IA extends I0 {
namespace: 'A'
}
export interface IB extends I0 {
namespace: 'B'
}
export interface IC extends I0 {
namespace: 'C'
payload: string
}
export interface ID extends I0 {
namespace: 'D'
}
export type Messages = IA | IB | IC | ID
export type Namespaces = Messages['namespace']
class NamespaceClass {
constructor(
public A = null,
public B = null,
public C = null,
public D = null,
) {}
}
export const namespaces = Object.keys(new NamespaceClass()) as NamespacesClassNamespaces[]
// If either of these does not typecheck you forgot to add your namespace to the
// `NamespaceClass` or the `Messages` union type.
//
// Both are necessary for different reasons:
//
// The Class can be used to get an Array of all keys and thus get an Array of
// all namespaces which is used by the mail-service to query the queue.
// Forgetting a namespace there would lead to the mail-service never getting
// those messages from the queue.
//
// The union type is used for exhaustiveness checking in the mail-service. If
// the union type contains a type that is not handled by the mail-service the
// compiler will yell. This makes sure that for all messages the mail-service
// queries the queue for, corresponding code exists that handles those messages.
type NamespacesClassNamespaces = keyof NamespaceClass
// If this fails: add the missing interface to the `Messages` union type.
let selfCheck1: Namespaces[]
selfCheck1 = namespaces as NamespacesClassNamespaces[]
// If this fails: add the missing namespace as a property to the
// `NamespaceClass`.
let selfCheck2: NamespacesClassNamespaces[]
selfCheck2 = namespaces as Namespaces[]
/**
* Dummy Implementation
*/
// tslint:disable-next-line: max-classes-per-file
class DummyQueue {
public find(_: string[]): Messages {
return {} as Messages
}
}
const dummyQueue = new DummyQueue()
while (true) {
handleMessage(getMessage(dummyQueue))
}
function getMessage(queue: DummyQueue): Messages {
return queue.find(namespaces)
}
function handleMessage(message: Messages): string {
switch (message.namespace) {
case 'A':
return message.namespace
case 'B':
return message.namespace
case 'C':
return message.payload
case 'D':
return message.namespace
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment