fix(router): Update types for TypeScript nullability support

This reverts commit ea8ffc9841.
This commit is contained in:
Miško Hevery 2017-04-17 11:13:13 -07:00 committed by Tobias Bosch
parent ec028b8109
commit bc431888f3
26 changed files with 230 additions and 223 deletions

View File

@ -25,7 +25,9 @@ import {UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
import {andObservables, forEach, waitForMap, wrapIntoObservable} from './utils/collection';
class NoMatch {
constructor(public segmentGroup: UrlSegmentGroup = null) {}
public segmentGroup: UrlSegmentGroup|null;
constructor(segmentGroup?: UrlSegmentGroup) { this.segmentGroup = segmentGroup || null; }
}
class AbsoluteRedirect {
@ -80,7 +82,7 @@ class ApplyRedirects {
this.expandSegmentGroup(this.ngModule, this.config, this.urlTree.root, PRIMARY_OUTLET);
const urlTrees$ = map.call(
expanded$, (rootSegmentGroup: UrlSegmentGroup) => this.createUrlTree(
rootSegmentGroup, this.urlTree.queryParams, this.urlTree.fragment));
rootSegmentGroup, this.urlTree.queryParams, this.urlTree.fragment !));
return _catch.call(urlTrees$, (e: any) => {
if (e instanceof AbsoluteRedirect) {
// after an absolute redirect we do not apply any more redirects!
@ -102,7 +104,7 @@ class ApplyRedirects {
this.expandSegmentGroup(this.ngModule, this.config, tree.root, PRIMARY_OUTLET);
const mapped$ = map.call(
expanded$, (rootSegmentGroup: UrlSegmentGroup) =>
this.createUrlTree(rootSegmentGroup, tree.queryParams, tree.fragment));
this.createUrlTree(rootSegmentGroup, tree.queryParams, tree.fragment !));
return _catch.call(mapped$, (e: any): Observable<UrlTree> => {
if (e instanceof NoMatch) {
throw this.noMatchError(e);
@ -215,8 +217,8 @@ class ApplyRedirects {
private expandWildCardWithParamsAgainstRouteUsingRedirect(
ngModule: NgModuleRef<any>, routes: Route[], route: Route,
outlet: string): Observable<UrlSegmentGroup> {
const newTree = this.applyRedirectCommands([], route.redirectTo, {});
if (route.redirectTo.startsWith('/')) {
const newTree = this.applyRedirectCommands([], route.redirectTo !, {});
if (route.redirectTo !.startsWith('/')) {
return absoluteRedirect(newTree);
}
@ -234,8 +236,8 @@ class ApplyRedirects {
if (!matched) return noMatch(segmentGroup);
const newTree = this.applyRedirectCommands(
consumedSegments, route.redirectTo, <any>positionalParamSegments);
if (route.redirectTo.startsWith('/')) {
consumedSegments, route.redirectTo !, <any>positionalParamSegments);
if (route.redirectTo !.startsWith('/')) {
return absoluteRedirect(newTree);
}
@ -331,7 +333,7 @@ class ApplyRedirects {
}
if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
return namedOutletsRedirect(route.redirectTo);
return namedOutletsRedirect(route.redirectTo !);
}
c = c.children[PRIMARY_OUTLET];
@ -442,9 +444,9 @@ function match(segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment
return {
matched: true,
consumedSegments: res.consumed,
lastChild: res.consumed.length,
positionalParamSegments: res.posParams,
consumedSegments: res.consumed !,
lastChild: res.consumed.length !,
positionalParamSegments: res.posParams !,
};
}

View File

@ -164,7 +164,7 @@ function createPositionApplyingDoubleDots(
let dd = numberOfDoubleDots;
while (dd > ci) {
dd -= ci;
g = g.parent;
g = g.parent !;
if (!g) {
throw new Error('Invalid number of \'../\'');
}

View File

@ -71,8 +71,8 @@ export class RouterOutlet implements OnDestroy {
if (!this.activated) throw new Error('Outlet is not activated');
this.location.detach();
const r = this.activated;
this.activated = null;
this._activatedRoute = null;
this.activated = null !;
this._activatedRoute = null !;
return r;
}
@ -86,8 +86,8 @@ export class RouterOutlet implements OnDestroy {
if (this.activated) {
const c = this.component;
this.activated.destroy();
this.activated = null;
this._activatedRoute = null;
this.activated = null !;
this._activatedRoute = null !;
this.deactivateEvents.emit(c);
}
}
@ -104,8 +104,8 @@ export class RouterOutlet implements OnDestroy {
this._activatedRoute = activatedRoute;
const snapshot = activatedRoute._futureSnapshot;
const component: any = <any>snapshot._routeConfig.component;
const factory = resolver.resolveComponentFactory(component);
const component: any = <any>snapshot._routeConfig !.component;
const factory = resolver.resolveComponentFactory(component) !;
const inj = ReflectiveInjector.fromResolvedProviders(providers, injector);
@ -126,10 +126,10 @@ export class RouterOutlet implements OnDestroy {
this._activatedRoute = activatedRoute;
const snapshot = activatedRoute._futureSnapshot;
const component = <any>snapshot._routeConfig.component;
const component = <any>snapshot._routeConfig !.component;
resolver = resolver || this.resolver;
const factory = resolver.resolveComponentFactory(component);
const factory = resolver.resolveComponentFactory(component) !;
const injector = new OutletInjector(activatedRoute, outletMap, this.location.injector);

View File

@ -21,14 +21,14 @@ import {TreeNode} from './utils/tree';
class NoMatch {}
export function recognize(
rootComponentType: Type<any>, config: Routes, urlTree: UrlTree,
rootComponentType: Type<any>| null, config: Routes, urlTree: UrlTree,
url: string): Observable<RouterStateSnapshot> {
return new Recognizer(rootComponentType, config, urlTree, url).recognize();
}
class Recognizer {
constructor(
private rootComponentType: Type<any>, private config: Routes, private urlTree: UrlTree,
private rootComponentType: Type<any>|null, private config: Routes, private urlTree: UrlTree,
private url: string) {}
recognize(): Observable<RouterStateSnapshot> {
@ -38,8 +38,8 @@ class Recognizer {
const children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
const root = new ActivatedRouteSnapshot(
[], Object.freeze({}), Object.freeze(this.urlTree.queryParams), this.urlTree.fragment, {},
PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
[], Object.freeze({}), Object.freeze(this.urlTree.queryParams), this.urlTree.fragment !,
{}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
const rootNode = new TreeNode<ActivatedRouteSnapshot>(root, children);
const routeState = new RouterStateSnapshot(this.url, rootNode);
@ -110,10 +110,10 @@ class Recognizer {
if ((route.outlet || PRIMARY_OUTLET) !== outlet) throw new NoMatch();
if (route.path === '**') {
const params = segments.length > 0 ? last(segments).parameters : {};
const params = segments.length > 0 ? last(segments) !.parameters : {};
const snapshot = new ActivatedRouteSnapshot(
segments, params, Object.freeze(this.urlTree.queryParams), this.urlTree.fragment,
getData(route), outlet, route.component, route, getSourceSegmentGroup(rawSegment),
segments, params, Object.freeze(this.urlTree.queryParams), this.urlTree.fragment !,
getData(route), outlet, route.component !, route, getSourceSegmentGroup(rawSegment),
getPathIndexShift(rawSegment) + segments.length, getResolve(route));
return [new TreeNode<ActivatedRouteSnapshot>(snapshot, [])];
}
@ -127,7 +127,7 @@ class Recognizer {
const snapshot = new ActivatedRouteSnapshot(
consumedSegments, parameters, Object.freeze(this.urlTree.queryParams),
this.urlTree.fragment, getData(route), outlet, route.component, route,
this.urlTree.fragment !, getData(route), outlet, route.component !, route,
getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + consumedSegments.length,
getResolve(route));
@ -160,7 +160,7 @@ function getChildConfig(route: Route): Route[] {
}
if (route.loadChildren) {
return route._loadedConfig.routes;
return route._loadedConfig !.routes;
}
return [];
@ -180,7 +180,7 @@ function match(segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment
if (!res) throw new NoMatch();
const posParams: {[n: string]: string} = {};
forEach(res.posParams, (v: UrlSegment, k: string) => { posParams[k] = v.path; });
forEach(res.posParams !, (v: UrlSegment, k: string) => { posParams[k] = v.path; });
const parameters = {...posParams, ...res.consumed[res.consumed.length - 1].parameters};
return {consumedSegments: res.consumed, lastChild: res.consumed.length, parameters};

View File

@ -37,13 +37,13 @@ export abstract class RouteReuseStrategy {
abstract shouldDetach(route: ActivatedRouteSnapshot): boolean;
/** Stores the detached route */
abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void;
abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle|null): void;
/** Determines if this route (and its subtree) should be reattached */
abstract shouldAttach(route: ActivatedRouteSnapshot): boolean;
/** Retrieves the previously stored route */
abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle;
abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null;
/** Determines if a route should be reused */
abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean;

View File

@ -189,7 +189,7 @@ export type RouterHook = (snapshot: RouterStateSnapshot) => Observable<void>;
* @internal
*/
function defaultRouterHook(snapshot: RouterStateSnapshot): Observable<void> {
return of (null);
return of (null) as any;
}
/**
@ -199,7 +199,7 @@ export class DefaultRouteReuseStrategy implements RouteReuseStrategy {
shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; }
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig;
}
@ -218,7 +218,7 @@ export class Router {
private currentUrlTree: UrlTree;
private rawUrlTree: UrlTree;
private navigations = new BehaviorSubject<NavigationParams>(null);
private navigations = new BehaviorSubject<NavigationParams>(null !);
private routerEvents = new Subject<Event>();
private currentRouterState: RouterState;
@ -263,7 +263,7 @@ export class Router {
*/
// TODO: vsavkin make internal after the final is out.
constructor(
private rootComponentType: Type<any>, private urlSerializer: UrlSerializer,
private rootComponentType: Type<any>|null, private urlSerializer: UrlSerializer,
private outletMap: RouterOutletMap, private location: Location, injector: Injector,
loader: NgModuleFactoryLoader, compiler: Compiler, public config: Routes) {
const onLoadStart = (r: Route) => this.triggerEvent(new RouteConfigLoadStart(r));
@ -354,7 +354,7 @@ export class Router {
dispose(): void {
if (this.locationSubscription) {
this.locationSubscription.unsubscribe();
this.locationSubscription = null;
this.locationSubscription = null !;
}
}
@ -407,7 +407,7 @@ export class Router {
}
const a = relativeTo || this.routerState.root;
const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
let q: Params = null;
let q: Params|null = null;
if (queryParamsHandling) {
switch (queryParamsHandling) {
case 'merge':
@ -417,12 +417,12 @@ export class Router {
q = this.currentUrlTree.queryParams;
break;
default:
q = queryParams;
q = queryParams || null;
}
} else {
q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams;
q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null;
}
return createUrlTree(a, this.currentUrlTree, commands, q, f);
return createUrlTree(a, this.currentUrlTree, commands, q !, f !);
}
/**
@ -535,7 +535,7 @@ export class Router {
// we should skip those.
if (lastNavigation && source !== 'imperative' && lastNavigation.source === 'imperative' &&
lastNavigation.rawUrl.toString() === rawUrl.toString()) {
return null; // return value is not used
return Promise.resolve(true); // return value is not used
}
// Because of a bug in IE and Edge, the location class fires two events (popstate and
@ -543,7 +543,7 @@ export class Router {
// flicker.
if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
lastNavigation.rawUrl.toString() === rawUrl.toString()) {
return null; // return value is not used
return Promise.resolve(true); // return value is not used
}
let resolve: any = null;
@ -572,7 +572,7 @@ export class Router {
Promise.resolve()
.then(
(_) => this.runNavigate(
url, rawUrl, extras.skipLocationChange, extras.replaceUrl, id, null))
url, rawUrl, !!extras.skipLocationChange, !!extras.replaceUrl, id, null))
.then(resolve, reject);
// we cannot process the current URL, but we could process the previous one =>
@ -596,7 +596,7 @@ export class Router {
private runNavigate(
url: UrlTree, rawUrl: UrlTree, shouldPreventPushState: boolean, shouldReplaceUrl: boolean,
id: number, precreatedState: RouterStateSnapshot): Promise<boolean> {
id: number, precreatedState: RouterStateSnapshot|null): Promise<boolean> {
if (id !== this.navigationId) {
this.location.go(this.urlSerializer.serialize(this.currentUrlTree));
this.routerEvents.next(new NavigationCancel(
@ -768,7 +768,7 @@ class CanActivate {
}
class CanDeactivate {
constructor(public component: Object, public route: ActivatedRouteSnapshot) {}
constructor(public component: Object|null, public route: ActivatedRouteSnapshot) {}
}
@ -804,8 +804,8 @@ export class PreActivation {
}
private traverseChildRoutes(
futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>,
outletMap: RouterOutletMap, futurePath: ActivatedRouteSnapshot[]): void {
futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>|null,
outletMap: RouterOutletMap|null, futurePath: ActivatedRouteSnapshot[]): void {
const prevChildren = nodeChildrenAsMap(currNode);
futureNode.children.forEach(c => {
@ -814,12 +814,12 @@ export class PreActivation {
});
forEach(
prevChildren, (v: TreeNode<ActivatedRouteSnapshot>, k: string) =>
this.deactiveRouteAndItsChildren(v, outletMap._outlets[k]));
this.deactiveRouteAndItsChildren(v, outletMap !._outlets[k]));
}
private traverseRoutes(
futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>,
parentOutletMap: RouterOutletMap, futurePath: ActivatedRouteSnapshot[]): void {
parentOutletMap: RouterOutletMap|null, futurePath: ActivatedRouteSnapshot[]): void {
const future = futureNode.value;
const curr = currNode ? currNode.value : null;
const outlet = parentOutletMap ? parentOutletMap._outlets[futureNode.value.outlet] : null;
@ -827,9 +827,9 @@ export class PreActivation {
// reusing the node
if (curr && future._routeConfig === curr._routeConfig) {
if (this.shouldRunGuardsAndResolvers(
curr, future, future._routeConfig.runGuardsAndResolvers)) {
curr, future, future._routeConfig !.runGuardsAndResolvers)) {
this.canActivateChecks.push(new CanActivate(futurePath));
this.canDeactivateChecks.push(new CanDeactivate(outlet.component, curr));
this.canDeactivateChecks.push(new CanDeactivate(outlet !.component, curr));
} else {
// we need to set the data
future.data = curr.data;
@ -864,7 +864,7 @@ export class PreActivation {
private shouldRunGuardsAndResolvers(
curr: ActivatedRouteSnapshot, future: ActivatedRouteSnapshot,
mode: RunGuardsAndResolvers): boolean {
mode: RunGuardsAndResolvers|undefined): boolean {
switch (mode) {
case 'always':
return true;
@ -880,7 +880,7 @@ export class PreActivation {
}
private deactiveRouteAndItsChildren(
route: TreeNode<ActivatedRouteSnapshot>, outlet: RouterOutlet): void {
route: TreeNode<ActivatedRouteSnapshot>, outlet: RouterOutlet|null): void {
const prevChildren = nodeChildrenAsMap(route);
const r = route.value;
@ -958,13 +958,14 @@ export class PreActivation {
}
private extractCanActivateChild(p: ActivatedRouteSnapshot):
{node: ActivatedRouteSnapshot, guards: any[]} {
{node: ActivatedRouteSnapshot, guards: any[]}|null {
const canActivateChild = p._routeConfig ? p._routeConfig.canActivateChild : null;
if (!canActivateChild || canActivateChild.length === 0) return null;
return {node: p, guards: canActivateChild};
}
private runCanDeactivate(component: Object, curr: ActivatedRouteSnapshot): Observable<boolean> {
private runCanDeactivate(component: Object|null, curr: ActivatedRouteSnapshot):
Observable<boolean> {
const canDeactivate = curr && curr._routeConfig ? curr._routeConfig.canDeactivate : null;
if (!canDeactivate || canDeactivate.length === 0) return of (true);
const canDeactivate$ = mergeMap.call(from(canDeactivate), (c: any) => {
@ -1020,7 +1021,7 @@ class ActivateRoutes {
}
private deactivateChildRoutes(
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>,
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>|null,
outletMap: RouterOutletMap): void {
const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode);
futureNode.children.forEach(c => {
@ -1031,7 +1032,7 @@ class ActivateRoutes {
}
private activateChildRoutes(
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>,
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>|null,
outletMap: RouterOutletMap): void {
const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode);
futureNode.children.forEach(
@ -1136,7 +1137,7 @@ class ActivateRoutes {
private deactiveRouteAndOutlet(route: TreeNode<ActivatedRoute>, parentOutletMap: RouterOutletMap):
void {
const prevChildren: {[key: string]: any} = nodeChildrenAsMap(route);
let outlet: RouterOutlet = null;
let outlet: RouterOutlet|null = null;
// getOutlet throws when cannot find the right outlet,
// which can happen if an outlet was in an NgIf and was removed
@ -1166,7 +1167,7 @@ function advanceActivatedRouteNodeAndItsChildren(node: TreeNode<ActivatedRoute>)
node.children.forEach(advanceActivatedRouteNodeAndItsChildren);
}
function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig|null {
for (let s = snapshot.parent; s; s = s.parent) {
const route = s._routeConfig;
if (route && route._loadedConfig) return route._loadedConfig;
@ -1176,7 +1177,7 @@ function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfi
return null;
}
function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig {
function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig|null {
if (!snapshot) return null;
for (let s = snapshot.parent; s; s = s.parent) {
@ -1187,7 +1188,7 @@ function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConf
return null;
}
function nodeChildrenAsMap<T extends{outlet: string}>(node: TreeNode<T>) {
function nodeChildrenAsMap<T extends{outlet: string}>(node: TreeNode<T>| null) {
const map: {[key: string]: TreeNode<T>} = {};
if (node) {

View File

@ -32,7 +32,7 @@ export class RouterConfigLoader {
this.onLoadStartListener(route);
}
const moduleFactory$ = this.loadModuleFactory(route.loadChildren);
const moduleFactory$ = this.loadModuleFactory(route.loadChildren !);
return map.call(moduleFactory$, (factory: NgModuleFactory<any>) => {
if (this.onLoadEndListener) {

View File

@ -327,7 +327,7 @@ export class RouterInitializer {
appInitializer(): Promise<any> {
const p: Promise<any> = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
return p.then(() => {
let resolve: Function = null;
let resolve: Function = null !;
const res = new Promise(r => resolve = r);
const router = this.injector.get(Router);
const opts = this.injector.get(ROUTER_CONFIGURATION);
@ -349,7 +349,7 @@ export class RouterInitializer {
// subsequent navigations should not be delayed
} else {
return of (null);
return of (null) as any;
}
};
router.initialNavigation();
@ -380,7 +380,7 @@ export class RouterInitializer {
preloader.setUpPreloading();
router.resetRootComponentType(ref.componentTypes[0]);
this.resultOfPreactivationDone.next(null);
this.resultOfPreactivationDone.next(null !);
this.resultOfPreactivationDone.complete();
}

View File

@ -25,5 +25,5 @@ export class RouterOutletMap {
/**
* Removes an outlet from this map.
*/
removeOutlet(name: string): void { this._outlets[name] = undefined; }
removeOutlet(name: string): void { this._outlets[name] = undefined !; }
}

View File

@ -57,7 +57,7 @@ export class RouterState extends Tree<ActivatedRoute> {
toString(): string { return this.snapshot.toString(); }
}
export function createEmptyState(urlTree: UrlTree, rootComponent: Type<any>): RouterState {
export function createEmptyState(urlTree: UrlTree, rootComponent: Type<any>| null): RouterState {
const snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
const emptyUrl = new BehaviorSubject([new UrlSegment('', {})]);
const emptyParams = new BehaviorSubject({});
@ -72,7 +72,7 @@ export function createEmptyState(urlTree: UrlTree, rootComponent: Type<any>): Ro
}
export function createEmptyStateSnapshot(
urlTree: UrlTree, rootComponent: Type<any>): RouterStateSnapshot {
urlTree: UrlTree, rootComponent: Type<any>| null): RouterStateSnapshot {
const emptyParams = {};
const emptyData = {};
const emptyQueryParams = {};
@ -132,21 +132,21 @@ export class ActivatedRoute {
public outlet: string,
/** The component of the route. It's a constant */
// TODO(vsavkin): remove |string
public component: Type<any>|string, futureSnapshot: ActivatedRouteSnapshot) {
public component: Type<any>|string|null, futureSnapshot: ActivatedRouteSnapshot) {
this._futureSnapshot = futureSnapshot;
}
/** The configuration used to match this route */
get routeConfig(): Route { return this._futureSnapshot.routeConfig; }
get routeConfig(): Route|null { return this._futureSnapshot.routeConfig; }
/** The root of the router state */
get root(): ActivatedRoute { return this._routerState.root; }
/** The parent of this route in the router state tree */
get parent(): ActivatedRoute { return this._routerState.parent(this); }
get parent(): ActivatedRoute|null { return this._routerState.parent(this); }
/** The first child of this route in the router state tree */
get firstChild(): ActivatedRoute { return this._routerState.firstChild(this); }
get firstChild(): ActivatedRoute|null { return this._routerState.firstChild(this); }
/** The children of this route in the router state tree */
get children(): ActivatedRoute[] { return this._routerState.children(this); }
@ -234,7 +234,7 @@ export function inheritedParamsDataResolve(route: ActivatedRouteSnapshot): Inher
*/
export class ActivatedRouteSnapshot {
/** @internal **/
_routeConfig: Route;
_routeConfig: Route|null;
/** @internal **/
_urlSegment: UrlSegmentGroup;
/** @internal */
@ -265,7 +265,7 @@ export class ActivatedRouteSnapshot {
/** The outlet name of the route */
public outlet: string,
/** The component of the route */
public component: Type<any>|string, routeConfig: Route, urlSegment: UrlSegmentGroup,
public component: Type<any>|string|null, routeConfig: Route|null, urlSegment: UrlSegmentGroup,
lastPathIndex: number, resolve: ResolveData) {
this._routeConfig = routeConfig;
this._urlSegment = urlSegment;
@ -274,16 +274,16 @@ export class ActivatedRouteSnapshot {
}
/** The configuration used to match this route */
get routeConfig(): Route { return this._routeConfig; }
get routeConfig(): Route|null { return this._routeConfig; }
/** The root of the router state */
get root(): ActivatedRouteSnapshot { return this._routerState.root; }
/** The parent of this route in the router state tree */
get parent(): ActivatedRouteSnapshot { return this._routerState.parent(this); }
get parent(): ActivatedRouteSnapshot|null { return this._routerState.parent(this); }
/** The first child of this route in the router state tree */
get firstChild(): ActivatedRouteSnapshot { return this._routerState.firstChild(this); }
get firstChild(): ActivatedRouteSnapshot|null { return this._routerState.firstChild(this); }
/** The children of this route in the router state tree */
get children(): ActivatedRouteSnapshot[] { return this._routerState.children(this); }
@ -398,5 +398,5 @@ export function equalParamsAndUrlSegments(
const parentsMismatch = !a.parent !== !b.parent;
return equalUrlParams && !parentsMismatch &&
(!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
}
(!a.parent || equalParamsAndUrlSegments(a.parent, b.parent !));
}

View File

@ -111,7 +111,7 @@ export function isNavigationCancelingError(error: Error) {
// Matches the route configuration (`route`) against the actual URL (`segments`).
export function defaultUrlMatcher(
segments: UrlSegment[], segmentGroup: UrlSegmentGroup, route: Route): UrlMatchResult|null {
const parts = route.path.split('/');
const parts = route.path !.split('/');
if (parts.length > segments.length) {
// The actual URL is shorter than the config, no match

View File

@ -113,7 +113,7 @@ export class UrlTree {
/** The query params of the URL */
public queryParams: {[key: string]: string},
/** The fragment of the URL */
public fragment: string) {}
public fragment: string|null) {}
get queryParamMap(): ParamMap {
if (!this._queryParamMap) {
@ -139,7 +139,7 @@ export class UrlSegmentGroup {
/** @internal */
_segmentIndexShift: number;
/** The parent node in the url tree */
parent: UrlSegmentGroup = null;
parent: UrlSegmentGroup|null = null;
constructor(
/** The URL segments of this group. See {@link UrlSegment} for more information */
@ -280,7 +280,7 @@ export class DefaultUrlSerializer implements UrlSerializer {
serialize(tree: UrlTree): string {
const segment = `/${serializeSegment(tree.root, true)}`;
const query = serializeQueryParams(tree.queryParams);
const fragment = typeof tree.fragment === `string` ? `#${encodeURI(tree.fragment)}` : '';
const fragment = typeof tree.fragment === `string` ? `#${encodeURI(tree.fragment !)}` : '';
return `${segment}${query}${fragment}`;
}
@ -397,7 +397,9 @@ class UrlParser {
return params;
}
parseFragment(): string { return this.consumeOptional('#') ? decodeURI(this.remaining) : null; }
parseFragment(): string|null {
return this.consumeOptional('#') ? decodeURI(this.remaining) : null;
}
private parseChildren(): {[outlet: string]: UrlSegmentGroup} {
if (this.remaining === '') {
@ -521,7 +523,7 @@ class UrlParser {
throw new Error(`Cannot parse url '${this.url}'`);
}
let outletName: string;
let outletName: string = undefined !;
if (path.indexOf(':') > -1) {
outletName = path.substr(0, path.indexOf(':'));
this.capture(outletName);

View File

@ -45,7 +45,7 @@ export function flatten<T>(arr: T[][]): T[] {
return Array.prototype.concat.apply([], arr);
}
export function last<T>(a: T[]): T {
export function last<T>(a: T[]): T|null {
return a.length > 0 ? a[a.length - 1] : null;
}

View File

@ -17,7 +17,7 @@ export class Tree<T> {
/**
* @internal
*/
parent(t: T): T {
parent(t: T): T|null {
const p = this.pathFromRoot(t);
return p.length > 1 ? p[p.length - 2] : null;
}
@ -33,7 +33,7 @@ export class Tree<T> {
/**
* @internal
*/
firstChild(t: T): T {
firstChild(t: T): T|null {
const n = findNode(t, this._root);
return n && n.children.length > 0 ? n.children[0].value : null;
}
@ -55,7 +55,7 @@ export class Tree<T> {
pathFromRoot(t: T): T[] { return findPath(t, this._root, []).map(s => s.value); }
}
function findNode<T>(expected: T, c: TreeNode<T>): TreeNode<T> {
function findNode<T>(expected: T, c: TreeNode<T>): TreeNode<T>|null {
if (expected === c.value) return c;
for (const cc of c.children) {
const r = findNode(expected, cc);

View File

@ -51,7 +51,7 @@ describe('applyRedirects', () => {
});
it('should throw when cannot handle a positional parameter', () => {
applyRedirects(testModule.injector, null, serializer, tree('/a/1'), [
applyRedirects(testModule.injector, null !, serializer, tree('/a/1'), [
{path: 'a/:id', redirectTo: 'a/:other'}
]).subscribe(() => {}, (e) => {
expect(e.message).toEqual('Cannot redirect to \'a/:other\'. Cannot find \':other\'.');
@ -403,7 +403,7 @@ describe('applyRedirects', () => {
{path: '', redirectTo: 'a', pathMatch: 'full'}
];
applyRedirects(testModule.injector, null, serializer, tree('b'), config)
applyRedirects(testModule.injector, null !, serializer, tree('b'), config)
.subscribe(
(_) => { throw 'Should not be reached'; },
e => { expect(e.message).toEqual('Cannot match any routes. URL Segment: \'b\''); });
@ -533,7 +533,7 @@ describe('applyRedirects', () => {
]
}];
applyRedirects(testModule.injector, null, serializer, tree('a/(d//aux:e)'), config)
applyRedirects(testModule.injector, null !, serializer, tree('a/(d//aux:e)'), config)
.subscribe(
(_) => { throw 'Should not be reached'; },
e => { expect(e.message).toEqual('Cannot match any routes. URL Segment: \'a\''); });
@ -564,7 +564,7 @@ describe('applyRedirects', () => {
it('should error when no children matching and some url is left', () => {
applyRedirects(
testModule.injector, null, serializer, tree('/a/c'),
testModule.injector, null !, serializer, tree('/a/c'),
[{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}])
.subscribe(
(_) => { throw 'Should not be reached'; },
@ -587,7 +587,7 @@ describe('applyRedirects', () => {
matcher: matcher,
component: ComponentA,
children: [{path: 'b', component: ComponentB}]
}],
}] as any,
'/a/1/b', (t: UrlTree) => { compareTrees(t, tree('a/1/b')); });
});
});
@ -614,7 +614,7 @@ describe('applyRedirects', () => {
it('should throw when using non-absolute redirects', () => {
applyRedirects(
testModule.injector, null, serializer, tree('a'),
testModule.injector, null !, serializer, tree('a'),
[
{path: 'a', redirectTo: 'b(aux:c)'},
])
@ -629,7 +629,7 @@ describe('applyRedirects', () => {
});
function checkRedirect(config: Routes, url: string, callback: any): void {
applyRedirects(TestBed, null, new DefaultUrlSerializer(), tree(url), config)
applyRedirects(TestBed, null !, new DefaultUrlSerializer(), tree(url), config)
.subscribe(callback, e => { throw e; });
}

View File

@ -16,7 +16,7 @@ import {NavigationEnd, Resolve, Router, RouterModule} from '@angular/router';
describe('bootstrap', () => {
let log: any[] = [];
let testProviders: any[] = null;
let testProviders: any[] = null !;
@Component({selector: 'test-app', template: 'root <router-outlet></router-outlet>'})
class RootCmp {
@ -80,7 +80,7 @@ describe('bootstrap', () => {
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router = res.injector.get(Router);
const data = router.routerState.snapshot.root.firstChild.data;
const data = router.routerState.snapshot.root.firstChild !.data;
expect(data['test']).toEqual('test-data');
expect(log).toEqual(
['TestModule', 'NavigationStart', 'RoutesRecognized', 'RootCmp', 'NavigationEnd']);

View File

@ -24,7 +24,8 @@ describe('config', () => {
it('should throw for undefined route', () => {
expect(() => {
validateConfig([{path: 'a', component: ComponentA}, , {path: 'b', component: ComponentB}]);
validateConfig(
[{path: 'a', component: ComponentA}, , {path: 'b', component: ComponentB}] as any);
}).toThrowError(/Invalid configuration of route ''/);
});
@ -36,7 +37,7 @@ describe('config', () => {
{path: 'b', component: ComponentB},
,
]
}]);
}] as any);
}).toThrowError(/Invalid configuration of route 'a'/);
});
@ -98,7 +99,7 @@ describe('config', () => {
});
it('should throw when path and matcher are missing', () => {
expect(() => { validateConfig([{component: null, redirectTo: 'b'}]); })
expect(() => { validateConfig([{component: null, redirectTo: 'b'}] as any); })
.toThrowError(
`Invalid configuration of route '': routes must have either a path or a matcher specified`);
});

View File

@ -19,7 +19,7 @@ describe('create router state', () => {
const reuseStrategy = new DefaultRouteReuseStrategy();
const emptyState = () =>
createEmptyState(new UrlTree(new UrlSegmentGroup([], {}), {}, null), RootComponent);
createEmptyState(new UrlTree(new UrlSegmentGroup([], {}), {}, null !), RootComponent);
it('should work create new state', () => {
const state = createRouterState(
@ -76,8 +76,8 @@ describe('create router state', () => {
createRouterState(reuseStrategy, createState(config, 'a/2;p=22/(b//right:c)'), prevState);
expect(prevState.root).toBe(state.root);
const prevP = prevState.firstChild(prevState.root);
const currP = state.firstChild(state.root);
const prevP = prevState.firstChild(prevState.root) !;
const currP = state.firstChild(state.root) !;
expect(prevP).toBe(currP);
const prevC = prevState.children(prevP);
@ -101,7 +101,7 @@ function advanceNode(node: TreeNode<ActivatedRoute>): void {
}
function createState(config: Routes, url: string): RouterStateSnapshot {
let res: RouterStateSnapshot;
let res: RouterStateSnapshot = undefined !;
recognize(RootComponent, config, tree(url), url).forEach(s => res = s);
return res;
}

View File

@ -247,10 +247,10 @@ function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragme
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1,
<any>null);
const a = new ActivatedRoute(
new BehaviorSubject(null), new BehaviorSubject(null), new BehaviorSubject(null),
new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s);
new BehaviorSubject(null !), new BehaviorSubject(null !), new BehaviorSubject(null !),
new BehaviorSubject(null !), new BehaviorSubject(null !), PRIMARY_OUTLET, 'someComponent', s);
advanceActivatedRoute(a);
return createUrlTree(a, tree, commands, queryParams, fragment);
return createUrlTree(a, tree, commands, queryParams !, fragment !);
}
function create(
@ -263,8 +263,8 @@ function create(
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment,
startIndex, <any>null);
const a = new ActivatedRoute(
new BehaviorSubject(null), new BehaviorSubject(null), new BehaviorSubject(null),
new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s);
new BehaviorSubject(null !), new BehaviorSubject(null !), new BehaviorSubject(null !),
new BehaviorSubject(null !), new BehaviorSubject(null !), PRIMARY_OUTLET, 'someComponent', s);
advanceActivatedRoute(a);
return createUrlTree(a, tree, commands, queryParams, fragment);
return createUrlTree(a, tree, commands, queryParams !, fragment !);
}

View File

@ -239,7 +239,7 @@ describe('Integration', () => {
advance(fixture);
let recordedError: any = null;
router.navigateByUrl('/blank').catch(e => recordedError = e);
router.navigateByUrl('/blank') !.catch(e => recordedError = e);
advance(fixture);
expect(recordedError.message).toEqual('Cannot find primary outlet to load \'BlankCmp\'');
@ -619,8 +619,8 @@ describe('Integration', () => {
const user = fixture.debugElement.children[1].componentInstance;
let r1: any, r2: any;
router.navigateByUrl('/user/victor').then(_ => r1 = _);
router.navigateByUrl('/user/fedor').then(_ => r2 = _);
router.navigateByUrl('/user/victor') !.then(_ => r1 = _);
router.navigateByUrl('/user/fedor') !.then(_ => r2 = _);
advance(fixture);
expect(r1).toEqual(false); // returns false because it was canceled
@ -649,7 +649,7 @@ describe('Integration', () => {
router.events.forEach(e => recordedEvents.push(e));
let e: any;
router.navigateByUrl('/invalid').catch(_ => e = _);
router.navigateByUrl('/invalid') !.catch(_ => e = _);
advance(fixture);
expect(e.message).toContain('Cannot match any routes');
@ -676,7 +676,7 @@ describe('Integration', () => {
router.events.forEach(e => recordedEvents.push(e));
let e: any;
router.navigateByUrl('/invalid').then(_ => e = _);
router.navigateByUrl('/invalid') !.then(_ => e = _);
advance(fixture);
expect(e).toEqual('resolvedValue');
@ -910,7 +910,7 @@ describe('Integration', () => {
router.events.subscribe(e => recordedEvents.push(e));
let e: any = null;
router.navigateByUrl('/simple').catch(error => e = error);
router.navigateByUrl('/simple') !.catch(error => e = error);
advance(fixture);
expectEvents(recordedEvents, [
@ -1687,7 +1687,7 @@ describe('Integration', () => {
{
provide: 'RecordingDeactivate',
useValue: (c: any, a: ActivatedRouteSnapshot, b: RouterStateSnapshot) => {
log.push({path: a.routeConfig.path, component: c});
log.push({path: a.routeConfig !.path, component: c});
return true;
}
},
@ -1735,14 +1735,14 @@ describe('Integration', () => {
advance(fixture);
expect(location.path()).toEqual('/team/22');
let successStatus: boolean;
router.navigateByUrl('/team/33').then(res => successStatus = res);
let successStatus: boolean = false;
router.navigateByUrl('/team/33') !.then(res => successStatus = res);
advance(fixture);
expect(location.path()).toEqual('/team/33');
expect(successStatus).toEqual(true);
let canceledStatus: boolean;
router.navigateByUrl('/team/44').then(res => canceledStatus = res);
let canceledStatus: boolean = false;
router.navigateByUrl('/team/44') !.then(res => canceledStatus = res);
advance(fixture);
expect(location.path()).toEqual('/team/33');
expect(canceledStatus).toEqual(false);
@ -2072,7 +2072,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/team/22');
router.navigateByUrl('/team/33').catch(() => {});
router.navigateByUrl('/team/33') !.catch(() => {});
advance(fixture);
expect(location.path()).toEqual('/team/22');
@ -2582,8 +2582,8 @@ describe('Integration', () => {
expect(location.path()).toEqual('/lazy/parent/child');
expect(fixture.nativeElement).toHaveText('parent[child]');
const pInj = fixture.debugElement.query(By.directive(Parent)).injector;
const cInj = fixture.debugElement.query(By.directive(Child)).injector;
const pInj = fixture.debugElement.query(By.directive(Parent)).injector !;
const cInj = fixture.debugElement.query(By.directive(Child)).injector !;
expect(pInj.get('moduleName')).toEqual('parent');
expect(pInj.get('fromParent')).toEqual('from parent');
@ -2769,7 +2769,7 @@ describe('Integration', () => {
router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]);
let recordedError: any = null;
router.navigateByUrl('/lazy/loaded').catch(err => recordedError = err);
router.navigateByUrl('/lazy/loaded') !.catch(err => recordedError = err);
advance(fixture);
expect(recordedError.message)
.toEqual(
@ -2942,7 +2942,7 @@ describe('Integration', () => {
const recordedEvents: any[] = [];
router.events.forEach(e => recordedEvents.push(e));
router.navigateByUrl('/lazy/loaded').catch(s => {});
router.navigateByUrl('/lazy/loaded') !.catch(s => {});
advance(fixture);
expect(location.path()).toEqual('/');
@ -3206,19 +3206,19 @@ describe('Integration', () => {
stored: {[k: string]: DetachedRouteHandle} = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return route.routeConfig.path === 'a';
return route.routeConfig !.path === 'a';
}
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {
this.stored[route.routeConfig.path] = detachedTree;
this.stored[route.routeConfig !.path !] = detachedTree;
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!this.stored[route.routeConfig.path];
return !!this.stored[route.routeConfig !.path !];
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
return this.stored[route.routeConfig.path];
return this.stored[route.routeConfig !.path !];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
@ -3230,7 +3230,7 @@ describe('Integration', () => {
shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null !; }
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
if (future.routeConfig !== curr.routeConfig) {
return false;

View File

@ -16,14 +16,14 @@ describe('recognize', () => {
it('should work', () => {
checkRecognize([{path: 'a', component: ComponentA}], 'a', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.root, '', {}, RootComponent);
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
});
});
it('should freeze params object', () => {
checkRecognize([{path: 'a/:id', component: ComponentA}], 'a/10', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.root, '', {}, RootComponent);
const child = s.firstChild(s.root);
const child = s.firstChild(s.root) !;
expect(Object.isFrozen(child.params)).toBeTruthy();
});
});
@ -79,11 +79,11 @@ describe('recognize', () => {
expect(s.root._urlSegment).toBe(url.root);
expect(s.root._lastPathIndex).toBe(-1);
const compA = s.firstChild(s.root);
const compA = s.firstChild(s.root) !;
expect(compA._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(compA._lastPathIndex).toBe(1);
const compC = s.firstChild(<any>compA);
const compC = s.firstChild(<any>compA) !;
expect(compC._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(compC._lastPathIndex).toBe(2);
});
@ -101,11 +101,11 @@ describe('recognize', () => {
expect(s.root._urlSegment).toBe(url.root);
expect(s.root._lastPathIndex).toBe(-1);
const compA = s.firstChild(s.root);
const compA = s.firstChild(s.root) !;
expect(compA._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(compA._lastPathIndex).toBe(0);
const compC = s.firstChild(<any>compA);
const compC = s.firstChild(<any>compA) !;
expect(compC._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(compC._lastPathIndex).toBe(2);
});
@ -119,16 +119,16 @@ describe('recognize', () => {
],
'a/paramA', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.root, '', {}, RootComponent);
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
checkActivatedRoute(
s.firstChild(<any>s.firstChild(s.root)), 'paramA', {id: 'paramA'}, ComponentB);
s.firstChild(<any>s.firstChild(s.root)) !, 'paramA', {id: 'paramA'}, ComponentB);
});
checkRecognize(
[{path: 'a', component: ComponentA}, {path: 'a/:id', component: ComponentC}], 'a/paramA',
(s: RouterStateSnapshot) => {
checkActivatedRoute(s.root, '', {}, RootComponent);
checkActivatedRoute(s.firstChild(s.root), 'a/paramA', {id: 'paramA'}, ComponentC);
checkActivatedRoute(s.firstChild(s.root) !, 'a/paramA', {id: 'paramA'}, ComponentC);
});
});
@ -187,7 +187,7 @@ describe('recognize', () => {
'a;a1=11;a2=22/b;b1=111;b2=222(left:c;c1=1111;c2=2222)', (s: RouterStateSnapshot) => {
const c = s.children(s.root);
checkActivatedRoute(c[0], 'a', {a1: '11', a2: '22'}, ComponentA);
checkActivatedRoute(s.firstChild(<any>c[0]), 'b', {b1: '111', b2: '222'}, ComponentB);
checkActivatedRoute(s.firstChild(<any>c[0]) !, 'b', {b1: '111', b2: '222'}, ComponentB);
checkActivatedRoute(c[1], 'c', {c1: '1111', c2: '2222'}, ComponentC, 'left');
});
});
@ -196,7 +196,7 @@ describe('recognize', () => {
it('should set static data', () => {
checkRecognize(
[{path: 'a', data: {one: 1}, component: ComponentA}], 'a', (s: RouterStateSnapshot) => {
const r: ActivatedRouteSnapshot = s.firstChild(s.root);
const r: ActivatedRouteSnapshot = s.firstChild(s.root) !;
expect(r.data).toEqual({one: 1});
});
});
@ -209,7 +209,7 @@ describe('recognize', () => {
children: [{path: 'b', data: {two: 2}, component: ComponentB}]
}],
'a/b', (s: RouterStateSnapshot) => {
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root));
const r: ActivatedRouteSnapshot = s.firstChild(<any>s.firstChild(s.root)) !;
expect(r.data).toEqual({one: 1, two: 2});
});
});
@ -218,7 +218,7 @@ describe('recognize', () => {
checkRecognize(
[{path: 'a', resolve: {one: 'some-token'}, component: ComponentA}], 'a',
(s: RouterStateSnapshot) => {
const r: ActivatedRouteSnapshot = s.firstChild(s.root);
const r: ActivatedRouteSnapshot = s.firstChild(s.root) !;
expect(r._resolve).toEqual({one: 'some-token'});
});
});
@ -228,7 +228,7 @@ describe('recognize', () => {
describe('root', () => {
it('should work', () => {
checkRecognize([{path: '', component: ComponentA}], '', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), '', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, '', {}, ComponentA);
});
});
@ -236,7 +236,7 @@ describe('recognize', () => {
checkRecognize(
[{path: '', pathMatch: 'full', component: ComponentA}], '',
(s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), '', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, '', {}, ComponentA);
});
});
@ -244,8 +244,8 @@ describe('recognize', () => {
checkRecognize(
[{path: '', component: ComponentA, children: [{path: '', component: ComponentB}]}], '',
(s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), '', {}, ComponentA);
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)), '', {}, ComponentB);
checkActivatedRoute(s.firstChild(s.root) !, '', {}, ComponentA);
checkActivatedRoute(s.firstChild(<any>s.firstChild(s.root)) !, '', {}, ComponentB);
});
});
@ -259,11 +259,11 @@ describe('recognize', () => {
expect(s.root._urlSegment).toBe(url.root);
expect(s.root._lastPathIndex).toBe(-1);
const c = s.firstChild(s.root);
const c = s.firstChild(s.root) !;
expect(c._urlSegment).toBe(url.root);
expect(c._lastPathIndex).toBe(-1);
const c2 = s.firstChild(<any>s.firstChild(s.root));
const c2 = s.firstChild(<any>s.firstChild(s.root)) !;
expect(c2._urlSegment).toBe(url.root);
expect(c2._lastPathIndex).toBe(-1);
});
@ -279,10 +279,10 @@ describe('recognize', () => {
]
}],
'/a;p=1', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {p: '1'}, ComponentA);
checkActivatedRoute(s.firstChild(s.firstChild(s.root)), '', {p: '1'}, ComponentB);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {p: '1'}, ComponentA);
checkActivatedRoute(s.firstChild(s.firstChild(s.root) !) !, '', {p: '1'}, ComponentB);
checkActivatedRoute(
s.firstChild(s.firstChild(s.firstChild(s.root))), '', {p: '1'}, ComponentC);
s.firstChild(s.firstChild(s.firstChild(s.root) !) !) !, '', {p: '1'}, ComponentC);
});
});
});
@ -299,9 +299,9 @@ describe('recognize', () => {
]
}],
'a/b', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
const c = s.children(s.firstChild(s.root));
const c = s.children(s.firstChild(s.root) !);
checkActivatedRoute(c[0], 'b', {}, ComponentB);
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
});
@ -330,13 +330,13 @@ describe('recognize', () => {
checkRecognize(config, 'parent/b', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.root, '', {}, RootComponent);
checkActivatedRoute(s.firstChild(s.root), 'parent', {}, undefined);
checkActivatedRoute(s.firstChild(s.root) !, 'parent', {}, undefined !);
const cc = s.children(s.firstChild(s.root));
const cc = s.children(s.firstChild(s.root) !);
checkActivatedRoute(cc[0], '', {}, ComponentA);
checkActivatedRoute(cc[1], '', {}, ComponentD, 'secondary');
checkActivatedRoute(s.firstChild(cc[0]), 'b', {}, ComponentB);
checkActivatedRoute(s.firstChild(cc[0]) !, 'b', {}, ComponentB);
});
});
@ -351,9 +351,9 @@ describe('recognize', () => {
]
}],
'a/b', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
const c = s.children(s.firstChild(s.root));
const c = s.children(s.firstChild(s.root) !);
expect(c.length).toEqual(1);
checkActivatedRoute(c[0], 'b', {}, ComponentB);
});
@ -375,11 +375,11 @@ describe('recognize', () => {
expect(s.root._urlSegment).toBe(url.root);
expect(s.root._lastPathIndex).toBe(-1);
const a = s.firstChild(s.root);
const a = s.firstChild(s.root) !;
expect(a._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(a._lastPathIndex).toBe(0);
const b = s.firstChild(a);
const b = s.firstChild(a) !;
expect(b._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(b._lastPathIndex).toBe(1);
@ -403,15 +403,15 @@ describe('recognize', () => {
expect(s.root._urlSegment).toBe(url.root);
expect(s.root._lastPathIndex).toBe(-1);
const a = s.firstChild(s.root);
const a = s.firstChild(s.root) !;
expect(a._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(a._lastPathIndex).toBe(0);
const b = s.firstChild(a);
const b = s.firstChild(a) !;
expect(b._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(b._lastPathIndex).toBe(0);
const c = s.firstChild(b);
const c = s.firstChild(b) !;
expect(c._urlSegment).toBe(url.root.children[PRIMARY_OUTLET]);
expect(c._lastPathIndex).toBe(0);
});
@ -431,15 +431,15 @@ describe('recognize', () => {
expect(s.root._urlSegment).toBe(url.root);
expect(s.root._lastPathIndex).toBe(-1);
const a = s.firstChild(s.root);
const a = s.firstChild(s.root) !;
expect(a._urlSegment).toBe(url.root);
expect(a._lastPathIndex).toBe(-1);
const b = s.firstChild(a);
const b = s.firstChild(a) !;
expect(b._urlSegment).toBe(url.root);
expect(b._lastPathIndex).toBe(-1);
const c = s.firstChild(b);
const c = s.firstChild(b) !;
expect(c._urlSegment).toBe(url.root);
expect(c._lastPathIndex).toBe(-1);
});
@ -458,9 +458,9 @@ describe('recognize', () => {
]
}],
'a', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
const c = s.children(s.firstChild(s.root));
const c = s.children(s.firstChild(s.root) !);
checkActivatedRoute(c[0], '', {}, ComponentB);
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
});
@ -477,9 +477,9 @@ describe('recognize', () => {
]
}],
'a', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
const c = s.children(s.firstChild(s.root));
const c = s.children(s.firstChild(s.root) !);
checkActivatedRoute(c[0], '', {}, ComponentB);
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
});
@ -496,9 +496,9 @@ describe('recognize', () => {
]
}],
'a/(aux:c)', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
const c = s.children(s.firstChild(s.root));
const c = s.children(s.firstChild(s.root) !);
checkActivatedRoute(c[0], '', {}, ComponentB);
checkActivatedRoute(c[1], 'c', {}, ComponentC, 'aux');
});
@ -538,13 +538,13 @@ describe('recognize', () => {
]
}],
'a/(d//aux:e)', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a', {}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a', {}, ComponentA);
const c = s.children(s.firstChild(s.root));
const c = s.children(s.firstChild(s.root) !);
checkActivatedRoute(c[0], '', {}, ComponentB);
checkActivatedRoute(s.firstChild(c[0]), 'd', {}, ComponentD);
checkActivatedRoute(s.firstChild(c[0]) !, 'd', {}, ComponentD);
checkActivatedRoute(c[1], '', {}, ComponentC, 'aux');
checkActivatedRoute(s.firstChild(c[1]), 'e', {}, ComponentE);
checkActivatedRoute(s.firstChild(c[1]) !, 'e', {}, ComponentE);
});
});
});
@ -554,7 +554,7 @@ describe('recognize', () => {
it('should support simple wildcards', () => {
checkRecognize(
[{path: '**', component: ComponentA}], 'a/b/c/d;a1=11', (s: RouterStateSnapshot) => {
checkActivatedRoute(s.firstChild(s.root), 'a/b/c/d', {a1: '11'}, ComponentA);
checkActivatedRoute(s.firstChild(s.root) !, 'a/b/c/d', {a1: '11'}, ComponentA);
});
});
});
@ -570,8 +570,8 @@ describe('recognize', () => {
]
}],
'p/11;pp=22/(a;pa=33//aux:b;pb=44)', (s: RouterStateSnapshot) => {
const p = s.firstChild(s.root);
checkActivatedRoute(p, 'p/11', {id: '11', pp: '22'}, undefined);
const p = s.firstChild(s.root) !;
checkActivatedRoute(p, 'p/11', {id: '11', pp: '22'}, undefined !);
const c = s.children(p);
checkActivatedRoute(c[0], 'a', {id: '11', pp: '22', pa: '33'}, ComponentA);
@ -593,16 +593,16 @@ describe('recognize', () => {
}]
}],
'p/11/a/victor/b/c', (s: RouterStateSnapshot) => {
const p = s.firstChild(s.root);
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined);
const p = s.firstChild(s.root) !;
checkActivatedRoute(p, 'p/11', {id: '11'}, undefined !);
const a = s.firstChild(p);
checkActivatedRoute(a, 'a/victor', {id: '11', name: 'victor'}, undefined);
const a = s.firstChild(p) !;
checkActivatedRoute(a, 'a/victor', {id: '11', name: 'victor'}, undefined !);
const b = s.firstChild(a);
const b = s.firstChild(a) !;
checkActivatedRoute(b, 'b', {id: '11', name: 'victor'}, ComponentB);
const c = s.firstChild(b);
const c = s.firstChild(b) !;
checkActivatedRoute(c, 'c', {}, ComponentC);
});
});
@ -614,7 +614,7 @@ describe('recognize', () => {
[{path: 'a', component: ComponentA, children: [{path: 'b', component: ComponentB}]}],
'/a', (s: RouterStateSnapshot) => {
const a = s.firstChild(s.root);
checkActivatedRoute(a, 'a', {}, ComponentA);
checkActivatedRoute(a !, 'a', {}, ComponentA);
});
});
@ -629,7 +629,7 @@ describe('recognize', () => {
]
}],
'/a', (s: RouterStateSnapshot) => {
const a = s.firstChild(s.root);
const a = s.firstChild(s.root) !;
checkActivatedRoute(a, 'a', {}, ComponentA);
checkActivatedRoute(a.children[0], '', {}, ComponentC, 'aux');
});
@ -651,11 +651,11 @@ describe('recognize', () => {
matcher: matcher,
component: ComponentA,
children: [{path: 'b', component: ComponentB}]
}],
}] as any,
'/a/1;p=99/b', (s: RouterStateSnapshot) => {
const a = s.root.firstChild;
const a = s.root.firstChild !;
checkActivatedRoute(a, 'a/1', {id: '1', p: '99'}, ComponentA);
checkActivatedRoute(a.firstChild, 'b', {}, ComponentB);
checkActivatedRoute(a.firstChild !, 'b', {}, ComponentB);
});
});
});

View File

@ -57,7 +57,7 @@ describe('Router', () => {
const inj = {get: (token: any) => () => `${token}_value`};
let empty: RouterStateSnapshot;
beforeEach(() => { empty = createEmptyStateSnapshot(serializer.parse('/'), null); });
beforeEach(() => { empty = createEmptyStateSnapshot(serializer.parse('/'), null !); });
it('should resolve data', () => {
const r = {data: 'resolver'};
@ -65,7 +65,7 @@ describe('Router', () => {
const s = new RouterStateSnapshot('url', new TreeNode(empty.root, [new TreeNode(n, [])]));
checkResolveData(s, empty, inj, () => {
expect(s.root.firstChild.data).toEqual({data: 'resolver_value'});
expect(s.root.firstChild !.data).toEqual({data: 'resolver_value'});
});
});
@ -73,7 +73,7 @@ describe('Router', () => {
const parentResolve = {data: 'resolver'};
const childResolve = {};
const parent = createActivatedRouteSnapshot(null, {resolve: parentResolve});
const parent = createActivatedRouteSnapshot(null !, {resolve: parentResolve});
const child = createActivatedRouteSnapshot('b', {resolve: childResolve});
const s = new RouterStateSnapshot(
@ -82,7 +82,7 @@ describe('Router', () => {
const inj = {get: (token: any) => () => Promise.resolve(`${token}_value`)};
checkResolveData(s, empty, inj, () => {
expect(s.root.firstChild.firstChild.data).toEqual({data: 'resolver_value'});
expect(s.root.firstChild !.firstChild !.data).toEqual({data: 'resolver_value'});
});
});
@ -99,8 +99,8 @@ describe('Router', () => {
const s2 = new RouterStateSnapshot(
'url', new TreeNode(empty.root, [new TreeNode(n21, [new TreeNode(n22, [])])]));
checkResolveData(s2, s1, inj, () => {
expect(s2.root.firstChild.data).toEqual({data: 'resolver1_value'});
expect(s2.root.firstChild.firstChild.data).toEqual({data: 'resolver2_value'});
expect(s2.root.firstChild !.data).toEqual({data: 'resolver1_value'});
expect(s2.root.firstChild !.firstChild !.data).toEqual({data: 'resolver2_value'});
});
});
});

View File

@ -39,17 +39,17 @@ describe('RouterState & Snapshot', () => {
});
it('should return root', () => {
const b = state.root.firstChild;
const b = state.root.firstChild !;
expect(b.root).toBe(state.root);
});
it('should return parent', () => {
const b = state.root.firstChild;
const b = state.root.firstChild !;
expect(b.parent).toBe(state.root);
});
it('should return path from root', () => {
const b = state.root.firstChild;
const b = state.root.firstChild !;
const p = b.pathFromRoot;
expect(p[0]).toBe(state.root);
expect(p[1]).toBe(b);
@ -81,17 +81,17 @@ describe('RouterState & Snapshot', () => {
});
it('should return root', () => {
const b = state.root.firstChild;
const b = state.root.firstChild !;
expect(b.root).toBe(state.root);
});
it('should return parent', () => {
const b = state.root.firstChild;
const b = state.root.firstChild !;
expect(b.parent).toBe(state.root);
});
it('should return path from root', () => {
const b = state.root.firstChild;
const b = state.root.firstChild !;
const p = b.pathFromRoot;
expect(p[0]).toBe(state.root);
expect(p[1]).toBe(b);
@ -102,7 +102,7 @@ describe('RouterState & Snapshot', () => {
function createSnapshot(params: Params, url: UrlSegment[]): ActivatedRouteSnapshot {
const snapshot = new ActivatedRouteSnapshot(
url, params, <any>null, <any>null, <any>null, <any>null, <any>null, <any>null, <any>null,
-1, null);
-1, null !);
snapshot._routerState = new RouterStateSnapshot('', new TreeNode(snapshot, []));
return snapshot;
}
@ -177,7 +177,7 @@ describe('RouterState & Snapshot', () => {
const data = {};
const snapshot = new ActivatedRouteSnapshot(
url, params, queryParams, fragment, data, <any>null, <any>null, <any>null, <any>null, -1,
null);
null !);
const state = new RouterStateSnapshot('', new TreeNode(snapshot, []));
snapshot._routerState = state;
return snapshot;
@ -200,7 +200,7 @@ describe('RouterState & Snapshot', () => {
function createActivatedRouteSnapshot(cmp: string) {
return new ActivatedRouteSnapshot(
<any>null, <any>null, <any>null, <any>null, <any>null, <any>null, <any>cmp, <any>null,
<any>null, -1, null);
<any>null, -1, null !);
}
function createActivatedRoute(cmp: string) {

View File

@ -86,7 +86,7 @@ export function setupTestingRouter(
loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector, routes: Route[][],
urlHandlingStrategy?: UrlHandlingStrategy) {
const router = new Router(
null, urlSerializer, outletMap, location, injector, loader, compiler, flatten(routes));
null !, urlSerializer, outletMap, location, injector, loader, compiler, flatten(routes));
if (urlHandlingStrategy) {
router.urlHandlingStrategy = urlHandlingStrategy;
}

View File

@ -10,6 +10,7 @@
"noEmitOnError": false,
"noImplicitAny": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"outDir": "../../dist/packages/router",
"paths": {
"@angular/core": ["../../dist/packages/core"],

View File

@ -1,19 +1,19 @@
/** @stable */
export declare class ActivatedRoute {
readonly children: ActivatedRoute[];
component: Type<any> | string;
component: Type<any> | string | null;
data: Observable<Data>;
readonly firstChild: ActivatedRoute;
readonly firstChild: ActivatedRoute | null;
fragment: Observable<string>;
outlet: string;
readonly paramMap: Observable<ParamMap>;
params: Observable<Params>;
readonly parent: ActivatedRoute;
readonly parent: ActivatedRoute | null;
readonly pathFromRoot: ActivatedRoute[];
readonly queryParamMap: Observable<ParamMap>;
queryParams: Observable<Params>;
readonly root: ActivatedRoute;
readonly routeConfig: Route;
readonly routeConfig: Route | null;
snapshot: ActivatedRouteSnapshot;
url: Observable<UrlSegment[]>;
toString(): string;
@ -22,19 +22,19 @@ export declare class ActivatedRoute {
/** @stable */
export declare class ActivatedRouteSnapshot {
readonly children: ActivatedRouteSnapshot[];
component: Type<any> | string;
component: Type<any> | string | null;
data: Data;
readonly firstChild: ActivatedRouteSnapshot;
readonly firstChild: ActivatedRouteSnapshot | null;
fragment: string;
outlet: string;
readonly paramMap: ParamMap;
params: Params;
readonly parent: ActivatedRouteSnapshot;
readonly parent: ActivatedRouteSnapshot | null;
readonly pathFromRoot: ActivatedRouteSnapshot[];
readonly queryParamMap: ParamMap;
queryParams: Params;
readonly root: ActivatedRouteSnapshot;
readonly routeConfig: Route;
readonly routeConfig: Route | null;
url: UrlSegment[];
toString(): string;
}
@ -239,7 +239,7 @@ export declare class Router {
readonly routerState: RouterState;
readonly url: string;
urlHandlingStrategy: UrlHandlingStrategy;
constructor(rootComponentType: Type<any>, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes);
constructor(rootComponentType: Type<any> | null, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes);
createUrlTree(commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling, preserveFragment}?: NavigationExtras): UrlTree;
dispose(): void;
initialNavigation(): void;
@ -261,11 +261,11 @@ export declare const ROUTER_INITIALIZER: InjectionToken<(compRef: ComponentRef<a
/** @experimental */
export declare abstract class RouteReuseStrategy {
abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle;
abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null;
abstract shouldAttach(route: ActivatedRouteSnapshot): boolean;
abstract shouldDetach(route: ActivatedRouteSnapshot): boolean;
abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean;
abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void;
abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void;
}
/** @stable */
@ -424,7 +424,7 @@ export declare class UrlSegmentGroup {
[key: string]: UrlSegmentGroup;
};
readonly numberOfChildren: number;
parent: UrlSegmentGroup;
parent: UrlSegmentGroup | null;
segments: UrlSegment[];
constructor(
segments: UrlSegment[],
@ -443,7 +443,7 @@ export declare abstract class UrlSerializer {
/** @stable */
export declare class UrlTree {
fragment: string;
fragment: string | null;
readonly queryParamMap: ParamMap;
queryParams: {
[key: string]: string;