-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
convert to typescript #18
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would really help to split this up into separate commits, rather than having a load of changes bundled into one
tsconfig.json
Outdated
"declaration": true | ||
}, | ||
"include": [ | ||
"lib/**/*.d.ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation here
package.json
Outdated
@@ -3,6 +3,7 @@ | |||
"version": "2.7.0", | |||
"description": "Collection of Resin.io JavaScript errors", | |||
"main": "build/errors.js", | |||
"types": "build/errors.d.ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for not pointing this at the typescript file instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As of now we're not publishing the lib directory altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really? Is there a good reason for that? I think our standard approach everywhere else is to publish the lib with the TS, point types
at that directly, and skip generating type definitions. I don't know of any downsides, and it's definitely simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least our styleguide mentions the .d.ts file. Will update to include the TS sources and point at them.
package.json
Outdated
"build": "rimraf ./build && npm run prettify:src && tsc && npm run prettify:dist", | ||
"prepublish": "npm run build && npm run readme && npm run test", | ||
"prettify:src": "prettier --use-tabs --single-quote --write lib/*.ts", | ||
"prettify:dist": "prettier --use-tabs --single-quote --write build/*.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you run prettifier on the generated code? It'd be better imo to leave it as is (rather than risk messing up the sourcemaps)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point about the sourcemaps, will remove
package.json
Outdated
"resin-config-karma": "^1.0.1", | ||
"rimraf": "^2.6.1", | ||
"tslint": "^5.5.0", | ||
"typescript": "2.4.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you target a fixed version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explained in a diff PR
package.json
Outdated
"prepublish": "gulp build", | ||
"test:node": "mocha --reporter min tests/**/*.spec.js", | ||
"test:browser": "karma start", | ||
"test": "tslint lib/**/*.ts && npm run build && npm run test:node && npm run test:browser", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't tslint
use tsconfig
to see what to target?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, will check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, complaints about the missing files without it
appveyor.yml
Outdated
@@ -11,14 +11,14 @@ cache: | |||
# what combinations to test | |||
environment: | |||
matrix: | |||
- nodejs_version: '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Targets the most recent version (8 as of now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this equivalent to stable
, which also resolves to 8 right now? Slightly clearer that way if so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM apart from page's comments
appveyor.yml
Outdated
@@ -11,14 +11,14 @@ cache: | |||
# what combinations to test | |||
environment: | |||
matrix: | |||
- nodejs_version: '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this equivalent to stable
, which also resolves to 8 right now? Slightly clearer that way if so.
public exitCode: number; | ||
} | ||
ResinError.prototype.code = 'ResinError'; | ||
ResinError.prototype.exitCode = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we don't do this (here and in all the cases below) inline in the class definition?
public code = 'ResinError'
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It used to be on the prototype, this would make it the instance prop. I don't mind, but decided to keep it unchanged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not realise that, but you're totally right: microsoft/TypeScript#1250
Fair enough, in that case this is fine by me 👍
package.json
Outdated
@@ -3,6 +3,7 @@ | |||
"version": "2.7.0", | |||
"description": "Collection of Resin.io JavaScript errors", | |||
"main": "build/errors.js", | |||
"types": "build/errors.d.ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really? Is there a good reason for that? I think our standard approach everywhere else is to publish the lib with the TS, point types
at that directly, and skip generating type definitions. I don't know of any downsides, and it's definitely simpler.
karma.conf.js
Outdated
const packageJSON = require('./package.json') | ||
|
||
module.exports = (config) => { | ||
const karmaConfig = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will later refactor this into a version2 of the resin-config-karma module, for now it's just faster to experiment here.
FYI now we have the tests here running in headless Chrome locally, in Travis, and in AppVeyor, with webpack and babel used for tests packaging. |
Also @Page- should we start using VB for this repo? |
@emirotin I don't see why not, but I've never touched this repo before so probably not the best to decide |
OK
…On Tue, Jul 25, 2017 at 3:15 AM, Page- ***@***.***> wrote:
@emirotin <https://github.com/emirotin> I don't see why not, but I've
never touched this repo before so probably not the best to decide
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#18 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAgGCFbv2sgu_gnhvsTZHdcKDMhQC18kks5sRTOhgaJpZM4Odadj>
.
--
Eugene Mirotin
Senior Frontend Engineer
site: Resin.io <https://resin.io/>, twitter: @resin_io
<https://twitter.com/resin_io>
|
lib/errors.ts
Outdated
* @example | ||
* checkId = (id) -> | ||
* if typeof id isnt 'number' | ||
* throw new errors.ResinInvalidParameterError('id', id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example probably shouldn't be coffeescript any more either
package.json
Outdated
"lint": "tslint lib/**/*.ts", | ||
"test": "npm run lint && npm run build && npm run test:node && npm run test:browser", | ||
"build": "rimraf ./build && npm run prettify && tsc && npm run readme", | ||
"prepublish": "npm run build && npm run test", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test
already runs build
, so you don't need both here
tsconfig.json
Outdated
"noUnusedParameters": true, | ||
"preserveConstEnums": true, | ||
"pretty": true, | ||
"sourceMap": true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the guidelines don't include it as standard (though I've just filed a PR), but we should really include "strictNullChecks": true
here too.
tests/errors.spec.js
Outdated
@@ -0,0 +1,34 @@ | |||
var m = require('mochainon') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file not TS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests should actually be in JS as TS won't let you go some wrong paths. But this one can be TS indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok, interesting point, that adds some useful context to the other discussion, thanks!
You should be able to get round that, nice and explicitly, with some good use of <any>
, and I think probably most tests should be doing things that are technically valid at a type level, because that's where most interesting testing happens. I agree there's other interesting cases though, and you're right that it's a little fiddly, but I think ignoring it until we hit problems and going for TS by default is nicer, imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to enable both TS and JS tests in the karma config and convert this one to TS then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me
Hey @pimterry can you help me here please? I'm trying to convert the tests to TS and having
These are two different errors.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a bunch of notes on why the TypeScript wasn't working, just for background info, and then also pushed a fix too since I wrote it out anyway sorting this.
tests/mochainon.d.ts
Outdated
} | ||
|
||
declare const mochainon: Mochainon; | ||
export default mochainon; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok: this isn't a type definition, it's an actual module, which is why it's not successfully defining 'mochainon' for your test file. If you have an import or an export at the top-level, you're a module, and modules aren't allowed to do declare
statements at all (I'm not sure why it isn't in the compiler output with the other errors, but for me in VSC I get an error on the declare at the top here).
You don't want this. You want a module declaration: to do that, add a body to your declare module 'mochainon'
statement, that defines the contents of that module. That's pretty close to what you've got here (but with braces around the whole lot).
There's on other bug here: you've used export default
, but it's not actually a default export (require('mochainon').default
doesn't exist) - it should be export = mochainon
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've actually tried this approach first and got the VSC error
tests/errors.spec.ts
Outdated
@@ -0,0 +1,43 @@ | |||
/// <reference path="mochainon.d.ts" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally you never ever want to use ///<reference...
.
It's a leftover from before TypeScript had a proper module system. You either want to have an actual dependency TypeScript can understand and follow to get the type (e.g. a normal import
), or you want to include the type definition in your tsconfig.json
. Here the problem is just that your tsconfig.json only matches lib/**/*.d.ts
, and it also needs test/**/*d.ts
(or you could have a single top-level typings
folder).
It's a little weird that this is lib
and test
together - in principle you could have test and prod tsconfigs, but I don't think it's worth it personally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again this is a leftover of my desperation to fix it. I wanted to keep this scoped to the tests only indeed, and it's impossible to import the typings otherwise if the module is already imported. But I'm fine with the current solution.
tests/errors.spec.ts
Outdated
const runForAllErrors = (fn: (errorName: string, ErrorClass: ResinErrorClass) => void) => { | ||
for (const errorName in errors) { | ||
if (errors.hasOwnProperty(errorName)) { | ||
fn(errorName, errors[errorName] as ResinErrorClass); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is upset because errorName
is just a string, and errors
doesn't have an index signature, so it has no idea what the result of searching it for a string is (what's the type of errors[unknownString]
?)
The missing info it needs is that errorName
is a key of errors
- annoyingly for/in isn't enough to know that in general: microsoft/TypeScript#12314.
We are pretty sure of that ourselves though, so we can just cast it: errors[errorName as keyof typeof errors]
.
That works, but leaves you with two casts (this new key cast, and then the ResinErrorClass
cast as well). That's a little messy, but it's not actually safe to remove as ResinErrorClass
, because that isn't actually true. Part of the type of ResinErrorClass is that it has a constructor which takes an error as the first argument. Lots of these error classes don't have that, so don't match the type. Type hierarchies of class objects (as opposed to instances) are weird. What you want to say it that it's an object with the same prototype, not that it's literally a same-shaped class (because it's not).
tests/mochainon.d.ts
Outdated
|
||
import * as chai from 'chai'; | ||
import * as sinon from 'sinon'; | ||
import * as chaiImport from 'chai'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chaiImport is unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's weird, sorry, not sure how that ended up there. Or why that works...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the references, chai has a top-level declare const chai: ...
, which I think actually declares that as a global type, so maybe you don't even need this. Presumably that's because it gets injected globally in a lot of normal chai usage? Feels weird though, I think we should keep importing it explicitly.
Hm. Some sub-dependency adds |
This is super weird. UPD1: running the seemingly equivalent UPD2: seems to be stochastic now, not always reproducible. Super weird. |
So here's the current state of the testing problems:
|
I can't seem to reproduce this at all, running this locally - for me it passes 100% of the time. Are you seeing this locally, or in CI somewhere?
If you change the browser runner to That's the ES2015 plugin, which says that to use iterators you have to include a polyfill. We'll either want to pull in a polyfill during testing (fine by me), or find some other plugin setup with better backward compatibility.
No idea why that compilation error is only happening in AppVeyor, but it looks like it's just looking for the es3 preset for some reason, which should be very solvable. Have you tried just including |
Thanks for looking into this. I can repro the typings error locally like every 3rd or 4th time, but I think I can ignore it for now. Symbol from the for-of makes sense, going to add the polyfill for now and check other options later. No, I didn't try adding ES3 config as it may mask a more serious problem, specifically builds working differently on Windows. I'll look into it deeper before resorting to that fix. |
1 - still there but probably doesn't fail the build 2 - solved with the polyfill 3 - it's because of the posix-specific forward slash in the exclusion regexp for babel-loader. Fixing now |
All tests passing! @pimterry can you approve now? |
tests/errors.spec.js
Outdated
@@ -0,0 +1,38 @@ | |||
const m = require('mochainon') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file can go now, since we've got the TS tests working.
package.json
Outdated
"prepublish": "gulp build", | ||
"test:node:js": "mocha --reporter spec tests/**/*.spec.js", | ||
"test:node:ts": "mocha -r ts-node/register --reporter spec tests/**/*.spec.ts", | ||
"test:node": "npm run test:node:js && npm run test:node:ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we've got the TS tests working happily, we can simplify this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍 👍
Change-Type: minor
To ensure backward compatibility I've created an SDK branch with this branch of errors. SDK tests make lots of assertions for the resin-errors error messages, all seem to be passing fine. So, going to merge now. |
Published as 2.8.0 |
Change-Type: minor
This should actually be good enough for a PR but I'm going to move the relevant parts to resin-karma-config and typed-error repos