Gleb Bahmutov PRO
JavaScript ninja, image processing expert, software quality fanatic
Boston TypeScript Meetup
February 2019
these slides
C / C++ / C# / Java / CoffeeScript / JavaScript / Node / Angular / Vue / Cycle.js / functional / testing
18 people. Atlanta, Philly, Boston, Chicago, NYC
Fast, easy and reliable testing for anything that runs in a browser
C, C++
Java, C#
CoffeeScript
JavaScript
Angular, Node
Node, Hyperapp, Vue
C, C++
Java, C#
CoffeeScript
JavaScript
Angular, Node
Node, Hyperapp, Vue
Templates
template <class T>
struct is_class_or_union
{
// SFINAE eliminates this when the type of arg is invalid
template <class U>
static yes tester(int U::*arg);
// overload resolution prefers anything at all over "..."
template <class U>
static no tester(...);
// see which overload is chosen when U == T
static bool const value
= sizeof(tester<T>(0)) == sizeof(yes);
typedef mpl::bool_<value> type;
};
struct X{};
BOOST_STATIC_ASSERT(is_class_or_union<X>::value);
BOOST_STATIC_ASSERT(!is_class_or_union<int>::value);
C:\PROGRA~1\MICROS~4\VC98\INCLUDE\xutility(19) : error C2679:
binary '=''std::string' (or there is no acceptable conversion)
foo.cpp(9) : see reference to function template instantiation
'class std::back_insert_iterator<class std::map<std::string,
std::string,struct std::less<std::string>,class
std::allocator<std::string> > > __cdecl std::copy(class
std::list<std::string,class std::allocator<std::string>
>::iterator,class std::list<std::string,class std::allocator<
std::string> >::iterator,class std::back_insert_iterator<
class std::map<std::string,std::string,struct std::
less<std::string>,class std::allocator<std::string> > >)'
being compiled
What am I doing ...
C++ / Java / C#
CoffeeScript
JavaScript
aka OSS heaven
Stick Express into ServiceWorker?
self.addEventListener('fetch', function (event) {
const parsedUrl = url.parse(event.request.url)
var req = {
url: parsedUrl.href,
method: event.request.method,
body: body,
headers: {
'content-type': event.request.headers.get('content-type')
},
unpipe: function () {}
}
var res = { /* our mock Node http Server Response object */ }
event.respondWith(new Promise(function (resolve) {
app(req, res)
}))
})
whatever works
Hack Node require?
// really-need index.js
var _compileStr = Module.prototype._compile.toString();
// pass all arguments from loaded module to our self.require
_compileStr = _compileStr.replace('self.require(path);',
'self.require.apply(self, arguments);'); // 1
/* jshint -W061 */
var patchedCompile = eval('(' + _compileStr + ')'); // 2
Module.prototype._compile = function(content, filename) {
return patchedCompile.call(this, content, filename);
};
sure, replace a string in Node's internals
Try to connect separate pieces of software together ... This is also why I don't use type system like Typescript - it does not let me hack things together!
Jan 2016
undefined is not a function
E2E
unit
E2E
unit
linters
Ramda, _
crash
reporting
E2E
unit
linters
Ramda, _
crash
reporting
Ok, ok. It would be useful to have the computer check this code statically ...
winner 🏆
// @flow
/*::
type MyAlias = {
foo: number,
bar: boolean,
baz: string,
};
*/
function method(value /*: MyAlias */) /*: boolean */ {
return value.bar;
}
method({ foo: 1, bar: true, baz: ["oops"] });
Aug 2018
Step 1: code in JS
const add = (a, b) => a + b
add(2, 'foo')
Step 2: add comment
VSCode extension "Document This"
https://marketplace.visualstudio.com/items?itemName=joelday.docthis
Profit: IntelliSense
Step 3: @ts-check
Step 3: @ts-check
Profit: tsc check
$ npx tsc --noEmit --allowJs app.js
app.js:9:8 - error TS2345: Argument of type '"foo"' is not assignable
to parameter of type 'number'.
9 add(2, 'foo')
~~~~~
Found 1 error.
define object types
cast types
⚠️ VSCode finds "Person" type, but "
import definitions from another file
Tip: restarting TypeScript server changes results
Write type definitions in ".d.ts" files and use from JS
Use TS types from JavaScript
$ npm install -D cypress
it('adds 2 todos', () => {
cy.visit('http://localhost:3000')
cy.get('.new-todo')
.type('learn testing{enter}')
.type('be cool{enter}')
cy.get('.todo-list li')
.should('have.length', 2)
})
https://on.cypress.io/<command>
types/
index.d.ts
package.json
"types": "types"
Explains global "
User test - just add this comment
Explains "cy.visit" command
Completion for BDD assertions
Completion for specific assertion with examples
every command and assertion
links to full docs
inline examples
IntelliSense brakes on "@" character
IntelliSense does not respect indent
✅ Fixes "@" and indent
👎 tslint freaks out
pull request #3163
"@ts-check" complaints
1. Merge new method with existing global TypeScript definition in ".d.ts" file
2. Use "reference path=" comment to load ".d.ts" file
app.jsx
1. Add property to interface "Window"
2. Use "reference path=" comment to load ".d.ts" file
VSCode: in the user settings, global or workspace set:
{
"json.schemas": [
{
"fileMatch": ["cypress.json"],
"url": "https://on.cypress.io/cypress.schema.json"
}
]
}
VSCode alternative: add "$schema" property to your JSON file
{
"viewportWidth": 600,
"viewportHeight": 800,
"ignoreTestFiles": "answer.js",
"baseUrl": "http://localhost:3000",
"$schema": "https://on.cypress.io/cypress.schema.json"
}
Boston TypeScript Meetup
February 2019
By Gleb Bahmutov
In this presentation, I will show how to get type checks without going all the way to TypeScript. We will look at how you can write JSDoc comments to describe types. I will also show how we provide external TypeScript definitions in Cypress end-to-end tests where the tests themselves are written in JavaScript.
JavaScript ninja, image processing expert, software quality fanatic