Need allowJs to be true to use the json module resolution

This commit is contained in:
Sheetal Nandi 2018-01-26 15:14:48 -08:00
parent a1922fd41f
commit ca590d6fed
18 changed files with 137 additions and 20 deletions

View File

@ -2084,7 +2084,7 @@ namespace ts {
}
// May be an untyped module. If so, ignore resolutionDiagnostic.
if (resolvedModule && !resolutionExtensionIsTypeScriptOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
if (resolvedModule && !extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
if (isForAugmentation) {
const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);

View File

@ -2037,7 +2037,8 @@ namespace ts {
// Rather than requery this for each file and filespec, we query the supported extensions
// once and store it on the expansion context.
const supportedExtensions = getSupportedExtensions(options, extraFileExtensions);
// When computing file names, do not include json files. Use only module resolution or explicit includes for them
const supportedExtensions = getSupportedExtensions(options, extraFileExtensions, /*excludeJson*/ true);
// Literal files are always included verbatim. An "include" or "exclude" specification cannot
// remove a literal file.

View File

@ -2674,14 +2674,21 @@ namespace ts {
export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray<Extension> = [Extension.Dts, Extension.Ts, Extension.Tsx];
export const supportedJavascriptExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx];
const allSupportedExtensions: ReadonlyArray<Extension> = [...supportedTypeScriptExtensions, ...supportedJavascriptExtensions];
let allSupportedExtensionsIncludingJson: ReadonlyArray<Extension> | undefined;
function getAllSupportedExtensionsIncludingJson() {
return allSupportedExtensionsIncludingJson || (allSupportedExtensionsIncludingJson = [...allSupportedExtensions, Extension.Json]);
}
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ReadonlyArray<string> {
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>, excludeJson?: boolean): ReadonlyArray<string> {
const needAllExtensions = options && options.allowJs;
const useJsonExtension = needAllExtensions && !excludeJson && getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeJs;
if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
return useJsonExtension ?
getAllSupportedExtensionsIncludingJson() :
needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
}
return deduplicate(
[...allSupportedExtensions, ...extraFileExtensions.map(e => e.extension)],
[...(useJsonExtension ? getAllSupportedExtensionsIncludingJson() : allSupportedExtensions), ...extraFileExtensions.map(e => e.extension)],
equateStringsCaseSensitive,
compareStringsCaseSensitive
);
@ -2691,6 +2698,10 @@ namespace ts {
return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension));
}
export function hasJavaScriptOrJsonFileExtension(fileName: string) {
return hasJavaScriptFileExtension(fileName) || fileExtensionIs(fileName, Extension.Json);
}
export function hasTypeScriptFileExtension(fileName: string) {
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
}
@ -3091,10 +3102,6 @@ namespace ts {
return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts;
}
export function resolutionExtensionIsTypeScriptOrJson(ext: Extension) {
return extensionIsTypeScript(ext) || ext === Extension.Json;
}
/**
* Gets the extension from a path.
* Path must have a valid extension.
@ -3112,7 +3119,9 @@ namespace ts {
}
export function tryGetExtensionFromPath(path: string): Extension | undefined {
return find<Extension>(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e));
return find<Extension>(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) ||
find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)) ||
(fileExtensionIs(path, Extension.Json) ? Extension.Json : undefined);
}
// Retrieves any string from the final "." onwards from a base file name.

View File

@ -890,7 +890,7 @@ namespace ts {
// If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
// e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
if (hasJavaScriptFileExtension(candidate) || fileExtensionIs(candidate, Extension.Json)) {
if (hasJavaScriptOrJsonFileExtension(candidate)) {
const extensionless = removeFileExtension(candidate);
if (state.traceEnabled) {
const extension = candidate.substring(extensionless.length);

View File

@ -1975,7 +1975,7 @@ namespace ts {
}
const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
const isJsFile = !resolutionExtensionIsTypeScriptOrJson(resolution.extension);
const isJsFile = !extensionIsTypeScript(resolution.extension);
const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
const resolvedFileName = resolution.resolvedFileName;
@ -2404,7 +2404,6 @@ namespace ts {
switch (extension) {
case Extension.Ts:
case Extension.Dts:
case Extension.Json:
// These are always allowed.
return undefined;
case Extension.Tsx:
@ -2412,6 +2411,7 @@ namespace ts {
case Extension.Jsx:
return needJsx() || needAllowJs();
case Extension.Js:
case Extension.Json:
return needAllowJs();
}

View File

@ -511,8 +511,9 @@ namespace FourSlash {
}
private getAllDiagnostics(): ts.Diagnostic[] {
const options = this.languageService.getProgram().getCompilerOptions();
return ts.flatMap(this.languageServiceAdapterHost.getFilenames(), fileName =>
ts.isAnySupportedFileExtension(fileName) ? this.getDiagnostics(fileName) : []);
ts.fileExtensionIsOneOf(fileName, ts.getSupportedExtensions(options)) ? this.getDiagnostics(fileName) : []);
}
public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) {

View File

@ -98,7 +98,7 @@ namespace ts.JsTyping {
// Only infer typings for .js and .jsx files
fileNames = mapDefined(fileNames, fileName => {
const path = normalizePath(fileName);
if (hasJavaScriptFileExtension(path)) {
if (hasJavaScriptOrJsonFileExtension(path)) {
return path;
}
});
@ -193,7 +193,7 @@ namespace ts.JsTyping {
*/
function getTypingNamesFromSourceFileNames(fileNames: string[]) {
const fromFileNames = mapDefined(fileNames, j => {
if (!hasJavaScriptFileExtension(j)) return undefined;
if (!hasJavaScriptOrJsonFileExtension(j)) return undefined;
const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase()));
const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName);

View File

@ -1,11 +1,11 @@
error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
!!! error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
==== tests/cases/compiler/a.ts (0 errors) ====
class c {
}

View File

@ -1,11 +1,11 @@
error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
!!! error TS5055: Cannot write file 'tests/cases/compiler/b.js' because it would overwrite input file.
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx'.
!!! error TS6054: File 'tests/cases/compiler/b.js.map' has unsupported extension. The only supported extensions are '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.json'.
==== tests/cases/compiler/a.ts (0 errors) ====
class c {
}

View File

@ -0,0 +1,27 @@
//// [tests/cases/compiler/requireOfJsonFileWithoutAllowJs.ts] ////
//// [file1.ts]
import b1 = require('./b');
let x = b1.a;
import b2 = require('./b.json');
if (x) {
let b = b2.b;
x = (b1.b === b);
}
//// [b.json]
{
"a": true,
"b": "hello"
}
//// [file1.js]
"use strict";
exports.__esModule = true;
var b1 = require("./b");
var x = b1.a;
var b2 = require("./b.json");
if (x) {
var b = b2.b;
x = (b1.b === b);
}

View File

@ -0,0 +1,24 @@
=== tests/cases/compiler/file1.ts ===
import b1 = require('./b');
>b1 : Symbol(b1, Decl(file1.ts, 0, 0))
let x = b1.a;
>x : Symbol(x, Decl(file1.ts, 1, 3))
>b1 : Symbol(b1, Decl(file1.ts, 0, 0))
import b2 = require('./b.json');
>b2 : Symbol(b2, Decl(file1.ts, 1, 13))
if (x) {
>x : Symbol(x, Decl(file1.ts, 1, 3))
let b = b2.b;
>b : Symbol(b, Decl(file1.ts, 4, 7))
>b2 : Symbol(b2, Decl(file1.ts, 1, 13))
x = (b1.b === b);
>x : Symbol(x, Decl(file1.ts, 1, 3))
>b1 : Symbol(b1, Decl(file1.ts, 0, 0))
>b : Symbol(b, Decl(file1.ts, 4, 7))
}

View File

@ -0,0 +1,33 @@
=== tests/cases/compiler/file1.ts ===
import b1 = require('./b');
>b1 : any
let x = b1.a;
>x : any
>b1.a : any
>b1 : any
>a : any
import b2 = require('./b.json');
>b2 : any
if (x) {
>x : any
let b = b2.b;
>b : any
>b2.b : any
>b2 : any
>b : any
x = (b1.b === b);
>x = (b1.b === b) : boolean
>x : any
>(b1.b === b) : boolean
>b1.b === b : boolean
>b1.b : any
>b1 : any
>b : any
>b : any
}

View File

@ -1,5 +1,6 @@
// @module: commonjs
// @outdir: out/
// @allowJs: true
// @Filename: file1.ts
import b1 = require('./b');

View File

@ -1,5 +1,6 @@
// @module: amd
// @outdir: out/
// @allowJs: true
// @Filename: file1.ts
import b1 = require('./b');

View File

@ -1,5 +1,6 @@
// @module: commonjs
// @outdir: out/
// @allowJs: true
// @Filename: file1.ts
import b1 = require('./b');

View File

@ -1,5 +1,6 @@
// @module: commonjs
// @outdir: out/
// @allowJs: true
// @Filename: file1.ts
import b1 = require('./b');

View File

@ -1,5 +1,6 @@
// @module: commonjs
// @outdir: out/
// @allowJs: true
// @Filename: file1.ts
import b1 = require('./b');

View File

@ -0,0 +1,17 @@
// @module: commonjs
// @outdir: out/
// @Filename: file1.ts
import b1 = require('./b');
let x = b1.a;
import b2 = require('./b.json');
if (x) {
let b = b2.b;
x = (b1.b === b);
}
// @Filename: b.json
{
"a": true,
"b": "hello"
}