3
3
namespace ts . moduleSpecifiers {
4
4
export interface ModuleSpecifierPreferences {
5
5
importModuleSpecifierPreference ?: "relative" | "non-relative" ;
6
- includingJsExtensionOnAutoImports ?: boolean ;
6
+ includeExtensionInImports ?: Extension . Js | Extension . Jsx ;
7
7
}
8
8
9
9
// Note: fromSourceFile is just for usesJsExtensionOnImports
@@ -38,39 +38,39 @@ namespace ts.moduleSpecifiers {
38
38
39
39
interface Info {
40
40
readonly moduleResolutionKind : ModuleResolutionKind ;
41
- readonly addJsExtension : boolean ;
41
+ readonly addExtension : Extension . Js | Extension . Jsx | undefined ;
42
42
readonly getCanonicalFileName : GetCanonicalFileName ;
43
43
readonly sourceDirectory : string ;
44
44
}
45
45
// importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
46
46
function getInfo ( compilerOptions : CompilerOptions , importingSourceFile : SourceFile , importingSourceFileName : string , host : ModuleSpecifierResolutionHost , preferences : ModuleSpecifierPreferences ) : Info {
47
47
const moduleResolutionKind = getEmitModuleResolutionKind ( compilerOptions ) ;
48
- const addJsExtension = usesJsExtensionOnImports ( importingSourceFile , preferences ) ;
48
+ const addExtension = usesExtensionOnImports ( importingSourceFile , preferences ) ;
49
49
const getCanonicalFileName = createGetCanonicalFileName ( host . useCaseSensitiveFileNames ? host . useCaseSensitiveFileNames ( ) : true ) ;
50
50
const sourceDirectory = getDirectoryPath ( importingSourceFileName ) ;
51
- return { moduleResolutionKind, addJsExtension , getCanonicalFileName, sourceDirectory } ;
51
+ return { moduleResolutionKind, addExtension , getCanonicalFileName, sourceDirectory } ;
52
52
}
53
53
54
54
function getGlobalModuleSpecifier (
55
55
moduleFileName : string ,
56
- { addJsExtension , getCanonicalFileName, sourceDirectory } : Info ,
56
+ { addExtension , getCanonicalFileName, sourceDirectory } : Info ,
57
57
host : ModuleSpecifierResolutionHost ,
58
58
compilerOptions : CompilerOptions ,
59
59
) {
60
- return tryGetModuleNameFromTypeRoots ( compilerOptions , host , getCanonicalFileName , moduleFileName , addJsExtension )
60
+ return tryGetModuleNameFromTypeRoots ( compilerOptions , host , getCanonicalFileName , moduleFileName , addExtension )
61
61
|| tryGetModuleNameAsNodeModule ( compilerOptions , moduleFileName , host , getCanonicalFileName , sourceDirectory )
62
62
|| compilerOptions . rootDirs && tryGetModuleNameFromRootDirs ( compilerOptions . rootDirs , moduleFileName , sourceDirectory , getCanonicalFileName ) ;
63
63
}
64
64
65
65
function getLocalModuleSpecifiers (
66
66
moduleFileName : string ,
67
- { moduleResolutionKind, addJsExtension , getCanonicalFileName, sourceDirectory } : Info ,
67
+ { moduleResolutionKind, addExtension , getCanonicalFileName, sourceDirectory } : Info ,
68
68
compilerOptions : CompilerOptions ,
69
69
preferences : ModuleSpecifierPreferences ,
70
70
) {
71
71
const { baseUrl, paths } = compilerOptions ;
72
72
73
- const relativePath = removeExtensionAndIndexPostFix ( ensurePathIsNonModuleName ( getRelativePathFromDirectory ( sourceDirectory , moduleFileName , getCanonicalFileName ) ) , moduleResolutionKind , addJsExtension ) ;
73
+ const relativePath = removeExtensionAndIndexPostFix ( ensurePathIsNonModuleName ( getRelativePathFromDirectory ( sourceDirectory , moduleFileName , getCanonicalFileName ) ) , moduleResolutionKind , addExtension ) ;
74
74
if ( ! baseUrl || preferences . importModuleSpecifierPreference === "relative" ) {
75
75
return [ relativePath ] ;
76
76
}
@@ -80,7 +80,7 @@ namespace ts.moduleSpecifiers {
80
80
return [ relativePath ] ;
81
81
}
82
82
83
- const importRelativeToBaseUrl = removeExtensionAndIndexPostFix ( relativeToBaseUrl , moduleResolutionKind , addJsExtension ) ;
83
+ const importRelativeToBaseUrl = removeExtensionAndIndexPostFix ( relativeToBaseUrl , moduleResolutionKind , addExtension ) ;
84
84
if ( paths ) {
85
85
const fromPaths = tryGetModuleNameFromPaths ( removeFileExtension ( relativeToBaseUrl ) , importRelativeToBaseUrl , paths ) ;
86
86
if ( fromPaths ) {
@@ -130,8 +130,14 @@ namespace ts.moduleSpecifiers {
130
130
return relativeFirst ? [ relativePath , importRelativeToBaseUrl ] : [ importRelativeToBaseUrl , relativePath ] ;
131
131
}
132
132
133
- function usesJsExtensionOnImports ( { imports } : SourceFile , preferences : ModuleSpecifierPreferences ) : boolean {
134
- return firstDefined ( imports , ( { text } ) => pathIsRelative ( text ) ? fileExtensionIs ( text , Extension . Js ) : undefined ) || ! ! preferences . includingJsExtensionOnAutoImports ;
133
+ function tryGetFileExtension ( text : string ) {
134
+ return pathIsRelative ( text ) && fileExtensionIsOneOf ( text , [ Extension . Js , Extension . Jsx ] ) ? (
135
+ fileExtensionIs ( text , Extension . Js ) ? Extension . Js : Extension . Jsx
136
+ ) : undefined ;
137
+ }
138
+
139
+ function usesExtensionOnImports ( { imports } : SourceFile , preferences : ModuleSpecifierPreferences ) : Extension . Js | Extension . Jsx | undefined {
140
+ return preferences . includeExtensionInImports === undefined ? firstDefined ( imports , ( { text } ) => tryGetFileExtension ( text ) ) : preferences . includeExtensionInImports ;
135
141
}
136
142
137
143
function discoverProbableSymlinks ( files : ReadonlyArray < SourceFile > , getCanonicalFileName : ( file : string ) => string , host : ModuleSpecifierResolutionHost ) {
@@ -245,14 +251,14 @@ namespace ts.moduleSpecifiers {
245
251
host : GetEffectiveTypeRootsHost ,
246
252
getCanonicalFileName : ( file : string ) => string ,
247
253
moduleFileName : string ,
248
- addJsExtension : boolean ,
254
+ addExtension : Extension . Js | Extension . Jsx | undefined ,
249
255
) : string | undefined {
250
256
const roots = getEffectiveTypeRoots ( options , host ) ;
251
257
return firstDefined ( roots , unNormalizedTypeRoot => {
252
258
const typeRoot = toPath ( unNormalizedTypeRoot , /*basePath*/ undefined , getCanonicalFileName ) ;
253
259
if ( startsWith ( moduleFileName , typeRoot ) ) {
254
260
// For a type definition, we can strip `/index` even with classic resolution.
255
- return removeExtensionAndIndexPostFix ( moduleFileName . substring ( typeRoot . length + 1 ) , ModuleResolutionKind . NodeJs , addJsExtension ) ;
261
+ return removeExtensionAndIndexPostFix ( moduleFileName . substring ( typeRoot . length + 1 ) , ModuleResolutionKind . NodeJs , addExtension ) ;
256
262
}
257
263
} ) ;
258
264
}
@@ -397,10 +403,10 @@ namespace ts.moduleSpecifiers {
397
403
} ) ;
398
404
}
399
405
400
- function removeExtensionAndIndexPostFix ( fileName : string , moduleResolutionKind : ModuleResolutionKind , addJsExtension : boolean ) : string {
406
+ function removeExtensionAndIndexPostFix ( fileName : string , moduleResolutionKind : ModuleResolutionKind , addExtension : Extension . Js | Extension . Jsx | undefined ) : string {
401
407
const noExtension = removeFileExtension ( fileName ) ;
402
- return addJsExtension
403
- ? noExtension + ".js"
408
+ return addExtension
409
+ ? noExtension + addExtension
404
410
: moduleResolutionKind === ModuleResolutionKind . NodeJs
405
411
? removeSuffix ( noExtension , "/index" )
406
412
: noExtension ;
0 commit comments