Skip to content

Instantly share code, notes, and snippets.

@yjaaidi
Last active June 8, 2016 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yjaaidi/695d7e3d23c117349f04b63095c35b2f to your computer and use it in GitHub Desktop.
Save yjaaidi/695d7e3d23c117349f04b63095c35b2f to your computer and use it in GitHub Desktop.
TypeScript dynamic runtime contracts example
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