Skip to content

Instantly share code, notes, and snippets.

@jonasantonelli
Created February 19, 2021 18:29
Show Gist options
  • Save jonasantonelli/6916220392ab8a67a455e8f67876b924 to your computer and use it in GitHub Desktop.
Save jonasantonelli/6916220392ab8a67a455e8f67876b924 to your computer and use it in GitHub Desktop.
Virtasant Compose Type Safety
// Function composition is a way to combine several simpler function into a more complicated one.
const readFromTextInput = (): string => {
// some pseudocode
return "abcde"
}
const addSignature = (input: string): string => {
return input + 'Hello AI.';
}
const fitInSMS = (input: string, limit: number = 160): boolean => {
return input.length <= limit
}
// Given these three simple functions, we can compose the following chain.
// const canSMS = fitInSMS(addSignature(readFromTextInput()))
// Alternatively, we can use compose(...) function
// const canSMS = compose(readFromTextInput, addSignature, fitInSMS)
// 1. The task is to write type-safe compose function
function compose<A, B, C>(
f1: (c: C) => string,
f2: (b: B) => string,
f3: (a: A) => boolean,
): boolean
function compose(...funcs: any[]) {
if (funcs.length === 0) {
return <T>(arg: T) => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args: any) => a(b(...args)))
}
// 1.1. Success case
// TS Transpiler should understand the return type of compose function
// const canSMS: boolean = compose(readFromTextInput, addSignature, fitInSMS)
const canSMS: boolean = compose(readFromTextInput, addSignature, fitInSMS)
// 1.2. Fail case
// TS Transpiler should validate types of parameters passed from one function to another, e.g.
const readFromNumberInput = (): number => {
// pseudocode
return 13
}
// This scenario should fail, because readFromNumberInput returns a number, however addSignature accepts string
const canFail: boolean = compose(readFromNumberInput, addSignature, fitInSMS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment