Skip to content

Commit 2124eb2

Browse files
committed
Fix url rule types
1 parent fccb1c7 commit 2124eb2

8 files changed

Lines changed: 91 additions & 46 deletions

File tree

@types/router/state/state-object.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export namespace StateObject {
124124
obj: StateObject | import("../state/interface.js").StateDeclaration,
125125
): boolean;
126126
/** Predicate which returns true if the object is an internal [[StateObject]] object */
127-
function isState(obj: { _stateObjectCache: any }): boolean;
127+
function isState(obj: any): boolean;
128128
}
129129
export type Param = import("../params/param.js").Param;
130130
export type Resolvable = import("../resolve/resolvable.js").Resolvable;

@types/router/state/state-service.d.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -418,20 +418,15 @@ export class StateProvider {
418418
* ```js
419419
* expect($state.href("about.person", { person: "bob" })).toEqual("/about/bob");
420420
* ```
421-
* @param {any} stateOrName The state name or state object you'd like to generate a url from.
422-
* @param {Object} params An object of parameter values to fill the state's required parameters.
423-
* @param {{ relative: any; inherit: any; lossy: any; absolute: any; }} options Options object. The options are:
421+
* @param {import("./state-matcher.js").StateOrName} stateOrName The state name or state object you'd like to generate a url from.
422+
* @param {import("../params/interface.ts").RawParams} params An object of parameter values to fill the state's required parameters.
423+
* @param {import("./interface.ts").HrefOptions} [options] Options object. The options are:
424424
* @returns {string} compiled state url
425425
*/
426426
href(
427-
stateOrName: any,
428-
params: any,
429-
options: {
430-
relative: any;
431-
inherit: any;
432-
lossy: any;
433-
absolute: any;
434-
},
427+
stateOrName: import("./state-matcher.js").StateOrName,
428+
params: import("../params/interface.ts").RawParams,
429+
options?: import("./interface.ts").HrefOptions,
435430
): string;
436431
/**
437432
* Sets or gets the default [[transitionTo]] error handler.

@types/router/url/interface.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface MatchResult {
4141
* @return the matched value, either truthy or falsey
4242
*/
4343
export interface UrlRuleMatchFn {
44-
(url?: UrlParts, router?: ng.RouterService): any;
44+
(url: UrlParts, router?: ng.RouterService): any;
4545
}
4646
/**
4747
* Handler invoked when a rule is matched

@types/router/url/url-rule.d.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,17 @@ export class UrlRuleFactory {
116116
* var match = rule.match('/foo/bar'); // results in [ '/foo/bar', 'bar' ]
117117
* var result = rule.handler(match); // '/home/bar'
118118
* ```
119+
* @param {RegExp} regexp
120+
* @param {string | import("./interface.js").UrlRuleHandlerFn} handler
121+
* @returns {import("./interface.js").RegExpRule}
119122
*/
120123
fromRegExp(
121-
regexp: any,
122-
handler: any,
123-
): BaseUrlRule & {
124-
regexp: any;
125-
type: string;
126-
};
124+
regexp: RegExp,
125+
handler: string | import("./interface.js").UrlRuleHandlerFn,
126+
): import("./interface.js").RegExpRule;
127127
}
128128
export namespace UrlRuleFactory {
129-
function isUrlRule(obj: any): boolean;
129+
function isUrlRule(obj: { [x: string]: any }): boolean;
130130
}
131131
/**
132132
* A base rule which calls `match`
@@ -155,9 +155,9 @@ export class BaseUrlRule {
155155
*/
156156
$id: number;
157157
/**
158-
* @type {string | undefined}
158+
* @type {number | undefined}
159159
*/
160-
_group: string | undefined;
160+
_group: number | undefined;
161161
/**
162162
* @type {import("./interface.js").UrlRuleHandlerFn}
163163
*/

src/router/state/state-object.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,5 @@ StateObject.isStateDeclaration = (
182182
) => isFunction(obj._state);
183183

184184
/** Predicate which returns true if the object is an internal [[StateObject]] object */
185-
StateObject.isState = (/** @type {{ _stateObjectCache: any; }} */ obj) =>
185+
StateObject.isState = (/** @type {any} */ obj) =>
186186
isObject(obj._stateObjectCache);

src/router/state/state-service.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,9 @@ export class StateProvider {
720720
* ```js
721721
* expect($state.href("about.person", { person: "bob" })).toEqual("/about/bob");
722722
* ```
723-
* @param {any} stateOrName The state name or state object you'd like to generate a url from.
724-
* @param {Object} params An object of parameter values to fill the state's required parameters.
725-
* @param {{ relative: any; inherit: any; lossy: any; absolute: any; }} options Options object. The options are:
723+
* @param {import("./state-matcher.js").StateOrName} stateOrName The state name or state object you'd like to generate a url from.
724+
* @param {import("../params/interface.ts").RawParams} params An object of parameter values to fill the state's required parameters.
725+
* @param {import("./interface.ts").HrefOptions} [options] Options object. The options are:
726726
* @returns {string} compiled state url
727727
*/
728728
href(stateOrName, params, options) {

src/router/url/interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export interface MatchResult {
4545
* @return the matched value, either truthy or falsey
4646
*/
4747
export interface UrlRuleMatchFn {
48-
(url?: UrlParts, router?: ng.RouterService): any;
48+
(url: UrlParts, router?: ng.RouterService): any;
4949
}
5050

5151
/**

src/router/url/url-rule.js

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ export class UrlRuleFactory {
5858
(/** @type {any} */ _what) => this.fromUrlMatcher(_what, handler),
5959
],
6060
[
61-
(...args) => isState(...args) || isStateDeclaration(...args),
61+
(/** @type {any} */ _what) =>
62+
isState(_what) || isStateDeclaration(_what),
6263
(/** @type {any} */ _what) =>
6364
this.fromState(_what, this.stateService, this.routerGlobals),
6465
],
@@ -124,16 +125,31 @@ export class UrlRuleFactory {
124125

125126
if (isString(handler)) handler = this.urlService.compile(handler);
126127

127-
if (is(UrlMatcher)(handler))
128-
_handler = (match) => /** @type {UrlMatcher} */ (handler).format(match);
128+
if (is(UrlMatcher)(handler)) {
129+
const matcher = /** @type {UrlMatcher} */ (handler);
130+
131+
_handler = (match) => {
132+
const url = matcher.format(match); // string | null
133+
134+
return url === null ? undefined : url; // string | void
135+
};
136+
}
129137
/**
130138
* @param {import("./interface.js").UrlParts} url
131-
* @returns {import("../params/interface.js").RawParams}
139+
* @returns {import("../params/interface.js").RawParams | boolean | null}
132140
*/
133141
function matchUrlParamters(url) {
134-
const params = urlMatcher.exec(url.path, url.search, url.hash);
142+
const params = urlMatcher.exec(
143+
url.path,
144+
url.search,
145+
/** @type {string} */ (url.hash),
146+
);
135147

136-
return urlMatcher.validates(params) && params;
148+
return (
149+
urlMatcher.validates(
150+
/** @type {import("../params/interface.js").RawParams} */ (params),
151+
) && params
152+
);
137153
}
138154
// Prioritize URLs, lowest to highest:
139155
// - Some optional URL parameters, but none matched
@@ -154,9 +170,18 @@ export class UrlRuleFactory {
154170

155171
return matched.length / optional.length;
156172
}
173+
/** @type {{ urlMatcher: UrlMatcher; matchPriority: (params: import("../params/interface.js").RawParams) => number; type: "URLMATCHER" }} */
157174
const details = { urlMatcher, matchPriority, type: "URLMATCHER" };
158175

159-
return Object.assign(new BaseUrlRule(matchUrlParamters, _handler), details);
176+
return /** @type {import("./interface.js").MatcherUrlRule} */ (
177+
Object.assign(
178+
new BaseUrlRule(
179+
matchUrlParamters,
180+
/** @type {import("./interface.js").UrlRuleHandlerFn} */ (_handler),
181+
),
182+
details,
183+
)
184+
);
160185
}
161186

162187
/**
@@ -176,7 +201,7 @@ export class UrlRuleFactory {
176201
*/
177202
fromState(stateOrDecl, stateService, globals) {
178203
const state = StateObject.isStateDeclaration(stateOrDecl)
179-
? stateOrDecl._state()
204+
? /** @type {StateObject} */ (stateOrDecl)?._state()
180205
: stateOrDecl;
181206

182207
/**
@@ -186,20 +211,32 @@ export class UrlRuleFactory {
186211
* A new transition is not required if the current state's URL
187212
* and the new URL are already identical
188213
*/
189-
const handler = (match) => {
214+
const handler = (
215+
/** @type {import("../params/interface.js").RawParams} */ match,
216+
) => {
190217
const $state = stateService;
191218

192219
if (
193220
$state.href(state, match) !==
194-
$state.href(globals.current, globals.params)
221+
$state.href(
222+
/** @type {import("../state/interface.js").StateDeclaration} */ (
223+
globals.current
224+
),
225+
globals.params,
226+
)
195227
) {
196228
$state.transitionTo(state, match, { inherit: true, source: "url" });
197229
}
198230
};
199231

200232
const details = { state, type: "STATE" };
201233

202-
return Object.assign(this.fromUrlMatcher(state.url, handler), details);
234+
return /** @type {import("./interface.js").StateRule} */ (
235+
Object.assign(
236+
this.fromUrlMatcher(/** @type {UrlMatcher} */ (state.url), handler),
237+
details,
238+
)
239+
);
203240
}
204241

205242
/**
@@ -233,6 +270,9 @@ export class UrlRuleFactory {
233270
* var match = rule.match('/foo/bar'); // results in [ '/foo/bar', 'bar' ]
234271
* var result = rule.handler(match); // '/home/bar'
235272
* ```
273+
* @param {RegExp} regexp
274+
* @param {string | import("./interface.js").UrlRuleHandlerFn} handler
275+
* @returns {import("./interface.js").RegExpRule}
236276
*/
237277
fromRegExp(regexp, handler) {
238278
if (regexp.global || regexp.sticky)
@@ -242,26 +282,36 @@ export class UrlRuleFactory {
242282
* If the string has any String.replace() style variables in it (like `$2`),
243283
* they will be replaced by the captures from [[match]]
244284
*/
245-
const redirectUrlTo = (match) =>
285+
const redirectUrlTo = (/** @type {RegExpExecArray} */ match) =>
246286
// Interpolates matched values into $1 $2, etc using a String.replace()-style pattern
247-
handler.replace(
287+
/** @type {string} */ (handler).replace(
248288
/\$(\$|\d{1,2})/,
249289
(_, what) => match[what === "$" ? 0 : Number(what)],
250290
);
251291

252292
const _handler = isString(handler) ? redirectUrlTo : handler;
253293

254-
const matchParamsFromRegexp = (url) => regexp.exec(url.path);
294+
const matchParamsFromRegexp = (
295+
/** @type {import("./interface.js").UrlParts} */ url,
296+
) => regexp.exec(url.path);
255297

256298
const details = { regexp, type: "REGEXP" };
257299

258-
return Object.assign(
259-
new BaseUrlRule(matchParamsFromRegexp, _handler),
260-
details,
300+
return /** @type {import("./interface.js").RegExpRule} */ (
301+
Object.assign(
302+
new BaseUrlRule(
303+
/** @type {import("./interface.js").UrlRuleMatchFn} */ (
304+
matchParamsFromRegexp
305+
),
306+
_handler,
307+
),
308+
details,
309+
)
261310
);
262311
}
263312
}
264-
UrlRuleFactory.isUrlRule = (obj) =>
313+
314+
UrlRuleFactory.isUrlRule = (/** @type {{ [x: string]: any; }} */ obj) =>
265315
obj && ["type", "match", "handler"].every((key) => isDefined(obj[key]));
266316

267317
/**
@@ -291,7 +341,7 @@ export class BaseUrlRule {
291341
this.$id = -1;
292342

293343
/**
294-
* @type {string | undefined}
344+
* @type {number | undefined}
295345
*/
296346
this._group = undefined;
297347

0 commit comments

Comments
 (0)