typed-ember / ember-cli-typescript Goto Github PK
View Code? Open in Web Editor NEWUse TypeScript in your Ember.js apps!
Home Page: https://docs.ember-cli-typescript.com
License: MIT License
Use TypeScript in your Ember.js apps!
Home Page: https://docs.ember-cli-typescript.com
License: MIT License
First off, thank you very much for all your hard work here. Really excited to see this reaching the 1.0.0 line. 🎉
I believe Ember is going to switch to use the JavaScript Modules API (that is Ember packages will be modules instead off a global namespace + destructuring). I believe the shim support (with ember-cli-babel 6.6.0 and above) for this is already being landed in Ember 2.16 (API docs are being changed to point to the new usage, Ember CLI blueprints are already being updated etc). There is also a JSON map today for making it easier to map: https://github.com/ember-cli/ember-rfc176-data
With this, I believe the type definitions for Ember need to be redefined (with multiple namespaces), otherwise it will break apps wanting to use this addon. Is there a plan to have some parity release with 1.0.0 (example 1.0.0 is only supported for apps using below Ember CLI 2.15)? Or will 1.0.0 support the new modules API as well?
Hello,
I'm running into an issue using Ember 2.6.2
where after installing this addon, and running ember s
, I am getting a continuous (successful) build:
Serving on http://localhost:4200/
2017-01-19 21:23 ember[31915] (FSEvents.framework) FSEventStreamFlushSync(): failed assertion '(SInt64)last_id > 0LL'
2017-01-19 21:23 ember[31915] (FSEvents.framework) FSEventStreamFlushSync(): failed assertion '(SInt64)last_id > 0LL'
2017-01-19 21:23 ember[31915] (FSEvents.framework) FSEventStreamFlushSync(): failed assertion '(SInt64)last_id > 0LL'
file added tmp/source_map_concat-input_base_path-vyxp9aC0.tmp/0
file added tmp/source_map_concat-output_path-IUJJF0ep.tmp/assets
file added tmp/source_map_concat-output_path-IUJJF0ep.tmp
2017-01-19 21:23 ember[31915] (FSEvents.framework) FSEventStreamFlushSync(): failed assertion '(SInt64)last_id > 0LL'
file added tmp/broccoli_persistent_filterbabel-input_base_path-UzQ5dziG.tmp
2017-01-19 21:23 ember[31915] (FSEvents.framework) FSEventStreamFlushSync(): failed assertion '(SInt64)last_id > 0LL'
file added tmp/cache_path-RKxvfCzd.tmp
file added tmp/output_path-j0VlpLPZ.tmp
file added tmp/funnel-input_base_path-nfg4kQrv.tmp
file added tmp/funnel-output_path-flgLnjMC.tmp
file added tmp/broccoli_persistent_filterbabel-input_base_path-oEOEPytn.tmp
Build successful - 9624ms.
Slowest Trees | Total
----------------------------------------------+---------------------
broccoli-persistent-filter:Babel | 4700ms
broccoli-typescript-compiler | 922ms
broccoli-typescript-compiler | 567ms
Slowest Trees (cumulative) | Total (avg)
----------------------------------------------+---------------------
broccoli-persistent-filter:Babel (30) | 5868ms (195 ms)
broccoli-typescript-compiler (2) | 1490ms (745 ms)
broccoli-persistent-filter:EslintValid... (3) | 558ms (186 ms)
Build successful - 1164ms.
Slowest Trees | Total
----------------------------------------------+---------------------
broccoli-typescript-compiler | 405ms
broccoli-typescript-compiler | 309ms
Funnel | 58ms
Slowest Trees (cumulative) | Total (avg)
----------------------------------------------+---------------------
broccoli-typescript-compiler (2) | 714ms (357 ms)
Funnel (19) | 79ms (4 ms)
2017-01-19 21:23 ember[31915] (FSEvents.framework) FSEventStreamFlushSync(): failed assertion '(SInt64)last_id > 0LL'
file changed tmp/source_map_concat-input_base_path-vyxp9aC0.tmp/0
file added tmp/output_path-ceVObbAD.tmp
file added tmp/output_path-3NXIUHJB.tmp
file added tmp/output_path-j0VlpLPZ.tmp
file added tmp/output_path-vxD3FWUV.tmp
Build successful - 741ms.
Slowest Trees | Total
----------------------------------------------+---------------------
broccoli-typescript-compiler | 260ms
broccoli-typescript-compiler | 235ms
Slowest Trees (cumulative) | Total (avg)
----------------------------------------------+---------------------
broccoli-typescript-compiler (2) | 495ms (247 ms)
broccoli-persistent-filter:Babel (30) | 40ms (1 ms)
file changed tmp/source_map_concat-input_base_path-vyxp9aC0.tmp/0
file added tmp/output_path-3NXIUHJB.tmp
file added tmp/output_path-j0VlpLPZ.tmp
file added tmp/output_path-vxD3FWUV.tmp
Let me throw this out there- I'm brand new to Typescript, so I left what was generated. They currently look like the following:
ember-cli-build.js
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
babel: {
optional: [ 'es7.decorators' ]
},
'ember-cli-foundation-6-sass': {
'foundationJs': 'all'
// load js partials: http://foundation.zurb.com/sites/docs/accordion.html#sass-variables
}
});
// app.import a bunch of fonts specific to the design of the app
return app.toTree();
};
tsconfig.json
"compilerOptions": {
"target": "ES6",
"allowJs": true,
"moduleResolution": "node",
"noEmitOnError": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"npm:*": ["local-types/*"],
"*": ["local-types/*"]
}
},
"include": [
"app/**/*"
]
}
app/config/environment.d.ts
/**
* Type declarations for
* import config from './config/environment'
*
* For now these need to be managed by the developer
* since different ember addons can materialize new entries.
*/
declare namespace config {
export var environment: any;
}
Thanks for the quick reply. Any help is much appreciated!
The addon unfortunately has problems with [email protected]
. My setup:
$ ember -v
ember-cli: 2.15.1
node: 8.6.0
os: darwin x64
Steps to reproduce:
ember new ember-test-ts
cd ember-test-ts
ember install ember-cli-typescript
ember g route application
// routes/application.js
import Ember from 'ember';
import TestClass from 'ember-test-ts/lib/TestClass';
// ...
// lib/TestClass.ts
export default class TestClass {
private bar;
constructor(foo = {}) {
this.bar = foo.bar;
}
}
and then run ember serve
which leads to this error:
Uncaught Error: Could not find module `ember-test-ts/lib/TestClass` imported from `ember-test-ts/routes/application`
It is independent whether TS version 2.4 resp. 2.5 is used, I tried both.
What's interessting, is when running with BROCCOLI_DEBUG=ember-cli-typescript:* ember serve
the DEBUG/ember-cli-typescript:1
directory is empty.
It looks like ember-cli-typescript
doesn't like computed-decorator
, I have this error on build time :
SyntaxError: controller.js: 'return' outside of function (155:4)
Is there any configuration specific to add ? I already put "experimentalDecorators": true
in my tsconfig.json
.
My code looks like that :
@readOnly
@computed('model.[]')
items (model) {
return A(model.slice());
},
I wanted to check the progress of all the work we've been doing, so I decided to convert an open source ember app to typescript and document the results.
First I tried converting the travis-ci app, but they're doing non-compliant decorator things. I settled on ember-api-docs: a small but non-trivial app that shows up on a google search for "ember app list".
All I've done is install e-c-ts and rename .js
to .ts
. I'm building against my local custom build of ember-typings which has some outstanding PRs merged.
It went surprisingly well! I went through the error log and categorized the errors. We already know about many of these problems and there are some new ones. I'll open new issues for some of them.
app/initializers/scroll-parent-shim.ts(1,8): error TS1192: Module ''jquery'' has no default export.
app/mixins/scroll-tracker.ts(3,8): error TS1192: Module ''jquery'' has no default export.
import $ from 'jquery';
Is this a shim for window.jQuery
? Who exports it?
app/initializers/scroll-parent-shim.ts(5,14): error TS2304: Cannot find name 'FastBoot'.
app/mixins/scroll-tracker.ts(17,19): error TS2304: Cannot find name 'FastBoot'.
if (typeof FastBoot !== 'undefined') {
return
}
Missing typings for fastboot
app/mixins/scroll-tracker.ts(21,20): error TS2339: Property 'APP' does not exist on type 'typeof config'.
ember-api-docs/adapters/application.ts(11,13): error TS2339: Property 'API_HOST' does not exist on type 'typeof config'.
ember-api-docs/router.ts(11,19): error TS2339: Property 'routerRootURL' does not exist on type 'typeof config'.
import config from 'ember-api-docs/config/environment';
$(config.APP.scrollContainerSelector).scrollTop(offset - 10);
It's not possible to define the environment config in typescript. Work around by adding to app/config/environment.d.ts
app/utils/get-last-version.ts(1,27): error TS2307: Cannot find module 'npm:semver-compare'.
ember-api-docs/components/api-index-filter.ts(3,18): error TS2307: Cannot find module 'npm:lodash.uniq'.
ember-api-docs/components/api-index-filter.ts(4,20): error TS2307: Cannot find module 'npm:lodash.sortby'.
import semverCompare from 'npm:semver-compare';
Missing typings for ember-browserify
app/utils/request-idle-callback.ts(1,8): error TS1192: Module '"/users/dwickern/code/ember-api-docs/node_modules/@types/rsvp/index"' has no default export.
ember-api-docs/components/search-input.ts(2,10): error TS2305: Module '"/users/dwickern/code/ember-typings/node_modules/@types/rsvp/index"' has no exported member 'denodeify'.
ember-api-docs/routes/class.ts(1,10): error TS2305: Module '"/users/dwickern/code/ember-typings/node_modules/@types/rsvp/index"' has no exported member 'hash'.
ember-api-docs/routes/class.ts(1,16): error TS2305: Module '"/users/dwickern/code/ember-typings/node_modules/@types/rsvp/index"' has no exported member 'resolve'.
import RSVP from 'rsvp';
import { hash, resolve } from 'rsvp';
The RSVP typings only declare typings for require('rsvp')
. Is this "rsvp" module actually a shim added by ember?
app/utils/request-idle-callback.ts(8,12): error TS2555: Expected at least 3 arguments, but got 2.
import { run } from '@ember/runloop';
return run.scheduleOnce('afterRender', cb);
Incomplete typings for scheduleOnce
ember-api-docs/tests/acceptance/analytics-page-tracking-test.ts(13,33): error TS2339: Property 'application' does not exist on type 'TestContext'.
test('checking that trackPage gets called on transitions', async function(assert) {
const analyticsService = this.application.__container__.lookup('service:analytics');
})
The application
property is added by a custom test helper module-for-acceptance
. You can fix this error with a merged declaration.
// tests/helpers/module-for-acceptance.ts
import Application from '@ember/application';
declare module "qunit" {
interface TestContext {
application: Ember.Application;
}
}
(you'll now have an error on __container__
though because there aren't typings for it, but that's a separate problem)
I think this module-for-acceptance
is a blueprint added to all projects by default? Maybe we should have an updated blueprint to fix this common issue.
ember-api-docs/tests/acceptance/analytics-page-tracking-test.ts(29,29): error TS2345: Argument of type '2000' is not assignable to parameter of type '{ timeout: any; }'.
export function requestIdlePromise({timeout}) {
...
}
return requestIdlePromise(2000);
Typescript caught a bug! 🎉
ember-api-docs/tests/acceptance/app-layout-test.ts(10,9): error TS2304: Cannot find name 'selectSearch'.
ember-api-docs/tests/acceptance/switch-versions-test.ts(14,9): error TS2304: Cannot find name 'selectChoose'.
await selectSearch('.select-container', '2');
Missing typings for ember-power-select
ember-api-docs/tests/helpers/resolver.ts(1,22): error TS2307: Cannot find module '../../resolver'.
ember-api-docs/tests/helpers/start-app.ts(3,25): error TS2307: Cannot find module '../../app'.
ember-api-docs/tests/helpers/start-app.ts(4,20): error TS2307: Cannot find module '../../config/environment'.
import Resolver from '../../resolver';
import config from '../../config/environment';
import Application from '../../app';
At least I'm not the only one confused by this.
ember-api-docs/tests/test-helper.ts(3,27): error TS2307: Cannot find module 'ember-exam/test-support/load'.
import loadEmberExam from 'ember-exam/test-support/load';
loadEmberExam();
Missing typings for ember-exam
ember-api-docs/tests/unit/initializers/scroll-parent-shim-test.ts(21,3): error TS2554: Expected 0 arguments, but got 1.
import { initialize } from 'ember-api-docs/initializers/scroll-parent-shim';
initialize(this.application);
export function initialize() {
}
Good.
ember-api-docs/adapters/application.ts(3,19): error TS2307: Cannot find module 'fetch'.
import fetch from 'fetch';
ember-api-docs/components/ember-anchor.ts(3,29): error TS2307: Cannot find module 'ember-anchor/components/ember-anchor'.
ember-api-docs/controllers/events.ts(3,37): error TS2307: Cannot find module 'ember-anchor/mixins/controller-support'.
import AnchorComponent from 'ember-anchor/components/ember-anchor';
Missing typings for ember-anchor
ember-api-docs/components/search-input.ts(7,17): error TS2307: Cannot find module 'ember-metal/get'.
ember-api-docs/components/search-input.ts(8,17): error TS2307: Cannot find module 'ember-metal/set'.
import get from 'ember-metal/get';
import set from 'ember-metal/set';
Missing typings for ember-metal
. Is this public API?
ember-api-docs/components/search-input/dropdown.ts(28,20): error TS2345: Argument of type '"results.length"' is not assignable to parameter of type 'never'.
ember-api-docs/components/ember-anchor.ts(11,36): error TS2345: Argument of type '"attrs.a"' is not assignable to parameter of type 'never'.
ember-api-docs/components/search-input/dropdown.ts(28,20): error TS2345: Argument of type '"results.length"' is not assignable to parameter of type 'never'.
ember-api-docs/components/search-input/dropdown.ts(55,41): error TS2345: Argument of type '"hierarchy.lvl1"' is not assignable to parameter of type 'never'.
if (!get(this, 'results.length')) {
return {};
}
let filterValue = get(this, `filterData.show${capitalize(filter)}`) ? filter : null;
let lvl0 = capitalize(get(current, 'hierarchy.lvl0'));
Ember typings don't support paths
ember-api-docs/controllers/project-version.ts(53,37): error TS2339: Property 'sort' does not exist on type 'NativeArray<{}>'.
ember-api-docs/mixins/filter-params.ts(22,19): error TS2339: Property 'push' does not exist on type 'NativeArray<{}>'.
ember-api-docs/mixins/filter-params.ts(35,33): error TS2339: Property 'includes' does not exist on type 'NativeArray<{}>'.
let filters = A(value.split(','));
let enabled = filters.includes(filter);
This seems to be a bug in ember typings.
ember-api-docs/models/missing.ts(1,19): error TS2307: Cannot find module 'ember-data/model'.
import Model from 'ember-data/model';
Missing typings for ember-data shims
ember-api-docs/router.ts(22,11): error TS2339: Property 'map' does not exist on type 'Readonly & (new () => { analytics: ComputedProperty; location: string; ro...'.
const AppRouter = Router.extend({
...
});
AppRouter.map(function() {
this.route('404');
...
});
Incomplete typings for Ember.Router
ember-api-docs/services/analytics.ts(21,5): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.
await requestIdlePromise({timeout: 1000});
export function requestIdlePromise({timeout}) {
return new RSVP.Promise(resolve => {
requestIdleCb(resolve, {timeout});
});
}
Incomplete typings for RSVP
See discussion here; we need to update to use [email protected] and ship a point release with the bug fix; this is a blocker for anyone looking to use ember-cli-typescript and [email protected].
The output from running ember install ember-cli-typescript
…
C:\src\try-typescript [master +1 ~1 -0 !]> ember install ember-cli-typescript
Yarn: Installed ember-cli-typescript
installing ember-cli-typescript
Path must be a string. Received undefined
TypeError: Path must be a string. Received undefined
at assertPath (path.js:7:11)
at Object.join (path.js:468:7)
at Class.buildFileInfo (C:\src\try-typescript\node_modules\ember-cli\lib\models\blueprint.js:651:24)
at Array.map (native)
at Class._getFileInfos (C:\src\try-typescript\node_modules\ember-cli\lib\models\blueprint.js:678:18)
at Class.processFiles (C:\src\try-typescript\node_modules\ember-cli\lib\models\blueprint.js:725:26)
at tryCatch (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:539:12)
at invokeCallback (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:554:13)
at publish (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:522:7)
at flush (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:2414:5)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
ember install …
did use yarn
to install, I also confirmed that I can npm install ember-cli-typescript
as well. However the blueprint doesn't run.
C:\src\try-typescript [master +1 ~1 -0 !]> ember g ember-cli-typescript
installing ember-cli-typescript
Path must be a string. Received undefined
TypeError: Path must be a string. Received undefined
at assertPath (path.js:7:11)
at Object.join (path.js:468:7)
at Class.buildFileInfo (C:\src\try-typescript\node_modules\ember-cli\lib\models\blueprint.js:651:24)
at Array.map (native)
at Class._getFileInfos (C:\src\try-typescript\node_modules\ember-cli\lib\models\blueprint.js:678:18)
at Class.processFiles (C:\src\try-typescript\node_modules\ember-cli\lib\models\blueprint.js:725:26)
at tryCatch (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:539:12)
at invokeCallback (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:554:13)
at publish (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:522:7)
at flush (C:\src\try-typescript\node_modules\rsvp\dist\rsvp.js:2414:5)
Version info:
C:\src\try-typescript [master +1 ~1 -0 !]> ember --version
ember-cli: 2.13.0-beta.3
node: 6.10.0
os: win32 x64
Also I noticed that I was able to setup a repo using ember-cli-typescript with an ember app using ember-cli: 2.13.0-beta.3 on a Mac. Then when cloning the repo on Windows I had trouble running the app. There were a bunch of permissions issues. I have a project on an older version of ember-cli so tried that too and had similar build/serve issues…
The Broccoli Plugin: [SourceMapConcat: Concat: Vendor /assets/vendor.js] failed with:
Error: EPERM: operation not permitted, symlink
The Broccoli Plugin: [SourceMapConcat: Concat: Vendor /assets/vendor.js] failed with:
Error: EPERM: operation not permitted, lstat
The Broccoli Plugin: [BroccoliMergeTrees] failed with:
Error: EPERM: operation not permitted, symlink
The Broccoli Plugin: [Funnel: Funnel (lint app)] failed with:
Error: EPERM: operation not permitted, symlink
In order to get module resolution working properly in VS Code—i.e., so that code completion and navigation-to-definition worked—I had to make the following changes to the blueprint. Note the additions to the paths
and include
keys.
{
"compilerOptions": {
"target": "ES6",
"allowJs": true,
"moduleResolution": "node",
"noEmitOnError": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"mobile-web/config/*": ["config/*"],
"mobile-web/tests/*": ["tests/*"],
"mobile-web/*": ["app/*"],
"npm:*": ["local-types/*"],
"*": ["local-types/*"]
}
},
"include": [
"app/**/*",
"tests/**/*"
]
}
If possible, these should either be generated by default, or the README should include them (I'm happy to submit a PR for either change, but wanted to open for discussion). It may also be worth bringing up the specific issue highlighted in the Configuration file section with the TypeScript team, as it seems like it may well affect more than just us.
(I'm concerned from a comment @locks made in Slack that this may end up including the tests
directory during the processing, but that seems like a decision that should be made during the Broccoli filtering, just like it would be in the pure-JS case, right?)
Am fairly new to TS and this plugin. I am trying to migrate a big project to this. However after installing everything when I do ember serve
I am getting the following..
2017-03-05 09:48 ember[10417] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
2017-03-05 09:48 ember[10417] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
2017-03-05 09:48 ember[10417] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
events.js:161
throw er; // Unhandled 'error' event
^
Error: Error watching file for changes: EMFILE
at exports._errnoException (util.js:1028:11)
at FSEvent.FSWatcher._handle.onchange (fs.js:1361:11)
Sorry this could be a very simple question. Just looking to get started 👍
I do get this error fairly often:
$ ember s
Livereload server on http://localhost:49153
The Broccoli Plugin: [broccoli-typescript-compiler] failed with:
TypeError: Cannot read property 'length' of undefined
at createSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:15396:109)
at parseSourceFileWorker (/path/to/my/project/node_modules/typescript/lib/typescript.js:15328:26)
at Object.parseSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:15277:26)
at Object.createSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:15131:29)
at SourceCache.getSourceFile (/path/to/my/project/node_modules/broccoli-typescript-compiler/dist/plugin.js:98:43)
at Object.getSourceFile (/path/to/my/project/node_modules/broccoli-typescript-compiler/dist/plugin.js:300:85)
at findSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:67716:29)
at processSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:67647:27)
at /path/to/my/project/node_modules/typescript/lib/typescript.js:67757:17
at Object.forEach (/path/to/my/project/node_modules/typescript/lib/typescript.js:1443:30)
at processReferencedFiles (/path/to/my/project/node_modules/typescript/lib/typescript.js:67755:16)
at findSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:67740:21)
at processSourceFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:67647:27)
at processRootFile (/path/to/my/project/node_modules/typescript/lib/typescript.js:67535:13)
at Object.createProgram (/path/to/my/project/node_modules/typescript/lib/typescript.js:66845:21)
at Compiler.createProgram (/path/to/my/project/node_modules/broccoli-typescript-compiler/dist/plugin.js:236:22)
The broccoli plugin was instantiated at:
at TypeScript.Plugin (/path/to/my/project/node_modules/broccoli-plugin/index.js:7:31)
at new TypeScript (/path/to/my/project/node_modules/broccoli-typescript-compiler/dist/plugin.js:324:27)
at typescript (/path/to/my/project/node_modules/broccoli-typescript-compiler/index.js:28:10)
at TypeScriptPreprocessor.toTree (/path/to/my/project/node_modules/ember-cli-typescript/lib/typescript-preprocessor.js:96:7)
at /path/to/my/project/node_modules/ember-cli-preprocess-registry/preprocessors.js:180:26
at Array.forEach (native)
at processPlugins (/path/to/my/project/node_modules/ember-cli-preprocess-registry/preprocessors.js:178:11)
at module.exports.preprocessJs (/path/to/my/project/node_modules/ember-cli-preprocess-registry/preprocessors.js:171:10)
at EmberApp.appAndDependencies (/path/to/my/project/node_modules/ember-cli/lib/broccoli/ember-app.js:1110:27)
at EmberApp.javascript (/path/to/my/project/node_modules/ember-cli/lib/broccoli/ember-app.js:1225:30)
at EmberApp.toArray (/path/to/my/project/node_modules/ember-cli/lib/broccoli/ember-app.js:1662:12)
at EmberApp.toTree (/path/to/my/project/node_modules/ember-cli/lib/broccoli/ember-app.js:1684:38)
at module.exports (/path/to/my/project/ember-cli-build.js:29:13)
at Builder.setupBroccoliBuilder (/path/to/my/project/node_modules/ember-cli/lib/models/builder.js:56:19)
at new Builder (/path/to/my/project/node_modules/ember-cli/lib/models/builder.js:30:10)
at ServeTask.run (/path/to/my/project/node_modules/ember-cli/lib/tasks/serve.js:24:55)
I'm trying to use typescript, however this pops up now and then. Here is what I do to solve this:
rm -rf tmp/
rm -rf node_modules/ && yarn install
yarn remove ember-cli-typescript
ember install ember-cli-typescript
If it pops up too often, I cancel on typescript and keep it deinstalled (however, yes, I'm really trying to use it)
RFC: https://github.com/emberjs/rfcs/blob/master/text/0176-javascript-module-api.md
import Component from '@ember/component';
generates an error : [ts] Cannot find module '@ember/component'.
This import is possible thanks to ember-cli/ember-cli-shims#92 available in https://github.com/ember-cli/ember-cli-shims/releases/tag/v1.2.0-beta.2.
How can we make typescript aware of those new modules ?
For some reason, on Windows 10, this addon will not run the development server (ember s
)
ENV:
ember --version
ember-cli: 2.12.1
node: 6.10.0
os: win32 x64
ember-cli-typescript: 0.3.0
Steps to reproduce:
npm install --save-dev typescript
npm install --save-dev @types/ember
npm install --save-dev ember-cli-typescript
ember g util hello-typescript
hello
ember server
Example repo: https://gitlab.com/pixelhandler/try-ember-cli-typescript
Expected result
The app should compile .ts file and run the compiled .js to display a message on a template.
Actual result
There were a bunch of permissions issues. and the app does not run in the browser…
The Broccoli Plugin: [SourceMapConcat: Concat: Vendor /assets/vendor.js] failed with:
Error: EPERM: operation not permitted, symlink
The Broccoli Plugin: [SourceMapConcat: Concat: Vendor /assets/vendor.js] failed with:
Error: EPERM: operation not permitted, lstat
The Broccoli Plugin: [BroccoliMergeTrees] failed with:
Error: EPERM: operation not permitted, symlink
The Broccoli Plugin: [Funnel: Funnel (lint app)] failed with:
Error: EPERM: operation not permitted, symlink
But if you wait some time it eventually works, but the tmp files keep regenerating and build is noisy still.
Ember test with server doesn't work ember t -s
Other notes
As a side note ember test
and ember build
worked. seems to be an issue running the development (express) server.
Hey guys, great work on integrating typescript!
I have a question about how things are going. I have seen presentation at https://www.youtube.com/watch?v=951HiqnNQ1w, and googled this repository as the only existing integration with typescript.
In the presentation, the presenter is showing type checking with get
functions, and even suggesting of what can be used inside get
, however this doesn't seem to be the case for me. Typescript doesn't seem to recognize that get
is a function, and that there is a set of acceptable inputs. Am I doing something wrong in here, or is this level of integration still not achievable?
I have a tsconfig.json
file similar to the following, but
{
"compilerOptions": {
"target": "ES6",
"allowJs": true,
"moduleResolution": "node",
"noEmitOnError": true,
"noEmit": true,
"baseUrl": ".",
"sourceMap": true,
"paths": {
"ember-simple-auth/mixins/application-route-mixin": [
"node_modules/ember-simple-auth/addon/mixins/application-route-mixin"
]
}
},
"include": [
"app/**/*"
]
}
and in routes/application.ts:
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
However, when i run ember serve
, I get the following error in the build process:
/my-app/routes/application.ts(7,35): Cannot find module 'ember-simple-auth/mixins/application-route-mixin'.
/my-app/routes/application.ts(7,35): Cannot find module 'ember-simple-auth/mixins/application-route-mixin'.
How do I get ember-cli-typescript to correctly pick up this file?
ember serve
and restarted after making the editsember addon my-addon
cd my-addon
ember install ember-cli-typescript
ember install ember-browserify
npm install ts-mockito
In my-test.ts
import mockito from 'npm:ts-mockito';
const {mock} = mockito;
In test run:
Died on test #1 at TestLoader.moduleLoadFailure (http://localhost:4200/assets/test-support.js:7866:24)
at TestLoader.<anonymous> (http://localhost:4200/assets/test-support.js:8094:16)
at TestLoader.require (http://localhost:4200/assets/test-support.js:8082:27)
at TestLoader.loadModules (http://localhost:4200/assets/test-support.js:8074:16)
at loadTests (http://localhost:4200/assets/test-support.js:7919:22)
at start (http://localhost:4200/assets/test-support.js:7954:7)
at Module.callback (http://localhost:4200/assets/my-test.js:108:28): Could not find module `ts-mockito` imported from `dummy/tests/unit/utils/my-test`
I get this error when trying to use e-c-ts in a fresh addon. Maybe I'm doing something wrong. Here's what I did:
ember addon my-addon --yarn
ember install ember-cli-typescript
devDependencies
into dependencies
as documented in the READMEyarn link
ed the dependency into my app and tried to run itIt seems that it's trying to load the tsconfig from the root of my app instead of from the addon
Cannot set property 'noEmit' of undefined
TypeError: Cannot set property 'noEmit' of undefined
at TypeScriptPreprocessor.toTree (/Users/dwickern/code/my-addon/node_modules/ember-cli-typescript/lib/typescript-preprocessor.js:68:37)
at /Users/dwickern/code/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:180:26
at Array.forEach (native)
at processPlugins (/Users/dwickern/code/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:178:11)
at Function.module.exports.preprocessJs (/Users/dwickern/code/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:171:10)
at Class.preprocessJs (/Users/dwickern/code/my-app/node_modules/ember-cli/lib/models/addon.js:1085:25)
at Class.processedAddonJsFiles (/Users/dwickern/code/my-app/node_modules/ember-cli/lib/models/addon.js:1099:33)
at Class.compileAddon (/Users/dwickern/code/my-app/node_modules/ember-cli/lib/models/addon.js:1007:24)
at Class.treeForAddon (/Users/dwickern/code/my-app/node_modules/ember-cli/lib/models/addon.js:661:26)
at Class._treeFor (/Users/dwickern/code/my-app/node_modules/ember-cli/lib/models/addon.js:517:33)
Recently I started using ember-typescript
in my existing project.
So I started by migrating few files to typescript
(component1, component2 and util1).
And when I run embe build, I see few build warnings I have not been able to figure out why.
Below is the warnings i see in console.
Cannot write file '/app/file1.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
/app/components/component1.ts(3,18): Cannot find module 'ember-uuid'.
/app/components/component2.ts(2,18): Cannot find module 'ember-uuid'.
/app/utils/util1.ts(4,18): Cannot find module 'ember-uuid'.
/myApp/components/component1.ts(2,23): Cannot find module '../file1'.
/myApp/components/component1.ts(3,18): Cannot find module 'ember-uuid'.
/myApp/components/component2.ts(2,18): Cannot find module 'ember-uuid'.
/myApp/utils/util1.ts(3,23): Cannot find module '../file1'.
/myApp/utils/util1.ts(4,18): Cannot find module 'ember-uuid'.
Everything worked normally when these were js
files. They still work fine and as expected, but these build errors are something I could not understand.
Any help is greatly appreciated.
Note: app/file1.js
is a js
file imported in ts
files. And also ember-uuid
is a node package I'm using and this too is imported in these ts
files.
The title sums up the entire issue.
Adding this addon to a new ember project and doing ember s
will show tmp files being tracked followed by a watcher crash.
If it does manage to compile, the typescript compiler continues to loop trying to compile the temp files (over and over and over and over and over...)
Steps to repeat:
ember new typescript-loop
# wait for that to finish
cd typescript-loop
ember install "ember-cli-typescript@emberwatch/ember-cli-typescript"
# wait again
ember s
The following gist contains an extract from the logs
https://gist.github.com/IceDragon200/3edbb19f54e883d1cf6e123220c2878d
Versions and stuff:
I would also like to point out, installing the addon the first time will fail with "unable to find typescript", forcing you to install typescript in the project first and then trying again to install this.
We tried to upgrade ember-cli-typescript
in our app from 1.0.6
to 1.1.1
, excited to try out incremental compilation. However, we discovered it actually broke the build process for us.
For starters, ember build
also seems to run tsc
in watch mode, because it produces the following message:
14:53:14 - Compilation complete. Watching for file changes.
I assume this is not intended?
Secondly, in most cases, tsc
seems to pick up several file changes right after "Compilation complete", and then the build essentially hangs indefinitely. Example:
14:53:14 - Compilation complete. Watching for file changes.
14:53:19 - File change detected. Starting incremental compilation...
14:53:20 - File change detected. Starting incremental compilation...
14:53:20 - File change detected. Starting incremental compilation...
14:53:21 - File change detected. Starting incremental compilation...
14:53:22 - File change detected. Starting incremental compilation...
14:53:24 - File change detected. Starting incremental compilation...
14:53:24 - File change detected. Starting incremental compilation...
On our CI server (CircleCI), no file changes are picked up and that's probably why the build is actually able to finish successfully there. File changes hang the build on several development machines and on Heroku though.
Any idea how to debug/fix this?
This isn't ready for addons yet:
I'm not an ember-cli expert, but I'd say these are a few things to address:
Hi,
Thanks for an excellent addon - eagerly awaiting the next steps of development here.
I have a usage question: how can I formulate some code like this and get it to properly understand that this.store
is indeed of the DS.Store
type?
class WorkspaceService extends Ember.Object {
session = Ember.inject.service();
store = Ember.inject.service();
someMethod() {
// The line below will generate a compilation error
this.store.findRecord('workspace', 1);
}
I can do like this, which gets incredibly ugly and type-unsafe. But what better way could there be? (unless creating this object outside of Ember and passing in the store
instance as a constructor parameter or similar...)
someMethod() {
let store = <DS.Store><any>this.store;
this.store.findRecord('workspace', 1);
}
Just what it says on the tin. We tried to add a definition file, it failed to compile; we changed the extension to just .ts
instead of .d.ts
and it worked.
Probably just what the tree is configured to snag, I'm guessing. Will take a look down the line.
I was a bit wondering, when the config/
folder for *.d.ts
files popped up under my /app
(soon to be /src
) folder. I would consider *.d.ts
files as metadata to my project and I think the current default location is wrong. My goto folder for these files would be /config/typings
. What do you think?
It would be nice to output .ts
instead of .js
For reference see how coffeescript does this in https://github.com/kimroen/ember-cli-coffeescript/tree/master/blueprints
Let's convert some generators!
The basic strategy you should use is—start by commenting that you're taking a generator on this thread (and look to make sure it hasn't been taken before you start in on one). Then:
ember generate blueprint <blueprint name>
. For example, to create the blueprint for a component
, run ember generate blueprint component
. (This will make sure you get the test generated in the node-tests
directory.)blueprints
directory in the Ember or Ember Data over the blueprint you just generated.For example, here's the process I followed for an Ember Route
. On the command line:
$ git clone https://github.com/typed-ember/ember-cli-typescript.git
$ git clone https://github.com/emberjs/ember.js.git
$ cd ember-cli-typescript
$ git checkout --branch add-route-generator
$ yarn
$ ember generate blueprint route
$ cp -r ../ember.js/blueprints/route/* ./blueprints/route/
$ cd blueprints/route/files/__root__/__path__/
$ mv __name__.js __name__.ts
$ cd ../../../../..
Next, I opened node-tests/blueprints/route-test.js
and added some checks to make sure it generates what I think it will:
'use strict';
const blueprintHelpers = require('ember-cli-blueprint-test-helpers/helpers');
const setupTestHooks = blueprintHelpers.setupTestHooks;
const emberNew = blueprintHelpers.emberNew;
const emberGenerateDestroy = blueprintHelpers.emberGenerateDestroy;
const expect = require('ember-cli-blueprint-test-helpers/chai').expect;
describe('Acceptance: ember generate and destroy route', function() {
setupTestHooks(this);
- it('route foo', function() {
+ it('route just-like-home', function() {
- let args = ['route', 'foo'];
+ let args = ['route', 'just-like-home'];
// pass any additional command line options in the arguments array
return emberNew()
.then(() => emberGenerateDestroy(args, (file) => {
- // expect(file('app/type/foo.js')).to.contain('foo');
+ const generated = file('app/routes/just-like-home.ts');
+ expect(generated).to.contain('class JustLikeHome extends Route');
}));
});
});
I ran the test by doing yarn run nodetest
on the command line, and the route just-like-home
test failed, as expected. So I opened blueprints/route/files/__root__/__path__/__name__.ts
in my editor and changed the contents:
import Route from '@ember/routing/route';
- export default Route.extend({
+ export default class <%= classifiedRouteName %> extends Route.extend({
+ // anything which *must* be merged to prototype here
- });
+ }) {
+ // normal class body definition here
+ }
Then I saved the file, and ran yarn run nodetest
again, and everything passed!
Finally, I committed my changes, pushed them, and created this PR.
Greenkeeper, to keep our dependencies up to date.
Running tsc
directly, compileOnSave
works, but ember serve
command throws an error.
Also the compiler seems to be running 3 times (using default tsconfig.json as recommended by the repo)
Livereload server on http://localhost:49153
Serving on http://localhost:4200/
Unknown compiler option 'compileOnSave'.
Unknown compiler option 'compileOnSave'.
Unknown compiler option 'compileOnSave'.
ember --version
ember-cli: 2.12.1
node: 7.4.0
os: linux x64
and
tsc -v
Version 2.2.2
package.json TS stuff
"@types/ember": "^2.7.37",
"@types/underscore": "^1.8.0",
"ember-cli-typescript": "github:emberwatch/ember-cli-typescript",
"typescript": "^2.2.2"
Add documentation for how to create a small shim in your library so you can use existing typings and ember-browserify together.
Hmm, I'm not quite sure with this issue. I'm just a ember consumer, with no background of ember internals at all. Yet I was about to use typescript in my project, I just started to use it and updated to ember 2.15 which crashed typescript support, see #77 . If I had my code written in typescript, it would me require to downgrade ember-cli back to the last working version. What this points out, is the reliability of ember-cli-typescript is questionable, which I think would be different if typescript was directly supported by ember-cli, which I guess would improve the idea to develop addons in typescript immense.
From what I read about ember and the direction ember is moving (e.g. glimmer) and I'm sure more parts of the whole ecosystem will turn over to typescript as well, this would require typescript support anyway, I was wondering if it might be an idea to think about merging ember-cli-typescript into ember-cli?
Hi,
I'm trying this addon out in perlun/electron-ember-typescript-example#3 but am running into some problems.
I am trying do define my controller like this:
class ApplicationController extends Ember.Controller
...but the problem if I then export it using export default ApplicationController
, it's actually a proper ES2015 class that gets exported. It doesn't cause any errors, but the constructor never runs (presumably because it must be an _init
method instead).
If I then export it as export default Ember.Controller.extend(ApplicationController)
, it doesn't work either.
Has anyone done this successfully, and if so, do you have a valid example? (This should be added to the wiki or README file as well)
"local-types/*"
(add-on, blueprint)? I find no local reference to this and nothing documenting anything like it for TS in general."node-modules/at-types-ember"
? Shouldn't this just be "node-modules/@types/ember"
?First, thank you for this! I converted my first addon last night and can't wait to work it into more of our code base.
I'm wondering about the recommended way(s) to have module resolution work in a parent app/addon when it is consuming an addon written in typescript. For example, addon-b has addon-a as a dependency and tries to import thing from addon-a/utils/foo
. I'm currently adding the following to addon-b's tsconfig. This appears to work fine, but it requires explicit code for every addon consumed. Is there a better way?
Thanks and I'd be happy to submit a PR for a doc update w/ whatever approach is recommended.
paths: {
"addon-a/*": [
"node_modules/addon-a/addon/*"
]
}
I'm on 1.0.0-beta.6
doing some very experimental testing with the ember-module-unification-blueprint
in combination with ember-cli-typescript
. So whenever I rename a file or delete it, then I do get this error:
The Broccoli Plugin: [SimpleConcatConcat] failed with:
Error: ENOENT: no such file or directory, lstat ' <path to tmp folder of file before rename/delete>'
at Object.fs.lstatSync (fs.js:947:11)
at EslintValidationFilter.Filter.isDirectory (/path/to/project/node_modules/broccoli-persistent-filter/index.js:270:23)
at EslintValidationFilter.Filter.getDestFilePath (/path/to/project/node_modules/broccoli-persistent-filter/index.js:275:12)
at EslintValidationFilter.getDestFilePath (/path/to/project/node_modules/broccoli-lint-eslint/lib/index.js:125:55)
at /path/to/project/node_modules/broccoli-persistent-filter/index.js:154:52
at /path/to/project/node_modules/promise-map-series/index.js:11:14
at tryCatch (/path/to/project/node_modules/rsvp/dist/rsvp.js:525:12)
at invokeCallback (/path/to/project/node_modules/rsvp/dist/rsvp.js:538:13)
at /path/to/project/node_modules/rsvp/dist/rsvp.js:606:14
at flush (/path/to/project/node_modules/rsvp/dist/rsvp.js:2415:5)
The broccoli plugin was instantiated at:
at Concat.Plugin (/path/to/project/node_modules/broccoli-plugin/index.js:7:31)
at new Concat (/path/to/project/node_modules/broccoli-concat/concat.js:38:10)
at module.exports (/path/to/project/node_modules/broccoli-concat/index.js:26:10)
at Function.EslintValidationFilter.create (/path/to/project/node_modules/broccoli-lint-eslint/lib/index.js:217:10)
at Class.lintTree (/path/to/project/node_modules/ember-cli-eslint/index.js:44:19)
at addons.reduce (/path/to/project/node_modules/ember-cli/lib/utilities/lint-addons-by-type.js:6:23)
at Array.reduce (native)
at lintAddonsByType (/path/to/project/node_modules/ember-cli/lib/utilities/lint-addons-by-type.js:4:17)
at EmberApp.addonLintTree (/path/to/project/node_modules/ember-cli/lib/broccoli/ember-app.js:719:18)
at EmberApp.lintTestTrees (/path/to/project/node_modules/ember-cli/lib/broccoli/ember-app.js:1345:28)
A couple issues here, some of which I'll see if I can open a PR for:
This is currently looking for ../../lib/<a bunch of things>
; it should switch to ember-cli/lib/<a bunch of things>
instead so it's not depending on install location.
This is looking for ember-cli/lib/utilities/string
; this doesn't appear to be a thing at all (I don't know when it was, but I assume it was at some point). It should look instead for ember-cli-string-utilities
.
Even after making those fixes, I get this error:
$ ember generate component my-foo
installing component
Unknown blueprint: component
There's a link on the readme that's currently that supposed to go to the wiki that's currently broken.
Please see [the wiki](https://github.com/emberwatch/ember-cli-typescript/wiki/tsconfig-how-to) for additional how to tips from other users or to add your own tips. If an use case is frequent enough we can codify in the plugin.
Any way I can help with this? I'd be happy to 😁
On a fresh ember project with ember-cli-typescript installed the generators for typescript are not working. I tested with an older version of ember-cli (2.18) on my system and that worked as expected.
Steps to reproduce:
Let me know if there is any other information needed to reproduce, I'll include the contents of my package.json here.
package.json:
{
"name": "example",
"version": "0.0.0",
"private": true,
"description": "Small description for example goes here",
"license": "MIT",
"author": "",
"directories": {
"doc": "doc",
"test": "tests"
},
"repository": "",
"scripts": {
"build": "ember build",
"lint:js": "eslint ./*.js app config lib server tests",
"start": "ember serve",
"test": "ember test"
},
"devDependencies": {
"@types/ember": "^2.8.9",
"@types/ember-data": "^2.14.8",
"@types/ember-test-helpers": "^0.7.0",
"@types/ember-testing-helpers": "^0.0.3",
"@types/rsvp": "^4.0.1",
"broccoli-asset-rev": "^2.4.5",
"ember-ajax": "^3.0.0",
"ember-cli": "~3.0.0",
"ember-cli-app-version": "^3.0.0",
"ember-cli-babel": "^6.6.0",
"ember-cli-dependency-checker": "^2.0.0",
"ember-cli-eslint": "^4.2.1",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-htmlbars-inline-precompile": "^1.0.0",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-qunit": "^4.1.1",
"ember-cli-shims": "^1.2.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-typescript": "^1.1.2",
"ember-cli-uglify": "^2.0.0",
"ember-data": "~3.0.0",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-resolver": "^4.0.0",
"ember-source": "~3.0.0",
"eslint-plugin-ember": "^5.0.0",
"loader.js": "^4.2.3",
"typescript": "^2.7.1"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
}
}
The goal of this quest issue is to write TypeScript type definitions to cover the top 100 addons listed on Ember Observer as of the time the quest is launched. Our bonus goal is to type any other addons which want to participate, as well!
There are two overarching concerns that drive everything else in this quest:
Good type definitions are worth their weight in gold. Bad type definitions are worse than no type definitions at all. Accordingly, our goal is not just to get some type definitions written, but to write good type definitions that actually give us these benefits, and which don’t mislead us or give us a false sense of security.
We should be good citizens of the Ember.js community. We want to use TypeScript to be helpful; we do not want to be pushy jerks or typed-language fanatics. As part of the Ember.js ecosystem, we’re all in this together, and those of us working on the TypeScript side should never look down on people who prefer JavaScript – there are legitimate tradeoffs either direction. So, as always, let’s be kind!
By doing this, we can make the experience of developing Ember apps better for everyone – not just TypeScript users, but all the people using plain-old JavaScript as well. An increasing number of editors will take advantage of TypeScript type definitions if they’re available to help you in your development experience, even if you’re not using TypeScript at all. And of course, if you are using TypeScript, having these will make all the difference in your experience of using an addon. So let’s do it!
First, a couple notes to both add-on authors and add-on users, then the nitty gritty!
{>> TODO <<}
One other approach you can take, if you're interested in adding types to your addon but don't have the knowledge or bandwidth to do it yourself is to add a Help Wanted issue to your repository and link it here! If your repo isn't in the top-100-addons list, I'll add it anyway in its own section. If you're
{>> TODO <<}
If you take a look at one of the addons on this list and the author hasn’t yet expressed any interest in adding TypeScript or TypeScript definitions to their addon, the very first thing you should do is open an issue and see if they’re open to the possibility of converting their addon to TypeScript or hosting the type definitions in the addon. We strongly recommend you just use this template when opening the issue:
Suggested Title: Interested in TypeScript?
Suggested Body:
Hello! I use your addon and really appreciate it. I’m also participating in this quest issue to add TypeScript support throughout the Ember.js ecosystem. This will benefit to everyone who uses your addon, not just TypeScript users! (See here for an explanation.)
Are you interested in either converting the addon to use TypeScript itself, or in adding type definitions? I’d love to help out, if so! And if not, that’s just fine. Thanks!
To make it easy, you can just copy and paste this directly into the issue of a body:
Hello! I use your addon and really appreciate it. I’m also participating in [this quest issue to add TypeScript support throughout the Ember.js ecosystem](https://github.com/typed-ember/ember-typings/issues/14). This will benefit to *everyone* who uses your addon, not just TypeScript users! (See [here]( improving-developer-experience-for-all-emberjs-users) for an explanation.)
Are you interested in either converting the addon to use TypeScript itself, or in adding type definitions? I’d love to help out, if so! And if not, that’s just fine. Thanks!
Based on their answer, you can then help them convert their addon to use TypeScript, help them add type definitions to the repository, or – and this is very important – just leave them alone if they’re not interested! It’s perfectly fine if addon authors aren’t interested in using TypeScript themselves or if they don’t want to take on the extra maintenance burden of hosting type definitions. Do not badger an addon author about TypeScript! If they aren’t interested, we can fall back to using DefinitelyTyped to host type definitions!
Okay, let's dive in and talk about how to do this!
{>> TODO <<}
As noted above, the most important thing about type definitions is that they are correct. If they're incorrect, they'll actually lead users to write wrong code, and that's a deeply frustrating experience.
Some general tips:
Wherever there is documentation, read it very carefully. It's not always correct or up to date, but it still usually gives you a good starting point. If nothing else, it is often a good guide for what the public API is.
Read the source code for the public API. This is the only way to actually be sure of what the code does. Take a look at the function arguments, and look at what is done with them. Are there optional arguments? Are the arguments "polymorphic," i.e. can you pass in either a string or an array of strings or an object as the nth argument? Does it always return the same thing or not? Etc.
Pick something you can handle! Your type definitions should capture everything about the actual behavior of an addon's classes and functions. Sometimes, this will be easy. Other times (here's looking at you, Ember CLI Mirage!) this will involve a lot of arcane type mechanics. If you're just starting out, that's okay! Pick a simpler addon. If you've got mad TypeScript chops, awesome: pick something harder!
Don't go it alone. Get input along the way. The folks on the ember-cli-typescript team and many of the people hanging out in #topic-typescript on the Ember Community Slack are happy to help review your typings work and help you go from just wrote my first type definition ever! to mentoring other people! And getting feedback along the way will help us achieve our goal
{>> TODO: how to write a good type definition <<}
{>> TODO: .d.ts
files, modules, exports <<}
For more complicated types, you may need to lean on TypeScript's optionals, generics, union and intersection types, overloading, or the combination of several of those.
One of the most common scenarios you'll need to cover is handling optional arguments or properties
{>> TODO <<}
There are two ways you'll commonly need to write out optional properties. One is when some items on a type are required and others are optional. In that case, you can write the type with each argument specified explicitly as being optional or not:
type ATypicalWesternName = {
first: string;
middle?: string;
last: string;
}
The other case is where every property on an object is optional. (This tends to come up when you're passing in a configuration/options hash to a function.) In that case, you can use the build-in Partial<T>
type, which makes every property optional:
type Options = {
doSomething: boolean;
withSomeValue: number;
};
export declare function takesOptions(options: Partial<Options>);
If any of the arguments are required, don't use Partial
, spell it out explicitly. Alternatively, build an intersection type from the combination of required properties and optional properties.
type WesternRequiredName = {
first: string;
last: string;
}
type WesternOptionalName = {
middle?: string;
}
type WesternName = WesternRequiredName & WesternOptionalName;
(This is something of a last resort, but it's there when you need it!)
Union types (described here) let you describe the either-or scenario. If a function can take either a number or a string or a boolean as an argument, you can write it like this:
declare function takesAUnion(firstArg: number | string | boolean);
Likewise, if a function returns more than one kind of things, you can write it like this:
declare function returnsAUnion(): number | string | boolean;
This is most useful for times when there is no distinct mapping between the input and output type. For example, the helpers in the ember-native-dom-helpers
helpers (now living at @ember/test-helpers
) all take either a string
or an HTMLElement
as their argument, but they always return the same kind of thing. The function signature for click
, for example, is:
export function click(selector: string | Element): Promise<void>;
However, in some circumstances, a function might take more than one input type and have different output types – but each kind of input would always have the same kind of output. For that, we'll use overloading.
With overloading, we can tell TypeScript that a single function or method has different "signatures." For example, you may recall that {>> TODO: example <<}
The basic structure of the type definition should mirror the structure of the addon or library you're documenting. However, the layout of Ember addons imposes specific requirements that are somewhat unique. In general in TypeScript, it is a good idea to lay out more complicated definitions side-by-side with the modules they document:
src/
index.js
index.d.ts
some-other-module.js
some-other-module.d.ts
However, in the current file system layout for Ember addons, the source location and the "lookup location" where you import the files from are not the same. That is, you don't import Foo from 'an-addon/addon/services/foo';
, you import Foo from 'an-addon/services/foo';
. This essentially constrains us to writing all of our type definitions in a single file. (The Module Unification file layout will help with this, but it will be some time before most addons are using it.)
Aside: The Ember types, as they stand today, are not a good example for how to document most libraries: we have documented Ember as it exists, where you can import things both in the new modules API and via the old global. As Ember itself moves to using the module structure under the hood and those packages are actually installed on the file system, type definitions should move to mirror them.
For a simple addon you can just put the type definitions in the root at index.d.ts
, like this:
the-addon/
addon/
index.js
app/
index.d.ts
index.js
package.json
A prime example of this kind of setup is ember-test-friendly-error-handler.
{>> TODO: example addon for multiple modules in index.d.ts
– ember-qunit maybe? <<}
{>> TODO: structure – modules etc. <<}
[Reminder: only do this after you've checked with the author(s) of the addon that they're interested!]
Once you have a version of the types working solidly in your own application(s), you can open a pull request to the addon with those types. The pull request should include:
index.d.ts
file in the root of the repository"types"
key in package.json
pointing to the file – for the sake of forwards-compatibility, so that if the type definitions are expanded-and-moved at a later time, things don't surprisingly breakIt should also have a good writeup, describing any open questions, pain points, limitations, etc. – that will help the addon maintainer and the reviewers help you wrap everything up with a bow!
Your best bet is to solicit feedback from both the addon maintainer and from knowledgeable folks in #topic-typescript on the Ember Community Slack. The Typed Ember team, currently consisting of @dfreeman, @dwickern, @jamescdavis, and @chriskrycho, are happy to help review these requests, and over time others will be experienced enough to chip in as well!
If you get feedback that things need tweaking, don't worry! Type definitions are hard to get just right, and the definitions for Ember have been through a ton of revisions and we're constantly finding issues with and helping each other with those, too!
You should also make sure the type definition is not excluded by .npmignore
file and if the package.json
is manually specifying files via the "files"
key, that index.d.ts
is in the list. (This is unusual for Ember addons.) See the documentation for the files
key for details.
{>> TODO <<}
DefinitelyTyped is an officially supported, Microsoft-owned GitHub repository which publishes to the @types
npm namespace. Type definitions are automatically published from each folder in the types
directory in the repository.
The process when using DefinitelyTyped is mostly the same as when adding them directly to an addon. When opening a PR for a set of types on DefinitelyTyped, as when doing it directly to an addon, you should get reviews from other folks who are comfortable with both TypeScript and the addon. The Typed Ember team, currently consisting of @dfreeman, @dwickern, @jamescdavis, and @chriskrycho, are happy to help review these requests, and over time others will be experienced enough to chip in as well!
Once it's in place, if the addon author is up for it, you can then open a PR to add a note to their README indicating that types are available at @types/<the-addon-name>
. You should also open a PR to this repository to update the known-typings.md file.
I’ve broken this down into two categories: Top 100 Addons on Ember Observer and Other addons. Both of these are important, albeit for different reasons.
The top 100 addons on Ember Observer represent the most-installed addons in the community; their importance is probably obvious—getting typings in place for them immediately impacts the most people. Other addons or packages are those which may be downloaded less, but whose authors actively want to participate in the quest! We want to support both of these.
The top 100 add-ons in the ecosystem, by way of Ember Observer! Some of these may not need typings added; we’ll remove them as we evaluate that. There is also quite a range of variation in the complexity of these.
@types/lodash
!Ember
global; the type definition already exists there.If your addon isn't in the top 100 on Ember Observer but you volunteer it, we'll list it here!
I'm not sure why this is, but I see it consistently: rebuilds at a minimum dump every error in the TS files every single time – I believe they may actually be reprocessing the whole TS tree every time, rather than just the affected file. This, plus dumping every error to the console, makes rebuilds slow.
Seems that modules defined in .ts
files don't get exported.
I have a reproduction example on this PR: cibernox/ember-native-dom-helpers#16
The only changes in that PR, aside from installing the addon, is that I renamed /test-support/helpers.js
-> /test-support/helpers.ts
.
I see two unexpected things.
First of all, I see some disturbing error messages in the console that sound like errors but perhaps they are warnings because they don't cause the build to fail:
The tests seems unable to resolve ember-native-dom-helpers/test-support/helpers
. Inspecting /assets/test-support.js
, there is no traces of define('ember-native-dom-helpers/test-support/helpers')
, but the modules defined in .js
files are there.
The simples way to reproduce is clone the repo linked above, checkout the migrate-to-typescript
branch and run ember s
I'm excited every time a commit gets merged into this addon, and can't wait until we can use TypeScript in Ember user-land code to a higher degree!
One thing that may be helpful is some clarity around what can and can't be done, relative to the advised TypeScript best practices. Here's a start
class
syntaxexport default MyComponent extends Ember.Component {
}
actions: {
turnWheel(degrees: number) {
...
}
}
// TypeScript compiler won't detect this type mismatch
this.send('turnWheel', 'ALSO-NOT-A-NUMBER');
Ember.Object.extend({
urls: <string[]> null,
port: 4200,
init() {
this._super(...arguments);
this.set('urls', []);
},
foo() {
// TypeScript won't detect these type mismatches
this.get('urls').addObject(51);
this.set('port', 3000);
}
});
I tried using typescript on top of ember-electron
, yet after installing and running ember electron
I got the following error:
$ ember electron
⠧ Building2017-04-30 01:28 ember[2206] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
2017-04-30 01:28 ember[2206] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
2017-04-30 01:28 ember[2206] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
2017-04-30 01:28 ember[2206] (FSEvents.framework) FSEventStreamStart: register_with_server: ERROR: f2d_register_rpc() => (null) (-22)
events.js:163
throw er; // Unhandled 'error' event
^
Error: Error watching file for changes: EMFILE
at exports._errnoException (util.js:1050:11)
at FSEvent.FSWatcher._handle.onchange (fs.js:1376:11)
That said ember serve
runs normal.
Cross-Ref: adopted-ember-addons/ember-electron#246
When using ember-cli addons, even you've installed type definition file, typescript still cannot find the module.
For example, when using ember-cli-htmlbar-inline-precompile
modules. Even you declare a module htmlbar-inline-precomple
in your type definition file, since node_modules/htmlbar-inline-precompile
does not exist, typescript cannot resolve it correctly.
Here's a working sample: https://github.com/inkless/ember-test-app
Type definition is here:
https://github.com/inkless/ember-test-app/blob/master/app/types/ember-shim.d.ts
Test code is here: https://github.com/inkless/ember-test-app/blob/master/tests/integration/components/apple-pie/component-test.ts
Hi,
I want to use ember-cli-typescript with ember-browserify. With a JS file, I can import a module like this:
import {
reduce
} from 'npm:ramda';
But, when I transformed this .js file in .ts, I have this error:
Cannot find module 'npm:ramda'
Is there a solution?
Frédéric
[ts]
The 'this' context of type 'this' is not assignable to method's 'this' of type 'ComputedProperties<{ onStateChanged: StateChangeCallback<SlideCueManagerState>; onCued: SlideCueM...'.
A summary of my code...
import EmberObject from '@ember/object';
import { task, timeout } from 'ember-concurrency';
class MyThing extends EmberObject {
constructor() {
super();
// stuff
}
private DoLater() {
this.get("doLaterTask").perform();
**// ====> FAILS TO COMPILE HERE WITH ABOVE ERROR**
}
private doLaterTask = task(function * () {
yield timeout(500);
// do stuff
}).drop();
}
export { ISlideCueManager, SlideCueManager, SlideCueManagerState };
When using ember-cli addons, even you've installed type definition file, typescript still cannot find the module.
For example, when using ember-cli-htmlbar-inline-precompile
modules. Even you declare a module htmlbar-inline-precomple
in your type definition file, since node_modules/htmlbar-inline-precompile
does not exist, typescript cannot resolve it correctly.
Here's a working sample: https://github.com/inkless/ember-test-app
Type definition is here:
https://github.com/inkless/ember-test-app/blob/master/app/types/ember-shim.d.ts
Test code is here: https://github.com/inkless/ember-test-app/blob/master/tests/integration/components/apple-pie/component-test.ts
Typescript still produce error:
WARNING: ember-test-app/tests/integration/components/apple-pie/component-test.ts(2,17): error TS2307: Cannot find module 'htmlbars-inline-precompile'.
We need to make it possible for add-ons to use TypeScript without requiring consumers of add-ons to also install the 22MB dependency – esp. if add-ons are using multiple versions of TS, that will get out of hand quickly.
Because that should minimize the pain for anyone whenever we make (even small) breaking changes to things in @types
.
We should generate a .d.ts
with prototype extensions.
Prototype extensions are controlled by EXTEND_PROTOTYPES
:
https://guides.emberjs.com/v2.3.0/configuring-ember/disabling-prototype-extensions/
We can't conditionally enable types based on this so the best we can do is generate a .d.ts
which the user can edit.
Array prototype extensions should be enabled by default for apps and disabled for addons. Function prototype extensions should be disabled by default probably. We haven't implemented string prototype extensions.
declare global {
interface Array<T> extends Ember.ArrayPrototypeExtensions<T> {}
interface Function extends Ember.FunctionPrototypeExtensions {}
}
When using Mixins in the extend method of a component I get the following errors
error TS2554: Expected 0-1 arguments, but got 2.
./app/mixins/foo.ts
import Ember from 'ember';
const { Mixin, computed } = Ember;
export default Mixin.create({
foo: 'foo'
});
./app/components/bar.ts
import Ember from 'ember';
import FooMixin from '../mixins/foo';
const { Component } = Ember;
export default Component.extend(FooMixin, {
bar: 'bar'
});
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.