refactor: utilize type narrowing (#33075)

PR Close #33075
This commit is contained in:
Danny Skoog 2019-10-09 17:17:52 +02:00 committed by Miško Hevery
parent 1ae77da609
commit 6ab5f3648a
29 changed files with 73 additions and 80 deletions

View File

@ -15,7 +15,7 @@ export class HeroDetailService {
// Returns a clone which caller may modify safely
getHero(id: number | string): Observable<Hero> {
if (typeof id === 'string') {
id = parseInt(id as string, 10);
id = parseInt(id, 10);
}
return this.heroService.getHero(id).pipe(
map(hero => {

View File

@ -18,7 +18,7 @@ export class HeroService {
constructor(private http: HttpClient) { }
/** GET heroes from the server */
getHeroes (): Observable<Hero[]> {
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
tap(heroes => this.log(`fetched heroes`)),
@ -29,7 +29,7 @@ export class HeroService {
/** GET hero by id. Return `undefined` when id not found */
getHero<Data>(id: number | string): Observable<Hero> {
if (typeof id === 'string') {
id = parseInt(id as string, 10);
id = parseInt(id, 10);
}
const url = `${this.heroesUrl}/?id=${id}`;
return this.http.get<Hero[]>(url)
@ -46,14 +46,14 @@ export class HeroService {
//////// Save methods //////////
/** POST: add a new hero to the server */
addHero (hero: Hero): Observable<Hero> {
addHero(hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions).pipe(
tap((hero: Hero) => this.log(`added hero w/ id=${hero.id}`)),
tap((addedHero) => this.log(`added hero w/ id=${addedHero.id}`)),
catchError(this.handleError<Hero>('addHero'))
);
}
/** DELETE: delete the hero from the server */
deleteHero (hero: Hero | number): Observable<Hero> {
deleteHero(hero: Hero | number): Observable<Hero> {
const id = typeof hero === 'number' ? hero : hero.id;
const url = `${this.heroesUrl}/${id}`;
@ -64,7 +64,7 @@ export class HeroService {
}
/** PUT: update the hero on the server */
updateHero (hero: Hero): Observable<any> {
updateHero(hero: Hero): Observable<any> {
return this.http.put(this.heroesUrl, hero, httpOptions).pipe(
tap(_ => this.log(`updated hero id=${hero.id}`)),
catchError(this.handleError<any>('updateHero'))
@ -75,7 +75,7 @@ export class HeroService {
* This error handler lets the app continue to run as if no error occurred.
* @param operation - name of the operation that failed
*/
private handleError<T> (operation = 'operation') {
private handleError<T>(operation = 'operation') {
return (error: HttpErrorResponse): Observable<T> => {
// TODO: send the error to remote logging infrastructure

View File

@ -42,9 +42,9 @@ export class TestHeroService extends HeroService {
getHero(id: number | string): Observable<Hero> {
if (typeof id === 'string') {
id = parseInt(id as string, 10);
id = parseInt(id, 10);
}
let hero = this.heroes.find(h => h.id === id);
const hero = this.heroes.find(h => h.id === id);
return this.lastResult = asyncData(hero);
}

View File

@ -244,12 +244,12 @@ export class AnimationAstBuilderVisitor implements AnimationDslVisitor {
(metadata.styles as(ɵStyleData | string)[]).forEach(styleTuple => {
if (typeof styleTuple == 'string') {
if (styleTuple == AUTO_STYLE) {
styles.push(styleTuple as string);
styles.push(styleTuple);
} else {
context.errors.push(`The provided style string value ${styleTuple} is not allowed.`);
}
} else {
styles.push(styleTuple as ɵStyleData);
styles.push(styleTuple);
}
});
} else {
@ -518,7 +518,7 @@ function consumeOffset(styles: ɵStyleData | string | (ɵStyleData | string)[]):
}
});
} else if (isObject(styles) && styles.hasOwnProperty('offset')) {
const obj = styles as ɵStyleData;
const obj = styles;
offset = parseFloat(obj['offset'] as string);
delete obj['offset'];
}
@ -534,8 +534,8 @@ function constructTimingAst(value: string | number | AnimateTimings, errors: any
if (value.hasOwnProperty('duration')) {
timings = value as AnimateTimings;
} else if (typeof value == 'number') {
const duration = resolveTiming(value as number, errors).duration;
return makeTimingAst(duration as number, 0, '');
const duration = resolveTiming(value, errors).duration;
return makeTimingAst(duration, 0, '');
}
const strValue = value as string;

View File

@ -13,9 +13,8 @@ export function parseTransitionExpr(
transitionValue: string | TransitionMatcherFn, errors: string[]): TransitionMatcherFn[] {
const expressions: TransitionMatcherFn[] = [];
if (typeof transitionValue == 'string') {
(<string>transitionValue)
.split(/\s*,\s*/)
.forEach(str => parseInnerTransitionStr(str, expressions, errors));
transitionValue.split(/\s*,\s*/).forEach(
str => parseInnerTransitionStr(str, expressions, errors));
} else {
expressions.push(<TransitionMatcherFn>transitionValue);
}
@ -30,7 +29,7 @@ function parseInnerTransitionStr(
expressions.push(result);
return;
}
eventStr = result as string;
eventStr = result;
}
const match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);

View File

@ -1708,7 +1708,7 @@ function _flattenGroupPlayersRecur(players: AnimationPlayer[], finalPlayers: Ani
if (player instanceof AnimationGroupPlayer) {
_flattenGroupPlayersRecur(player.players, finalPlayers);
} else {
finalPlayers.push(player as AnimationPlayer);
finalPlayers.push(player);
}
}
}

View File

@ -26,7 +26,7 @@ export const NG_ANIMATING_SELECTOR = '.ng-animating';
export function resolveTimingValue(value: string | number) {
if (typeof value == 'number') return value;
const matches = (value as string).match(/^(-?[\.\d]+)(m?s)/);
const matches = value.match(/^(-?[\.\d]+)(m?s)/);
if (!matches || matches.length < 2) return 0;
return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
@ -73,7 +73,7 @@ function parseTimeExpression(
easing = easingVal;
}
} else {
duration = <number>exp;
duration = exp;
}
if (!allowNegativeValues) {
@ -214,10 +214,8 @@ const PARAM_REGEX =
export function extractStyleParams(value: string | number): string[] {
let params: string[] = [];
if (typeof value === 'string') {
const val = value.toString();
let match: any;
while (match = PARAM_REGEX.exec(val)) {
while (match = PARAM_REGEX.exec(value)) {
params.push(match[1] as string);
}
PARAM_REGEX.lastIndex = 0;

View File

@ -457,7 +457,7 @@ export class HttpClient {
if (first instanceof HttpRequest) {
// It is. The other arguments must be undefined (per the signatures) and can be
// ignored.
req = first as HttpRequest<any>;
req = first;
} else {
// It's a string, so it represents a URL. Construct a request based on it,
// and incorporate the remaining arguments (assuming `GET` unless a method is
@ -477,7 +477,7 @@ export class HttpClient {
if (options.params instanceof HttpParams) {
params = options.params;
} else {
params = new HttpParams({ fromObject: options.params } as HttpParamsOptions);
params = new HttpParams({fromObject: options.params});
}
}
@ -1798,7 +1798,7 @@ export class HttpClient {
}): Observable<Blob>;
/**
* Constructs a `PATCH` request that interprets the body as as a text string and
* Constructs a `PATCH` request that interprets the body as a text string and
* returns the response as a string value.
*
* @param url The endpoint URL.

View File

@ -94,9 +94,9 @@ export class NgLocaleLocalization extends NgLocalization {
export function getPluralCase(locale: string, nLike: number | string): Plural {
// TODO(vicb): lazy compute
if (typeof nLike === 'string') {
nLike = parseInt(<string>nLike, 10);
nLike = parseInt(nLike, 10);
}
const n: number = nLike as number;
const n: number = nLike;
const nDecimal = n.toString().replace(/^[^.]*\.?/, '');
const i = Math.floor(Math.abs(n));
const v = nDecimal.length;

View File

@ -50,7 +50,7 @@ function formatNumber(
}
}
return NumberFormatter.format(value as number, locale, style, {
return NumberFormatter.format(value, locale, style, {
minimumIntegerDigits: minInt,
minimumFractionDigits: minFraction,
maximumFractionDigits: maxFraction,

View File

@ -624,7 +624,7 @@ function findClassSymbolInContext(type: StaticSymbol, context: TypeContext): ts.
// This handles a case where an <packageName>/index.d.ts and a <packageName>/<packageName>.d.ts
// are in the same directory. If we are looking for <packageName>/<packageName> and didn't
// find it, look for <packageName>/index.d.ts as the program might have found that instead.
const p = type.filePath as string;
const p = type.filePath;
const m = p.match(INDEX_PATTERN);
if (m) {
const indexVersion = path.join(path.dirname(p), 'index.d.ts');

View File

@ -306,7 +306,7 @@ export class Evaluator {
error = propertyValue;
return true; // Stop the forEachChild.
} else {
obj[<string>propertyName] = isPropertyAssignment(assignment) ?
obj[propertyName] = isPropertyAssignment(assignment) ?
recordEntry(propertyValue, assignment.initializer) :
propertyValue;
}
@ -401,7 +401,7 @@ export class Evaluator {
return recordEntry(member, node);
}
if (expression && this.isFoldable(propertyAccessExpression.expression))
return (<any>expression)[<string>member];
return (<any>expression)[member];
if (isMetadataModuleReferenceExpression(expression)) {
// A select into a module reference and be converted into a reference to the symbol
// in the module

View File

@ -271,7 +271,7 @@ export function extractQueryMetadata(
} else if (typeof arg === 'string') {
predicate = [arg];
} else if (isStringArrayOrDie(arg, '@' + name)) {
predicate = arg as string[];
predicate = arg;
} else {
throw new FatalDiagnosticError(
ErrorCode.VALUE_HAS_WRONG_TYPE, node, `@${name} predicate cannot be interpreted`);

View File

@ -1012,18 +1012,19 @@ export class CompileMetadataResolver {
return;
} else {
const providersInfo =
(<string[]>providers.reduce(
(soFar: string[], seenProvider: any, seenProviderIdx: number) => {
if (seenProviderIdx < providerIdx) {
soFar.push(`${stringifyType(seenProvider)}`);
} else if (seenProviderIdx == providerIdx) {
soFar.push(`?${stringifyType(seenProvider)}?`);
} else if (seenProviderIdx == providerIdx + 1) {
soFar.push('...');
}
return soFar;
},
[]))
providers
.reduce(
(soFar: string[], seenProvider: any, seenProviderIdx: number) => {
if (seenProviderIdx < providerIdx) {
soFar.push(`${stringifyType(seenProvider)}`);
} else if (seenProviderIdx == providerIdx) {
soFar.push(`?${stringifyType(seenProvider)}?`);
} else if (seenProviderIdx == providerIdx + 1) {
soFar.push('...');
}
return soFar;
},
[])
.join(', ');
this._reportError(
syntaxError(

View File

@ -81,7 +81,7 @@ export function isNodeMatchingSelector(
const current = selector[i];
if (typeof current === 'number') {
// If we finish processing a :not selector and it hasn't failed, return false
if (!skipToNextSelector && !isPositive(mode) && !isPositive(current as number)) {
if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
return false;
}
// If we are skipping to the next :not() and this mode flag is positive,

View File

@ -195,7 +195,7 @@ class TQuery_ implements TQuery {
private matchTNode(tView: TView, tNode: TNode): void {
if (Array.isArray(this.metadata.predicate)) {
const localNames = this.metadata.predicate as string[];
const localNames = this.metadata.predicate;
for (let i = 0; i < localNames.length; i++) {
this.matchTNodeWithReadOption(tView, tNode, getIdxOfMatchingSelector(tNode, localNames[i]));
}

View File

@ -73,9 +73,8 @@ export function setUpAttributes(renderer: Renderer3, native: RElement, attrs: TA
}
} else {
isProc ?
(renderer as ProceduralRenderer3)
.setAttribute(native, attrName as string, attrVal as string) :
native.setAttribute(attrName as string, attrVal as string);
(renderer as ProceduralRenderer3).setAttribute(native, attrName, attrVal as string) :
native.setAttribute(attrName, attrVal as string);
}
i++;
}

View File

@ -424,7 +424,7 @@ export function normalizeIntoStylingMap(
if (props) {
for (let i = 0; i < props.length; i++) {
const prop = props[i] as string;
const prop = props[i];
const newProp = normalizeProps ? hyphenate(prop) : prop;
const value = allValuesTrue ? true : map ![prop];
addItemToStylingMap(stylingMapArr, newProp, value, true);

View File

@ -88,9 +88,8 @@ class SafeResourceUrlImpl extends SafeValueImpl implements SafeResourceUrl {
}
export function unwrapSafeValue(value: string | SafeValue): string {
return value instanceof SafeValueImpl ?
(value as SafeValueImpl).changingThisBreaksApplicationSecurity :
(value as string);
return value instanceof SafeValueImpl ? value.changingThisBreaksApplicationSecurity :
value as string;
}
@ -116,8 +115,7 @@ export function allowSanitizationBypassAndThrow(value: any, type: BypassType): b
}
export function getSanitizationBypassType(value: any): BypassType|null {
return value instanceof SafeValueImpl && (value as SafeValueImpl).getTypeName() as BypassType ||
null;
return value instanceof SafeValueImpl && value.getTypeName() as BypassType || null;
}
/**

View File

@ -45,7 +45,7 @@ export function asyncFallback(fn: Function): (done: any) => any {
}
runInTestZone(fn, this, done, (err: any) => {
if (typeof err === 'string') {
return done.fail(new Error(<string>err));
return done.fail(new Error(err));
} else {
done.fail(err);
}

View File

@ -48,11 +48,11 @@ function _find(control: AbstractControl, path: Array<string|number>| string, del
if (path == null) return null;
if (!(path instanceof Array)) {
path = (<string>path).split(delimiter);
path = path.split(delimiter);
}
if (path instanceof Array && (path.length === 0)) return null;
if (path instanceof Array && path.length === 0) return null;
return (<Array<string|number>>path).reduce((v: AbstractControl | null, name) => {
return path.reduce((v: AbstractControl | null, name) => {
if (v instanceof FormGroup) {
return v.controls.hasOwnProperty(name as string) ? v.controls[name] : null;
}

View File

@ -25,7 +25,7 @@ export abstract class Body {
*/
json(): any {
if (typeof this._body === 'string') {
return JSON.parse(<string>this._body);
return JSON.parse(this._body);
}
if (this._body instanceof ArrayBuffer) {
@ -57,9 +57,9 @@ export abstract class Body {
if (this._body instanceof ArrayBuffer) {
switch (encodingHint) {
case 'legacy':
return String.fromCharCode.apply(null, new Uint16Array(this._body as ArrayBuffer));
return String.fromCharCode.apply(null, new Uint16Array(this._body));
case 'iso-8859':
return String.fromCharCode.apply(null, new Uint8Array(this._body as ArrayBuffer));
return String.fromCharCode.apply(null, new Uint8Array(this._body));
default:
throw new Error(`Invalid value for encodingHint: ${encodingHint}`);
}
@ -81,7 +81,7 @@ export abstract class Body {
*/
arrayBuffer(): ArrayBuffer {
if (this._body instanceof ArrayBuffer) {
return <ArrayBuffer>this._body;
return this._body;
}
return stringToArrayBuffer(this.text());
@ -92,7 +92,7 @@ export abstract class Body {
*/
blob(): Blob {
if (this._body instanceof Blob) {
return <Blob>this._body;
return this._body;
}
if (this._body instanceof ArrayBuffer) {

View File

@ -118,7 +118,7 @@ export class Http {
if (typeof url === 'string') {
responseObservable = httpRequest(
this._backend,
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, <string>url)));
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, url)));
} else if (url instanceof Request) {
responseObservable = httpRequest(this._backend, url);
} else {
@ -215,8 +215,7 @@ export class Jsonp extends Http {
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
let responseObservable: any;
if (typeof url === 'string') {
url =
new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, <string>url));
url = new Request(mergeOptions(this._defaultOptions, options, RequestMethod.Get, url));
}
if (url instanceof Request) {
if (url.method !== RequestMethod.Get) {

View File

@ -200,8 +200,8 @@ class UpgradeNg1ComponentAdapter implements OnInit, OnChanges, DoCheck {
// Linking
const link = this.directive.link;
const preLink = (typeof link == 'object') && (link as IDirectivePrePost).pre;
const postLink = (typeof link == 'object') ? (link as IDirectivePrePost).post : link;
const preLink = typeof link == 'object' && link.pre;
const postLink = typeof link == 'object' ? link.post : link;
const attrs: IAttributes = NOT_SUPPORTED;
const transcludeFn: ITranscludeFunction = NOT_SUPPORTED;
if (preLink) {

View File

@ -168,8 +168,8 @@ export class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
// Linking
const link = this.directive.link;
const preLink = (typeof link == 'object') && (link as IDirectivePrePost).pre;
const postLink = (typeof link == 'object') ? (link as IDirectivePrePost).post : link;
const preLink = typeof link == 'object' && link.pre;
const postLink = typeof link == 'object' ? link.post : link;
const attrs: IAttributes = NOT_SUPPORTED;
const transcludeFn: ITranscludeFunction = NOT_SUPPORTED;
if (preLink) {
@ -229,7 +229,7 @@ export class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
`Binding definitions on scope and controller at the same time is not supported.`);
}
const context = (btcIsObject) ? directive.bindToController : directive.scope;
const context = btcIsObject ? directive.bindToController : directive.scope;
const bindings = new Bindings();
if (typeof context == 'object') {

View File

@ -132,7 +132,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
if (state !== REJECTED && value instanceof ZoneAwarePromise &&
value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) &&
(value as any)[symbolState] !== UNRESOLVED) {
clearRejectedNoCatch(<Promise<any>>value as any);
clearRejectedNoCatch(value);
resolvePromise(promise, (value as any)[symbolState], (value as any)[symbolValue]);
} else if (state !== REJECTED && typeof then === 'function') {
try {

View File

@ -24,7 +24,7 @@ Zone.__load_patch('EventEmitter', (global: any) => {
const eventNameToString = function(eventName: string|Symbol) {
if (typeof eventName === 'string') {
return eventName as string;
return eventName;
}
if (!eventName) {
return '';

View File

@ -26,7 +26,7 @@ Zone.__load_patch('asynctest', (global: any, Zone: ZoneType, api: _ZonePrivate)
}
runInTestZone(fn, this, done, (err: any) => {
if (typeof err === 'string') {
return done.fail(new Error(<string>err));
return done.fail(new Error(err));
} else {
done.fail(err);
}

View File

@ -43,8 +43,7 @@ function compareSizeEntry(
actual: DirectorySizeEntry | number, expected: DirectorySizeEntry | number, filePath: string,
threshold: Threshold) {
if (typeof actual !== 'number' && typeof expected !== 'number') {
return compareDirectorySizeEntry(
<DirectorySizeEntry>actual, <DirectorySizeEntry>expected, filePath, threshold);
return compareDirectorySizeEntry(actual, expected, filePath, threshold);
} else {
return compareActualSizeToExpected(<number>actual, <number>expected, filePath, threshold);
}