Last active
June 8, 2016 10:51
-
-
Save yjaaidi/695d7e3d23c117349f04b63095c35b2f to your computer and use it in GitHub Desktop.
TypeScript dynamic runtime contracts example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'reflect-metadata'; | |
let _contractDictMetadataKey = 'contractDict'; | |
let ApplyContracts = () => { | |
return (target, key) => { | |
let originalMethod = target[key]; | |
let contractDict = Reflect.getOwnMetadata(_contractDictMetadataKey, target, key); | |
target[key] = function (...argList) { | |
if (contractDict !== undefined) { | |
argList.forEach((value, index) => { | |
let contract = contractDict[index]; | |
if (contract === undefined) { | |
return; | |
} | |
if (!contract(value)) { | |
throw new Error(`Value '${value}' does not respect contract for \`${target.constructor.name}.${key}(param_${index})\`.`); | |
} | |
}); | |
} | |
return originalMethod(...argList); | |
} | |
}; | |
}; | |
let Contract = (contract: (value: any) => boolean) => { | |
return (target, key, index):any => { | |
let contractDict = Reflect.getOwnMetadata(_contractDictMetadataKey, target, key); | |
if (contractDict === undefined) { | |
contractDict = {}; | |
} | |
contractDict[index] = contract; | |
Reflect.defineMetadata(_contractDictMetadataKey, contractDict, target, key); | |
}; | |
}; | |
let isPositive = value => value > 0; | |
class Utils { | |
@ApplyContracts() | |
double(@Contract(isPositive) number: number): number { | |
return number * 2; | |
} | |
} | |
console.log(new Utils().double(2)); // 4 | |
console.log(new Utils().double(0)); // Error: Value '0' does not respect contract for `Utils.double(param_0)`. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment