fix(localize): update type castings for JSON.parse usage (#40710)

Update usages of JSON.parse to be cast as specific types.

PR Close #40710
This commit is contained in:
Joey Perrott 2021-02-04 14:21:09 -08:00 committed by Alex Rickabaugh
parent 7ecfd2d7ed
commit 4b469c960e
4 changed files with 22 additions and 15 deletions

View File

@ -177,9 +177,10 @@ export { renderModule, renderModuleFactory } from '@angular/platform-server';`;
it('should add package to `devDependencies` by default', async () => { it('should add package to `devDependencies` by default', async () => {
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise(); host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
const packageJsonText = host.readContent('/package.json'); const packageJsonText = host.readContent('/package.json');
expect(JSON.parse(packageJsonText).devDependencies?.['@angular/localize']) const packageJsonObj = JSON.parse(packageJsonText) as
.toBe('~0.0.0-PLACEHOLDER'); {devDependencies: {[key: string]: string}, dependencies: {[key: string]: string}};
expect(JSON.parse(packageJsonText).dependencies?.['@angular/localize']).toBeUndefined(); expect(packageJsonObj.devDependencies?.['@angular/localize']).toBe('~0.0.0-PLACEHOLDER');
expect(packageJsonObj.dependencies?.['@angular/localize']).toBeUndefined();
}); });
it('should add package to `dependencies` if `useAtRuntime` is `true`', async () => { it('should add package to `dependencies` if `useAtRuntime` is `true`', async () => {
@ -187,8 +188,9 @@ export { renderModule, renderModuleFactory } from '@angular/platform-server';`;
.runSchematicAsync('ng-add', {...defaultOptions, useAtRuntime: true}, host) .runSchematicAsync('ng-add', {...defaultOptions, useAtRuntime: true}, host)
.toPromise(); .toPromise();
const packageJsonText = host.readContent('/package.json'); const packageJsonText = host.readContent('/package.json');
expect(JSON.parse(packageJsonText).dependencies?.['@angular/localize']) const packageJsonObj = JSON.parse(packageJsonText) as
.toBe('~0.0.0-PLACEHOLDER'); {devDependencies: {[key: string]: string}, dependencies: {[key: string]: string}};
expect(JSON.parse(packageJsonText).devDependencies?.['@angular/localize']).toBeUndefined(); expect(packageJsonObj.dependencies?.['@angular/localize']).toBe('~0.0.0-PLACEHOLDER');
expect(packageJsonObj.devDependencies?.['@angular/localize']).toBeUndefined();
}); });
}); });

View File

@ -40,5 +40,5 @@ export function validateOptions(name: string, validOptions: ValidOptions, option
* @param optionString The string to parse. * @param optionString The string to parse.
*/ */
export function parseFormatOptions(optionString: string = '{}'): FormatOptions { export function parseFormatOptions(optionString: string = '{}'): FormatOptions {
return JSON.parse(optionString); return JSON.parse(optionString) as FormatOptions;
} }

View File

@ -93,7 +93,7 @@ export class ArbTranslationParser implements TranslationParser<ArbJsonObject> {
} }
private tryParseArbFormat(contents: string): ArbJsonObject { private tryParseArbFormat(contents: string): ArbJsonObject {
const json = JSON.parse(contents); const json = JSON.parse(contents) as ArbJsonObject;
if (typeof json['@@locale'] !== 'string') { if (typeof json['@@locale'] !== 'string') {
throw new Error('Missing @@locale property.'); throw new Error('Missing @@locale property.');
} }

View File

@ -11,6 +11,11 @@ import {Diagnostics} from '../../../diagnostics';
import {ParseAnalysis, ParsedTranslationBundle, TranslationParser} from './translation_parser'; import {ParseAnalysis, ParsedTranslationBundle, TranslationParser} from './translation_parser';
interface SimpleJsonFile {
locale: string;
translations: {[messageId: string]: string};
}
/** /**
* A translation parser that can parse JSON that has the form: * A translation parser that can parse JSON that has the form:
* *
@ -27,16 +32,16 @@ import {ParseAnalysis, ParsedTranslationBundle, TranslationParser} from './trans
* @see SimpleJsonTranslationSerializer * @see SimpleJsonTranslationSerializer
* @publicApi used by CLI * @publicApi used by CLI
*/ */
export class SimpleJsonTranslationParser implements TranslationParser<Object> { export class SimpleJsonTranslationParser implements TranslationParser<SimpleJsonFile> {
/** /**
* @deprecated * @deprecated
*/ */
canParse(filePath: string, contents: string): Object|false { canParse(filePath: string, contents: string): SimpleJsonFile|false {
const result = this.analyze(filePath, contents); const result = this.analyze(filePath, contents);
return result.canParse && result.hint; return result.canParse && result.hint;
} }
analyze(filePath: string, contents: string): ParseAnalysis<Object> { analyze(filePath: string, contents: string): ParseAnalysis<SimpleJsonFile> {
const diagnostics = new Diagnostics(); const diagnostics = new Diagnostics();
// For this to be parsable, the extension must be `.json` and the contents must include "locale" // For this to be parsable, the extension must be `.json` and the contents must include "locale"
// and "translations" keys. // and "translations" keys.
@ -46,7 +51,7 @@ export class SimpleJsonTranslationParser implements TranslationParser<Object> {
return {canParse: false, diagnostics}; return {canParse: false, diagnostics};
} }
try { try {
const json = JSON.parse(contents); const json = JSON.parse(contents) as SimpleJsonFile;
if (json.locale === undefined) { if (json.locale === undefined) {
diagnostics.warn('Required "locale" property missing.'); diagnostics.warn('Required "locale" property missing.');
return {canParse: false, diagnostics}; return {canParse: false, diagnostics};
@ -70,8 +75,8 @@ export class SimpleJsonTranslationParser implements TranslationParser<Object> {
} }
} }
parse(_filePath: string, contents: string, json?: Object): ParsedTranslationBundle { parse(_filePath: string, contents: string, json?: SimpleJsonFile): ParsedTranslationBundle {
const {locale: parsedLocale, translations} = json || JSON.parse(contents); const {locale: parsedLocale, translations} = json || JSON.parse(contents) as SimpleJsonFile;
const parsedTranslations: Record<ɵMessageId, ɵParsedTranslation> = {}; const parsedTranslations: Record<ɵMessageId, ɵParsedTranslation> = {};
for (const messageId in translations) { for (const messageId in translations) {
const targetMessage = translations[messageId]; const targetMessage = translations[messageId];