Last active
February 9, 2025 15:32
-
-
Save queerviolet/f5d84865129a17711d7bef661fbb247d to your computer and use it in GitHub Desktop.
Type Annotation Comments in JS
This file contains hidden or 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
/** | |
* I like annotating my functions with comments that contain type annotations. | |
* The annotation syntax I use is, obviously, not an actual language, but it's | |
* strict enough to be one. Perhaps some day I'll write a yet another type flow tool | |
* to check these things! | |
* | |
* The syntax is a mishmash of Swift and JS destructuring expressions. | |
**/ | |
/***** Basic format *****/ | |
// x: Number | |
const x = 5 // I rarely type annotate individual variables, but if I did, that's how it would look. | |
// sum(a: Number, b: Number) -> Number | |
// | |
// sum takes two Numbers, a and b, and returns their sum, also a Number. | |
// a and b must be present and may not be null. | |
// | |
// (Note that we don't actually check this in the function, but if it's not | |
// true, the caller is violating the contract and we make no guarantees as | |
// to what will happen). | |
function sum(a, b) { return a + b } | |
// sumMaybeNumbers(a: Number?, b: Number?) -> Number | |
// | |
// sum takes two numbers, a and b, which may be null, and returns a Number. | |
function sumMaybeNumbers(a, b) { | |
return (a || 0) + (b || 0) | |
} | |
// sumArray(nums: [...Number]) -> Number | |
// | |
// sumArray takes an array of numbers and returns their sum, also a Number. | |
// We represent an array of numbers with the type [...Number], inspired by the | |
// rest operator. | |
function sumArray(nums) { return nums.reduce((x, y) => x + y) } | |
// increment(nums!: [...Number]) -> [...Number] | |
// | |
// increment takes an array of numbers and modifies it by adding one to each | |
// element in the array. | |
// | |
// We use `nums!` to indicate that it will be modified. | |
function increment(array) { | |
let i = array.length; while(--i >= 0) { --array[i] } | |
return array | |
} | |
// read(file: String, done: (String)->any?) -> undef | |
// | |
// read takes a String filename and a done function. | |
// done takes a String (the file content) and returns anything. | |
function read(file, done) { | |
fs.readFile(file, (err, ok) => ok && done(ok.toString())) | |
} | |
/**** Composite types **** | |
* Composite types look like object literals, only they're made of types. | |
**/ | |
// area(box: {width: Number, height: Number}) -> Number | |
// | |
// area takes a box (which is an object that must have a width and height, both Numbers), | |
// and returns its area. | |
function area(box) { return box.width * box.height } | |
/**** Type definitions **** | |
* If I use a particular composite type a lot, I might want to give it a name. | |
* The syntax I use is: | |
* | |
* Size = {width: Number, height: Number} | |
* | |
* Which would now let me say, | |
* | |
* area(box: Size) -> Number | |
* | |
* To describe the area function above. | |
**/ | |
/**** Type algebra **** | |
* You can express that a parameter may be the intersection or union of different types with | |
* the & and | operators | |
**/ | |
// sumNumOrStr(a: Number|String, b: Number|String) -> Number | |
// | |
// Return the sum a and b. If strings, they will be converted | |
// to numbers. | |
function sumNumOrStr(a, b) { return (+a) + (+b) } | |
// Size = {width: Number, height: Number} | |
// Position = {x: Number, y: Number} | |
// Bounds = {top: Number, left: Number, bottom: Number, right: Number} | |
// bounds(box: Size & Position) -> Size & Position & Bounds | |
// | |
// box must have all the properties {width, height, x, y}, all Numbers. | |
// A new object is returned with the box's size and position and computed bounds. | |
function bounds(box) { | |
return Object.assign({}, box, { | |
top: box.y, | |
left: box.x, | |
bottom: box.y + box.height, | |
right: box.x + box.width | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment