Produce .d.ts files from our typescript compilation.

Deliver them into our npm module output so users can consume them directly.

Fixes #3082
This commit is contained in:
Alex Eagle 2015-10-01 19:49:45 -07:00 committed by Alex Eagle
parent 393b0526b4
commit 95f984615b
30 changed files with 131 additions and 82 deletions

View File

@ -50,7 +50,7 @@ module.exports = new Package('angular-v2-docs', [jsdocPackage, nunjucksPackage,
createTypeDefinitionFile.typeDefinitions = [
{
id: 'angular2/angular2',
references: ['../es6-shim/es6-shim.d.ts'],
references: [],
modules: {
'angular2/angular2': {namespace: 'ng', id: 'angular2/angular2'},
'angular2/web_worker/worker': {namespace: 'ngWorker', id: 'angular2/web_worker/worker'},
@ -71,7 +71,7 @@ module.exports = new Package('angular-v2-docs', [jsdocPackage, nunjucksPackage,
},
{
id: 'angular2/test_lib',
references: ['./angular2.d.ts', '../jasmine/jasmine.d.ts'],
references: ['./angular2.d.ts'],
remapTypes: { Type: 'ng.Type', Binding: 'ng.Binding', ViewMetadata: 'ng.ViewMetadata', Injector: 'ng.Injector',
Predicate: 'ng.Predicate', ElementRef: 'ng.ElementRef', DebugElement: 'ng.DebugElement',
InjectableReference: 'ng.InjectableReference', ComponentRef: 'ng.ComponentRef' },

View File

@ -446,7 +446,7 @@ function runKarma(configFile, done) {
gulp.task('test.js', function(done) {
runSequence('test.unit.tools/ci', 'test.transpiler.unittest', 'test.unit.js/ci',
'test.unit.cjs/ci', 'test.typings', sequenceComplete(done));
'test.unit.cjs/ci', 'test.typings', 'test.typings.npm', sequenceComplete(done));
});
gulp.task('test.dart', function(done) {
@ -771,8 +771,25 @@ gulp.task('!pre.test.typings', ['docs/typings'], function() {
});
// -----------------
// Tests for the typings we deliver for TS users
//
// There are currently two mechanisms for this.
// The first is the legacy, bundled .d.ts file produced by dgeni.
// This is tested by 'test.typings'.
//
// The second is individual .d.ts files produced by the compiler,
// distributed in our npm package, and loaded from node_modules by
// the typescript compiler.
// This is tested by 'test.typings.npm'.
//
// During the transition, we support both packaging/delivery types.
// TODO(alexeagle): remove the dgeni bundle when users have switched
gulp.task('test.typings', ['!pre.test.typings'], function() {
return gulp.src(['typing_spec/*.ts', 'dist/docs/typings/angular2/*.d.ts', 'dist/docs/typings/http.d.ts'])
return gulp.src(['typing_spec/*.ts', 'dist/docs/typings/angular2/*.d.ts',
'dist/docs/typings/http.d.ts',
'dist/docs/typings/es6-shim/es6-shim.d.ts',
'dist/docs/typings/jasmine/jasmine.d.ts'])
.pipe(tsc({target: 'ES5', module: 'commonjs',
experimentalDecorators: true,
noImplicitAny: true,
@ -781,6 +798,29 @@ gulp.task('test.typings', ['!pre.test.typings'], function() {
typescript: require('typescript')}));
});
// Make sure the two typings tests are isolated, by running this one in a tempdir
var tmpdir = path.join(os.tmpdir(), 'test.typings', new Date().getTime().toString());
gulp.task('!pre.test.typings.layoutNodeModule', function() {
return gulp
.src(['dist/js/dev/es5/angular2/**/*'], {base: 'dist/js/dev/es5'})
.pipe(gulp.dest(path.join(tmpdir, 'node_modules')));
});
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
return gulp
.src(['typing_spec/basic_spec.ts'], {base: 'typing_spec'})
.pipe(gulp.dest(path.join(tmpdir)));
});
gulp.task('test.typings.npm', [
'!pre.test.typings.layoutNodeModule',
'!pre.test.typings.copyTypingsSpec'
], function() {
return gulp.src([tmpdir + '/**'])
.pipe(tsc({target: 'ES5', module: 'commonjs',
experimentalDecorators: true,
noImplicitAny: true,
typescript: require('typescript')}));
});
// -----------------
// orchestrated targets

View File

@ -0,0 +1,31 @@
/**
* Declarations angular depends on for compilation to ES6.
* This file is also used to propagate our transitive typings
* to users.
*/
/// <reference path="../typings/zone/zone.d.ts"/>
/// <reference path="../typings/hammerjs/hammerjs.d.ts"/>
/// <reference path="../typings/jasmine/jasmine.d.ts"/>
/// <reference path="../typings/angular-protractor/angular-protractor.d.ts"/>
declare var assert: any;
interface BrowserNodeGlobal {
Object: typeof Object;
Array: typeof Array;
Map: typeof Map;
Set: typeof Set;
Date: typeof Date;
RegExp: typeof RegExp;
JSON: typeof JSON;
Math: typeof Math;
assert(condition: any): void;
Reflect: any;
zone: Zone;
getAngularTestability: Function;
getAllAngularTestabilities: Function;
setTimeout: Function;
clearTimeout: Function;
setInterval: Function;
clearInterval: Function;
}

View File

@ -1,26 +1,7 @@
/**
* This file contains declarations of global symbols we reference in our code
* Declarations angular depends on for compilation to ES6.
* This file is also used to propagate our transitive typings
* to users.
*/
/// <reference path="../typings/zone/zone.d.ts"/>
declare var assert: any;
interface BrowserNodeGlobal {
Object: typeof Object;
Array: typeof Array;
Map: typeof Map;
Set: typeof Set;
Date: typeof Date;
RegExp: typeof RegExp;
JSON: typeof JSON;
Math: typeof Math;
assert(condition): void;
Reflect: any;
zone: Zone;
getAngularTestability: Function;
getAllAngularTestabilities: Function;
setTimeout: Function;
clearTimeout: Function;
setInterval: Function;
clearInterval: Function;
}
/// <reference path="../typings/es6-shim/es6-shim.d.ts"/>
/// <reference path="./globals-es6.d.ts"/>

View File

@ -13,6 +13,7 @@
"zone.js": "<%= packageJson.dependencies['zone.js'] %>"
},
"devDependencies": <%= JSON.stringify(packageJson.defaultDevDependencies) %>,
"typings": "./angular2.d.ts",
"typescript": {
"definitions": [
"bundles/typings/angular2/angular2.d.ts",

View File

@ -117,9 +117,6 @@ export function createNgZone(): NgZone {
var _platform: PlatformRef;
/**
* @internal
*/
export function platformCommon(bindings?: Array<Type | Binding | any[]>, initializer?: () => void):
PlatformRef {
if (isPresent(_platform)) {

View File

@ -2,9 +2,6 @@ import {isPresent} from 'angular2/src/core/facade/lang';
import {BaseException} from 'angular2/src/core/facade/exceptions';
import {ListWrapper, MapWrapper} from 'angular2/src/core/facade/collection';
/**
* @internal
*/
export class Locals {
constructor(public parent: Locals, public current: Map<any, any>) {}

View File

@ -30,9 +30,6 @@ import {
} from './exceptions';
import {resolveForwardRef} from './forward_ref';
/**
* @internal
*/
export class Dependency {
constructor(public key: Key, public optional: boolean, public lowerBoundVisibility: any,
public upperBoundVisibility: any, public properties: any[]) {}
@ -280,7 +277,6 @@ export class ResolvedBinding_ implements ResolvedBinding {
}
/**
* @internal
* An internal resolved representation of a factory function created by resolving {@link Binding}.
*/
export class ResolvedFactory {

View File

@ -387,7 +387,6 @@ export class BindingWithVisibility {
}
/**
* @internal
* Used to provide dependencies that cannot be easily expressed as bindings.
*/
export interface DependencyProvider {

View File

@ -1,5 +1,4 @@
/**
* @internal
* Type literals is a Dart-only feature. This is here only so we can x-compile
* to multiple languages.
*/

View File

@ -2,3 +2,4 @@
// I need to be here to make TypeScript think this is a module.
import {} from 'angular2/src/core/facade/lang';
export var workaround_empty_observable_list_diff: any;

View File

@ -1,4 +1,3 @@
///<reference path="../../../typings/tsd.d.ts" />
import {global, isPresent} from 'angular2/src/core/facade/lang';
// TODO(jeffbcross): use ES6 import once typings are available
var Subject = require('@reactivex/rxjs/dist/cjs/Subject');
@ -56,14 +55,18 @@ export class PromiseWrapper {
}
}
export class TimerWrapper {
static setTimeout(fn: Function, millis: number): number { return global.setTimeout(fn, millis); }
static clearTimeout(id: number): void { global.clearTimeout(id); }
export namespace NodeJS {
export interface Timer {}
}
static setInterval(fn: Function, millis: number): number {
export class TimerWrapper {
static setTimeout(fn: (...args: any[]) => void, millis: number): NodeJS.Timer { return global.setTimeout(fn, millis); }
static clearTimeout(id: NodeJS.Timer): void { global.clearTimeout(id); }
static setInterval(fn: (...args: any[]) => void, millis: number): NodeJS.Timer {
return global.setInterval(fn, millis);
}
static clearInterval(id: number): void { global.clearInterval(id); }
static clearInterval(id: NodeJS.Timer): void { global.clearInterval(id); }
}
export class ObservableWrapper {

View File

@ -259,7 +259,7 @@ export class ListWrapper {
static toString<T>(l: T[]): string { return l.toString(); }
static toJSON<T>(l: T[]): string { return JSON.stringify(l); }
static maximum<T>(list: T[], predicate: (T) => number): T {
static maximum<T>(list: T[], predicate: (t: T) => number): T {
if (list.length == 0) {
return null;
}

View File

@ -1,5 +1,3 @@
/// <reference path="../../../manual_typings/globals.d.ts" />
import {ExceptionHandler} from './exception_handler';
export {ExceptionHandler} from './exception_handler';

View File

@ -1,5 +1,3 @@
/// <reference path="../../../manual_typings/globals.d.ts" />
// TODO(jteplitz602): Load WorkerGlobalScope from lib.webworker.d.ts file #3492
declare var WorkerGlobalScope;
var globalScope: BrowserNodeGlobal;
@ -196,7 +194,7 @@ export class StringJoiner {
export class NumberParseError extends Error {
name: string;
constructor(public message: string) { super(message); }
constructor(public message: string) { super(); }
toString(): string { return this.message; }
}
@ -251,7 +249,7 @@ export class RegExpWrapper {
flags = flags.replace(/g/g, '');
return new _global.RegExp(regExpStr, flags + 'g');
}
static firstMatch(regExp: RegExp, input: string): string[] {
static firstMatch(regExp: RegExp, input: string): RegExpExecArray {
// Reset multimatch regex state
regExp.lastIndex = 0;
return regExp.exec(input);
@ -277,7 +275,7 @@ export class RegExpMatcherWrapper {
static next(matcher: {
re: RegExp;
input: string
}): string[] {
}): RegExpExecArray {
return matcher.re.exec(matcher.input);
}
}

View File

@ -1,9 +1,6 @@
import {MapWrapper} from 'angular2/src/core/facade/collection';
import {SimpleChange} from 'angular2/src/core/change_detection/change_detection_util';
/**
* @internal
*/
export enum LifecycleHooks {
OnInit,
OnDestroy,

View File

@ -13,13 +13,13 @@ interface Trace {
endTimeRange(range: Range);
}
interface Range {}
export interface Range {}
interface Events {
createScope(signature: string, flags: any): Scope;
}
interface Scope {
export interface Scope {
(...args): any;
}

View File

@ -9,7 +9,7 @@ import {
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';
import {ListWrapper} from 'angular2/src/core/facade/collection';
import {GetterFn, SetterFn, MethodFn} from './types';
import {PlatformReflectionCapabilities} from 'platform_reflection_capabilities';
import {PlatformReflectionCapabilities} from './platform_reflection_capabilities';
export class ReflectionCapabilities implements PlatformReflectionCapabilities {
private _reflect: any;

View File

@ -1,5 +1,3 @@
/// <reference path="../../../../../typings/hammerjs/hammerjs.d.ts"/>
import {HammerGesturesPluginCommon} from './hammer_common';
import {isPresent} from 'angular2/src/core/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';

View File

@ -90,7 +90,7 @@ export class KeyEventsPlugin extends EventManagerPlugin {
return fullKey;
}
static eventCallback(element: HTMLElement, fullKey: any, handler: (Event) => any, zone: NgZone):
static eventCallback(element: HTMLElement, fullKey: any, handler: (e: Event) => any, zone: NgZone):
(event: KeyboardEvent) => void {
return (event) => {
if (StringWrapper.equals(KeyEventsPlugin.getEventFullKey(event), fullKey)) {

View File

@ -236,7 +236,7 @@ if (!(Reflect && Reflect.getMetadata)) {
throw 'reflect-metadata shim is required when using class decorators';
}
export function makeDecorator(annotationCls, chainFn: (fn: Function) => void = null): (...args) =>
export function makeDecorator(annotationCls, chainFn: (fn: Function) => void = null): (...args: any[]) =>
(cls: any) => any {
function DecoratorFactory(objOrType): (cls: any) => any {
var annotationInstance = new (<any>annotationCls)(objOrType);

View File

@ -1,7 +1,3 @@
/// <reference path="../../typings/node/node.d.ts" />
/// <reference path="../../typings/angular-protractor/angular-protractor.d.ts" />
/// <reference path="../../typings/jasmine/jasmine"/>
import * as webdriver from 'selenium-webdriver';
export var browser: protractor.IBrowser = global['browser'];

View File

@ -1,5 +1,3 @@
/// <reference path="../../typings/jasmine/jasmine.d.ts"/>
import {global} from 'angular2/src/core/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';
import {ListWrapper} from 'angular2/src/core/facade/collection';

View File

@ -1,5 +1,3 @@
/// <reference path="../../typings/jasmine/jasmine.d.ts"/>
import {DOM} from 'angular2/src/core/dom/dom_adapter';
import {StringMapWrapper} from 'angular2/src/core/facade/collection';
import {global, isFunction, Math} from 'angular2/src/core/facade/lang';

View File

@ -1,4 +1,3 @@
/// <reference path="../../../manual_typings/globals.d.ts" />
import {MessageBus} from "angular2/src/web_workers/shared/message_bus";
import {print, isPresent, DateWrapper, stringify} from "angular2/src/core/facade/lang";
import {

View File

@ -23,7 +23,7 @@ var needsLongerTimers = browserDetection.isSlow || browserDetection.isEdge;
var resultTimer = 1000;
var testTimeout = browserDetection.isEdge ? 1200 : 100;
// Schedules a macrotask (using a timer)
function macroTask(fn: Function, timer = 1): void {
function macroTask(fn: (...args: any[]) => void, timer = 1): void {
// adds longer timers for passing tests in IE and Edge
_zone.runOutsideAngular(() => TimerWrapper.setTimeout(fn, needsLongerTimers ? timer : 1));
}

View File

@ -39,7 +39,7 @@ export class ImageDemo {
}
}
private _filter(i: number): Function {
private _filter(i: number): (...args: any[]) => void {
return () => {
var imageData = this._bitmapService.convertToImageData(this.images[i].buffer);
imageData = this._bitmapService.applySepia(imageData);

View File

@ -118,6 +118,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
mapRoot: '', // force sourcemaps to use relative path
noEmitOnError: false,
rootDir: '.',
rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'],
sourceMap: true,
sourceRoot: '.',
target: 'ES6'
@ -126,7 +127,8 @@ module.exports = function makeBrowserTree(options, destinationPath) {
// Use TypeScript to transpile the *.ts files to ES5
var typescriptOptions = {
allowNonTsExtensions: false,
declaration: false,
declaration: true,
stripInternal: true,
emitDecoratorMetadata: true,
experimentalDecorators: true,
mapRoot: '', // force sourcemaps to use relative path
@ -134,6 +136,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
moduleResolution: 1 /* classic */,
noEmitOnError: true,
rootDir: '.',
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
sourceMap: true,
sourceRoot: '.',
target: 'ES5'
@ -228,8 +231,29 @@ module.exports = function makeBrowserTree(options, destinationPath) {
htmlTree = mergeTrees([htmlTree, scripts, polymer, react]);
es5Tree = mergeTrees([es5Tree, htmlTree, assetsTree, clientModules]);
es6Tree = mergeTrees([es6Tree, htmlTree, assetsTree, clientModules]);
var typingsTree = new Funnel('modules', {
include: ['angular2/typings/**/*.d.ts',
'angular2/manual_typings/*.d.ts'],
destDir: '/'});
// Add a line to the end of our top-level .d.ts file.
// This HACK for transitive typings is a workaround for
// https://github.com/Microsoft/TypeScript/issues/5097
//
// This allows users to get our top-level dependencies like es6-shim.d.ts
// to appear when they compile against angular2.
//
// This carries the risk that the user brings their own copy of that file
// (or any other symbols exported here) and they will get a compiler error
// because of the duplicate definitions.
// TODO(alexeagle): remove this when typescript releases a fix
es5Tree = replace(es5Tree, {
files: ['angular2/angular2.d.ts'],
patterns: [{match: /$/, replacement: 'import "./manual_typings/globals.d.ts";\n'}]
});
es5Tree = mergeTrees([es5Tree, htmlTree, assetsTree, clientModules, typingsTree]);
es6Tree = mergeTrees([es6Tree, htmlTree, assetsTree, clientModules, typingsTree]);
var mergedTree = mergeTrees([stew.mv(es6Tree, '/es6'), stew.mv(es5Tree, '/es5')]);

View File

@ -41,7 +41,7 @@ module.exports = function makeNodeTree(destinationPath) {
moduleResolution: 1 /* classic */,
noEmitOnError: true,
rootDir: '.',
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
rootFilePaths: ['angular2/manual_typings/globals.d.ts', 'angular2/typings/es6-shim/es6-shim.d.ts'],
sourceMap: true,
sourceRoot: '.',
target: 'ES5'

View File

@ -1,5 +1,3 @@
///<reference path="../dist/docs/typings/angular2/angular2.d.ts"/>
import {Component, bootstrap, View} from 'angular2/angular2'
@Component({
@ -15,4 +13,4 @@ class MyAppComponent {
constructor() { this.name = 'Alice'; }
}
bootstrap(MyAppComponent);
bootstrap(MyAppComponent);