YahooArchive / swiv

For the open source UI formerly know as Pivot

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Typescript does not compile

monitorjbl opened this issue · comments

I don't do a lot with Node and I've never tried to use Typescript before, so it's entirely possible that I'm just doing something wrong. However, I've tried just about everything I can think of and this project simply will not build.

This is what I do to attempt a build:

npm install -g gulp
npm install
gulp

I then get

[00:43:58] Using gulpfile ~/Projects/swiv/gulpfile.js
[00:43:58] Starting 'all'...
[00:43:58] Starting 'clean'...
[00:43:59] Finished 'clean' after 145 ms
[00:43:59] Starting 'style'...
[00:43:59] Starting 'icons'...
[00:44:00] Finished 'icons' after 1.05 s
[00:44:01] Finished 'style' after 2.31 s
[00:44:01] Starting 'server:tsc'...
[00:44:01] Starting 'client:tsc'...
node_modules/@types/express-serve-static-core/index.d.ts(242,37): error TS1110 Type expected.
node_modules/@types/express-serve-static-core/index.d.ts(243,39): error TS1110 Type expected.

There are dozens more Typescript errors similar to that in the log. Based on the research I've done, the *.d.ts files are apparently being treated as normal Typescript files in the compilation process. The type definition files are not in Typescript syntax and so they understandably throw these compilation errors.

I've done a bit with Gulp, so I tried to see if I could fix it. However, the build is using Imply's laborer package to compile the typescript, which is completely undocumented. Seriously, even by OSS standards that project is egregious.

Anyway, the last build in Travis appears to have worked, so I tried building this in an Ubuntu Docker container with matching major versions of the node/npm:

root@dfd7a351076f:/swiv# node --version
v6.11.1
root@dfd7a351076f:/swiv# npm --version
3.10.10
root@dfd7a351076f:/swiv# gulp --version
[05:01:11] CLI version 3.9.1
[05:01:11] Local version 3.9.1

Same problem with the latest commit (e4085f4) and latest tag (v0.9.42):

root@dfd7a351076f:/swiv# ./travis-test 
[05:01:52] Using gulpfile /swiv/gulpfile.js
[05:01:52] Starting 'all'...
[05:01:52] Starting 'clean'...
[05:01:52] Finished 'clean' after 121 ms
[05:01:52] Starting 'style'...
[05:01:53] Starting 'icons'...
[05:01:54] Finished 'icons' after 1.49 s
[05:01:55] Finished 'style' after 2.76 s
[05:01:55] Starting 'server:tsc'...
[05:01:55] Starting 'client:tsc'...
/swiv/node_modules/@types/express-serve-static-core/index.d.ts(242,37): error TS1110 Type expected.
/swiv/node_modules/@types/express-serve-static-core/index.d.ts(243,39): error TS1110 Type expected.

Is this happening for others? I don't see any other way that I could build this project, but given the complete lack of documentation for laborer perhaps I'm missing something.

It took a couple of days of learning more about Typescript and Node, but I found a solution. I'm still not sure why this builds in Travis, but I think you'll want this fix. The root cause of all of the errors was a single file (node_modules/@types/express-serve-static-core/index.d.ts). The errors are all around using values as return "types" on function declarations. Here's an example of one of the failed functions:

acceptsEncodings(encoding: string): string | false;

This was, at least as far as I could tell, valid Typescript. However, the Typescript version laborer uses (2.0.0) appears to not support this language feature. You can see this yourself:

mkdir test-bug-14
cd test-bug-14
npm install -g typescript@2.0.0
echo '
interface TestIface {
    acceptsEncodings(encoding: string): string | false;
}

class TestClass implements TestIface{
    acceptsEncodings(encoding: string): string | false{
        if(encoding == "test"){
            return "test"
        } else {
            return false
        }
    }
}

console.log(new TestClass().acceptsEncodings("test"));
console.log(new TestClass().acceptsEncodings("prod"));
' > main.ts
tsc main.ts

This fails with the following output:

main.ts(3,50): error TS1110: Type expected.
main.ts(7,50): error TS1110: Type expected.
main.ts(7,55): error TS1005: ';' expected.
main.ts(14,1): error TS1128: Declaration or statement expected.

Replace the typescript version with 2.0.8 and it works. Apparently, the 2.0.0 release of Typescript had a serious bug because this definitely worked in older releases. In any other language, this would have been catastrophic, but I guess Typescript is just too new for people to care much. Fortunately, fixing this was fairly trivial: update the laborer version of typescript to 2.0.8.

Sadly, NPM makes this awkward because there is no way to exclude transitive dependencies. Short of getting Imply to update the laborer package, the only real way to fix the original dependency is to create a new one. However, it does support file-based "versions" so you can include modules in your codebase.

To fix this bug, I've added laborer to the lib directory and updated the dependencies. This also exposed a few Typescript syntax problems that the older version of laborer was not picking up.