Skip to content

Allow setting JSON.parse return type #39383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/lib.es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ interface JSON {
* @param reviver A function that transforms the results. This function is called for each member of the object.
* If a member contains nested objects, the nested objects are transformed before the parent object is.
*/
parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;
parse<T = any>(text: string, reviver?: (this: any, key: string, value: any) => any): T;
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
* @param value A JavaScript value, usually an object or array, to be converted.
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ namespace ts {

/*@internal*/
export function getBuildInfo(buildInfoText: string) {
return JSON.parse(buildInfoText) as BuildInfo;
return JSON.parse<BuildInfo>(buildInfoText);
}

/*@internal*/
Expand Down
4 changes: 2 additions & 2 deletions src/harness/documentsUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ namespace documents {
private _sourceLineMappings: Mapping[][][] = [];

constructor(mapFile: string | undefined, data: string | RawSourceMap) {
this.raw = typeof data === "string" ? JSON.parse(data) as RawSourceMap : data;
this.raw = typeof data === "string" ? JSON.parse<RawSourceMap>(data) : data;
this.mapFile = mapFile;
this.version = this.raw.version;
this.file = this.raw.file;
Expand Down Expand Up @@ -184,4 +184,4 @@ namespace documents {
return vlq;
}
}
}
}
2 changes: 1 addition & 1 deletion src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ interface JSON {
* @param reviver A function that transforms the results. This function is called for each member of the object.
* If a member contains nested objects, the nested objects are transformed before the parent object is.
*/
parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;
parse<T = any>(text: string, reviver?: (this: any, key: string, value: any) => any): T;
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
* @param value A JavaScript value, usually an object or array, to be converted.
Expand Down
2 changes: 1 addition & 1 deletion src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2756,7 +2756,7 @@ namespace ts.server {
let request: protocol.Request | undefined;
let relevantFile: protocol.FileRequestArgs | undefined;
try {
request = <protocol.Request>JSON.parse(message);
request = JSON.parse<protocol.Request>(message);
relevantFile = request.arguments && (request as protocol.FileRequest).arguments.file ? (request as protocol.FileRequest).arguments : undefined;

perfLogger.logStartCommand("" + request.command, message.substring(0, 100));
Expand Down
16 changes: 8 additions & 8 deletions src/services/shims.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ namespace ts {
// 'in' does not have this effect.
if ("getModuleResolutionsForFile" in this.shimHost) {
this.resolveModuleNames = (moduleNames, containingFile) => {
const resolutionsInFile = <MapLike<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile!(containingFile)); // TODO: GH#18217
const resolutionsInFile = JSON.parse<MapLike<string>>(this.shimHost.getModuleResolutionsForFile!(containingFile)); // TODO: GH#18217
return map(moduleNames, name => {
const result = getProperty(resolutionsInFile, name);
return result ? { resolvedFileName: result, extension: extensionFromPath(result), isExternalLibraryImport: false } : undefined;
Expand All @@ -358,7 +358,7 @@ namespace ts {
}
if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) {
this.resolveTypeReferenceDirectives = (typeDirectiveNames, containingFile) => {
const typeDirectivesForFile = <MapLike<ResolvedTypeReferenceDirective>>JSON.parse(this.shimHost.getTypeReferenceDirectiveResolutionsForFile!(containingFile)); // TODO: GH#18217
const typeDirectivesForFile = JSON.parse<MapLike<ResolvedTypeReferenceDirective>>(this.shimHost.getTypeReferenceDirectiveResolutionsForFile!(containingFile)); // TODO: GH#18217
return map(typeDirectiveNames, name => getProperty(typeDirectivesForFile, name));
};
}
Expand Down Expand Up @@ -406,7 +406,7 @@ namespace ts {
if (settingsJson === null || settingsJson === "") {
throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
}
const compilerOptions = <CompilerOptions>JSON.parse(settingsJson);
const compilerOptions = JSON.parse<CompilerOptions>(settingsJson);
// permit language service to handle all files (filtering should be performed on the host side)
compilerOptions.allowNonTsExtensions = true;
return compilerOptions;
Expand Down Expand Up @@ -948,7 +948,7 @@ namespace ts {
return this.forwardJSONCall(
`getCompletionEntryDetails('${fileName}', ${position}, '${entryName}')`,
() => {
const localOptions: FormatCodeOptions = formatOptions === undefined ? undefined : JSON.parse(formatOptions);
const localOptions: FormatCodeOptions | undefined = formatOptions === undefined ? undefined : JSON.parse(formatOptions);
return this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source, preferences);
}
);
Expand Down Expand Up @@ -1116,7 +1116,7 @@ namespace ts {

public resolveModuleName(fileName: string, moduleName: string, compilerOptionsJson: string): string {
return this.forwardJSONCall(`resolveModuleName('${fileName}')`, () => {
const compilerOptions = <CompilerOptions>JSON.parse(compilerOptionsJson);
const compilerOptions = JSON.parse<CompilerOptions>(compilerOptionsJson);
const result = resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host);
let resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined;
if (result.resolvedModule && result.resolvedModule.extension !== Extension.Ts && result.resolvedModule.extension !== Extension.Tsx && result.resolvedModule.extension !== Extension.Dts) {
Expand All @@ -1132,7 +1132,7 @@ namespace ts {

public resolveTypeReferenceDirective(fileName: string, typeReferenceDirective: string, compilerOptionsJson: string): string {
return this.forwardJSONCall(`resolveTypeReferenceDirective(${fileName})`, () => {
const compilerOptions = <CompilerOptions>JSON.parse(compilerOptionsJson);
const compilerOptions = JSON.parse<CompilerOptions>(compilerOptionsJson);
const result = resolveTypeReferenceDirective(typeReferenceDirective, normalizeSlashes(fileName), compilerOptions, this.host);
return {
resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined,
Expand Down Expand Up @@ -1163,7 +1163,7 @@ namespace ts {
return this.forwardJSONCall(
`getAutomaticTypeDirectiveNames('${compilerOptionsJson}')`,
() => {
const compilerOptions = <CompilerOptions>JSON.parse(compilerOptionsJson);
const compilerOptions = JSON.parse<CompilerOptions>(compilerOptionsJson);
return getAutomaticTypeDirectiveNames(compilerOptions, this.host);
}
);
Expand Down Expand Up @@ -1212,7 +1212,7 @@ namespace ts {
public discoverTypings(discoverTypingsJson: string): string {
const getCanonicalFileName = createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false);
return this.forwardJSONCall("discoverTypings()", () => {
const info = <DiscoverTypingsInfo>JSON.parse(discoverTypingsJson);
const info = JSON.parse<DiscoverTypingsInfo>(discoverTypingsJson);
if (this.safeList === undefined) {
this.safeList = JsTyping.loadSafeList(this.host, toPath(info.safeListPath, info.safeListPath, getCanonicalFileName));
}
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/projectsRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ namespace project {
}

try {
testCase = <ProjectRunnerTestCase & ts.CompilerOptions>JSON.parse(testFileText!);
testCase = JSON.parse(testFileText!);
}
catch (e) {
throw assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
Expand Down
4 changes: 2 additions & 2 deletions src/testRunner/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ namespace Harness {
export let globalTimeout: number;
function handleTestConfig() {
if (testConfigContent !== "") {
const testConfig = <TestConfig>JSON.parse(testConfigContent);
const testConfig = JSON.parse<TestConfig>(testConfigContent);
if (testConfig.light) {
setLightMode(true);
}
Expand Down Expand Up @@ -262,4 +262,4 @@ namespace Harness {
}

startTestEnvironment();
}
}
2 changes: 1 addition & 1 deletion src/typingsInstaller/nodeTypingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace ts.server.typingsInstaller {
return createMap<MapLike<string>>();
}
try {
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath)!);
const content = JSON.parse<TypesRegistryFile>(host.readFile(typesRegistryFilePath)!);
return createMapFromTemplate(content.entries);
}
catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions src/typingsInstallerCore/typingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ namespace ts.server.typingsInstaller {
this.log.writeLine(`Trying to find '${packageJson}'...`);
}
if (this.installTypingHost.fileExists(packageJson) && this.installTypingHost.fileExists(packageLockJson)) {
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson)!); // TODO: GH#18217
const npmLock = <NpmLock>JSON.parse(this.installTypingHost.readFile(packageLockJson)!); // TODO: GH#18217
const npmConfig = JSON.parse<NpmConfig>(this.installTypingHost.readFile(packageJson)!); // TODO: GH#18217
const npmLock = JSON.parse<NpmLock>(this.installTypingHost.readFile(packageLockJson)!); // TODO: GH#18217
if (this.log.isEnabled()) {
this.log.writeLine(`Loaded content of '${packageJson}': ${JSON.stringify(npmConfig)}`);
this.log.writeLine(`Loaded content of '${packageLockJson}'`);
Expand Down
41 changes: 21 additions & 20 deletions tests/baselines/reference/1.0lib-noErrors.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//// [1.0lib-noErrors.ts]
//// [1.0lib-noErrors.ts]
/* *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
Expand Down Expand Up @@ -936,7 +936,7 @@ interface JSON {
* @param reviver A function that transforms the results. This function is called for each member of the object.
* If a member contains nested objects, the nested objects are transformed before the parent object is.
*/
parse(text: string, reviver?: (key: any, value: any) => any): any;
Wparse<T = any>(text: string, reviver?: (this: any, key: string, value: any) => any): T;
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
* @param value A JavaScript value, usually an object or array, to be converted.
Expand Down Expand Up @@ -1141,21 +1141,22 @@ declare var Array: {
<T>(...items: T[]): T[];
isArray(arg: any): boolean;
prototype: Array<any>;
}

//// [1.0lib-noErrors.js]
/* *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
}


//// [1.0lib-noErrors.js]
/* *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
6 changes: 3 additions & 3 deletions tests/baselines/reference/controlFlowIfStatement.types
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@ function c<T>(data: string | T): T {
>'string' : "string"

return JSON.parse(data);
>JSON.parse(data) : any
>JSON.parse : (text: string, reviver?: (this: any, key: string, value: any) => any) => any
>JSON.parse(data) : T
>JSON.parse : <T = any>(text: string, reviver?: (this: any, key: string, value: any) => any) => T
>JSON : JSON
>parse : (text: string, reviver?: (this: any, key: string, value: any) => any) => any
>parse : <T = any>(text: string, reviver?: (this: any, key: string, value: any) => any) => T
>data : string | (T & string)
}
else {
Expand Down
4 changes: 2 additions & 2 deletions tests/cases/conformance/decorators/1.0lib-noErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ interface JSON {
* @param reviver A function that transforms the results. This function is called for each member of the object.
* If a member contains nested objects, the nested objects are transformed before the parent object is.
*/
parse(text: string, reviver?: (key: any, value: any) => any): any;
parse<T = any>(text: string, reviver?: (this: any, key: string, value: any) => any): T;
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
* @param value A JavaScript value, usually an object or array, to be converted.
Expand Down Expand Up @@ -1141,4 +1141,4 @@ declare var Array: {
<T>(...items: T[]): T[];
isArray(arg: any): boolean;
prototype: Array<any>;
}
}
2 changes: 1 addition & 1 deletion tests/lib/lib.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,7 @@ interface JSON {
* @param reviver A function that transforms the results. This function is called for each member of the object.
* If a member contains nested objects, the nested objects are transformed before the parent object is.
*/
parse(text: string, reviver?: (key: any, value: any) => any): any;
parse<T = any>(text: string, reviver?: (this: any, key: string, value: any) => any): T;
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
* @param value A JavaScript value, usually an object or array, to be converted.
Expand Down