Skip to content

Commit f09024d

Browse files
authored
fix: cater for change in resolveTypeReferenceDirective API in TypeScript 4.7 (#1422)
* speculative * v9.2.7 * node 16
1 parent dcec071 commit f09024d

File tree

6 files changed

+103
-42
lines changed

6 files changed

+103
-42
lines changed

.github/workflows/push.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
name: Execution Tests Ubuntu
4949
strategy:
5050
matrix:
51-
node: [12, 14]
51+
node: [14, 16]
5252
ts: [3.8.3, 3.9.3, 4.0.3, 4.1.5, 4.2.4, 4.3.2, 4.4.2, 4.5.2, next]
5353
runs-on: ubuntu-latest
5454
steps:
@@ -75,7 +75,7 @@ jobs:
7575
name: Execution Tests Windows
7676
strategy:
7777
matrix:
78-
node: [12, 14]
78+
node: [14, 16]
7979
ts: [3.8.3, 3.9.3, 4.0.3, 4.1.5, 4.2.4, 4.3.2, 4.4.2, 4.5.2, next]
8080
runs-on: windows-latest
8181
steps:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- name: install node
1414
uses: actions/setup-node@v1
1515
with:
16-
node-version: 14
16+
node-version: 16
1717
registry-url: https://registry.npmjs.org/
1818

1919
- name: install

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## v9.2.7
4+
5+
* [cater for change in resolveTypeReferenceDirective API in TypeScript 4.7](https://github.com/TypeStrong/ts-loader/pull/1422) [#1421] - thanks @johnny_reilly and @cspotcode for inspiration in ts-node work here: https://github.com/TypeStrong/ts-node/pull/1648
6+
7+
## v9.2.6
8+
9+
* [Docs fix for thread-loader / history](https://github.com/TypeStrong/ts-loader/pull/1377) - thanks @johnnyreilly
10+
311
## v9.2.5
412

513
* [Add function to get the latest program](https://github.com/TypeStrong/ts-loader/pull/1352) - thanks @Zn4rK

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ts-loader",
3-
"version": "9.2.6",
3+
"version": "9.2.7",
44
"description": "TypeScript loader for webpack",
55
"main": "index.js",
66
"types": "dist",

src/interfaces.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,29 @@ export interface ResolvedModule {
307307
isExternalLibraryImport?: boolean;
308308
}
309309

310+
export interface TSCommon {
311+
// Changed in TS 4.7
312+
resolveTypeReferenceDirective(
313+
typeReferenceDirectiveName: string,
314+
containingFile: string | undefined,
315+
options: typescript.CompilerOptions,
316+
host: typescript.ModuleResolutionHost,
317+
redirectedReference?: typescript.ResolvedProjectReference,
318+
cache?: typescript.TypeReferenceDirectiveResolutionCache,
319+
resolutionMode?: typescript.SourceFile['impliedNodeFormat']
320+
): typescript.ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
321+
}
322+
323+
/**
324+
* Compiler APIs we use that are marked internal and not included in TypeScript's public API declarations
325+
* @internal
326+
*/
327+
export interface TSInternal {
328+
// Added in TS 4.7
329+
getModeForFileReference?: (
330+
ref: typescript.FileReference | string,
331+
containingFileMode: typescript.SourceFile['impliedNodeFormat']
332+
) => typescript.SourceFile['impliedNodeFormat'];
333+
}
334+
310335
export type Severity = 'error' | 'warning';

src/servicesHost.ts

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import {
1717
ServiceHostWhichMayBeCacheable,
1818
SolutionBuilderWithWatchHost,
1919
SolutionDiagnostics,
20+
TSCommon,
2021
TSInstance,
22+
TSInternal,
2123
WatchCallbacks,
2224
WatchFactory,
2325
WatchHost,
@@ -175,9 +177,10 @@ export function makeServicesHost(
175177
return file.version.toString();
176178
}
177179

178-
const outputFileAndKey = instance.solutionBuilderHost?.getOutputFileAndKeyFromReferencedProject(
179-
fileName
180-
);
180+
const outputFileAndKey =
181+
instance.solutionBuilderHost?.getOutputFileAndKeyFromReferencedProject(
182+
fileName
183+
);
181184
if (outputFileAndKey !== undefined) {
182185
instance.solutionBuilderHost!.outputAffectingInstanceVersion.set(
183186
outputFileAndKey.key,
@@ -198,9 +201,10 @@ export function makeServicesHost(
198201

199202
if (file === undefined) {
200203
if (instance.solutionBuilderHost) {
201-
const outputFileAndKey = instance.solutionBuilderHost.getOutputFileTextAndKeyFromReferencedProject(
202-
fileName
203-
);
204+
const outputFileAndKey =
205+
instance.solutionBuilderHost.getOutputFileTextAndKeyFromReferencedProject(
206+
fileName
207+
);
204208
if (outputFileAndKey !== undefined) {
205209
instance.solutionBuilderHost!.outputAffectingInstanceVersion.set(
206210
outputFileAndKey.key,
@@ -288,16 +292,20 @@ function makeResolvers<T extends typescript.ModuleResolutionHost>(
288292
);
289293

290294
const resolveTypeReferenceDirectives = (
291-
typeDirectiveNames: string[],
295+
typeDirectiveNames: string[] | readonly typescript.FileReference[],
292296
containingFile: string,
293-
redirectedReference?: typescript.ResolvedProjectReference
297+
redirectedReference: typescript.ResolvedProjectReference | undefined,
298+
options: typescript.CompilerOptions,
299+
containingFileMode?: typescript.SourceFile['impliedNodeFormat'] | undefined // new impliedNodeFormat is accepted by compilerHost
294300
): (typescript.ResolvedTypeReferenceDirective | undefined)[] =>
295301
typeDirectiveNames.map(
296302
directive =>
297303
resolveTypeReferenceDirective(
298304
directive,
299305
containingFile,
300-
redirectedReference
306+
options,
307+
redirectedReference,
308+
containingFileMode
301309
).resolvedTypeReferenceDirective
302310
);
303311

@@ -312,9 +320,12 @@ function createWatchFactory(
312320
filePathKeyMapper: (fileName: string) => FilePathKey,
313321
compiler: typeof typescript
314322
): WatchFactory {
315-
const watchedFiles: WatchCallbacks<typescript.FileWatcherCallback> = new Map();
316-
const watchedDirectories: WatchCallbacks<typescript.DirectoryWatcherCallback> = new Map();
317-
const watchedDirectoriesRecursive: WatchCallbacks<typescript.DirectoryWatcherCallback> = new Map();
323+
const watchedFiles: WatchCallbacks<typescript.FileWatcherCallback> =
324+
new Map();
325+
const watchedDirectories: WatchCallbacks<typescript.DirectoryWatcherCallback> =
326+
new Map();
327+
const watchedDirectoriesRecursive: WatchCallbacks<typescript.DirectoryWatcherCallback> =
328+
new Map();
318329

319330
return {
320331
watchedFiles,
@@ -473,13 +484,8 @@ export function makeWatchHost(
473484
instance: TSInstance,
474485
projectReferences?: ReadonlyArray<typescript.ProjectReference>
475486
) {
476-
const {
477-
compiler,
478-
compilerOptions,
479-
files,
480-
otherFiles,
481-
filePathKeyMapper,
482-
} = instance;
487+
const { compiler, compilerOptions, files, otherFiles, filePathKeyMapper } =
488+
instance;
483489

484490
const { watchFile, watchDirectory, invokeFileWatcher } = createWatchFactory(
485491
filePathKeyMapper,
@@ -507,9 +513,10 @@ export function makeWatchHost(
507513
readFile: readFileWithCachingText,
508514

509515
watchFile: (fileName, callback, pollingInterval, options) => {
510-
const outputFileKey = instance.solutionBuilderHost?.getOutputFileKeyFromReferencedProject(
511-
fileName
512-
);
516+
const outputFileKey =
517+
instance.solutionBuilderHost?.getOutputFileKeyFromReferencedProject(
518+
fileName
519+
);
513520
if (!outputFileKey || outputFileKey === filePathKeyMapper(fileName)) {
514521
return watchFile(fileName, callback, pollingInterval, options);
515522
}
@@ -1155,9 +1162,11 @@ export function getSolutionErrors(instance: TSInstance, context: string) {
11551162
}
11561163

11571164
type ResolveTypeReferenceDirective = (
1158-
directive: string,
1165+
directive: string | typescript.FileReference,
11591166
containingFile: string,
1160-
redirectedReference?: typescript.ResolvedProjectReference
1167+
options: typescript.CompilerOptions,
1168+
redirectedReference?: typescript.ResolvedProjectReference,
1169+
containingFileMode?: typescript.SourceFile['impliedNodeFormat'] | undefined // new impliedNodeFormat is accepted by compilerHost
11611170
) => typescript.ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
11621171

11631172
function makeResolveTypeReferenceDirective(
@@ -1172,31 +1181,50 @@ function makeResolveTypeReferenceDirective(
11721181
if (customResolveTypeReferenceDirective === undefined) {
11731182
// Until the api is published
11741183
if (
1175-
(compiler as any).createTypeReferenceDirectiveResolutionCache &&
1184+
compiler.createTypeReferenceDirectiveResolutionCache !== undefined &&
11761185
!instance.typeReferenceResolutionCache
11771186
) {
1178-
instance.typeReferenceResolutionCache = (compiler as any).createTypeReferenceDirectiveResolutionCache(
1179-
moduleResolutionHost.getCurrentDirectory!(),
1180-
createGetCanonicalFileName(instance),
1181-
instance.compilerOptions,
1182-
instance.moduleResolutionCache?.getPackageJsonInfoCache?.()
1183-
);
1187+
instance.typeReferenceResolutionCache =
1188+
compiler.createTypeReferenceDirectiveResolutionCache(
1189+
moduleResolutionHost.getCurrentDirectory!(),
1190+
createGetCanonicalFileName(instance),
1191+
instance.compilerOptions,
1192+
instance.moduleResolutionCache?.getPackageJsonInfoCache?.()
1193+
);
11841194
}
1185-
return (directive, containingFile, redirectedReference) =>
1186-
// Until the api is published
1187-
(compiler.resolveTypeReferenceDirective as any)(
1188-
directive,
1195+
return (
1196+
typeDirectiveName,
1197+
containingFile,
1198+
options,
1199+
redirectedReference,
1200+
containingFileMode
1201+
) => {
1202+
// Copy-pasted from https://github.com/TypeStrong/ts-node/blob/9f789d0d91c6eba30ac7f7aad45194a23b44f159/src/resolver-functions.ts#L139
1203+
const nameIsString = typeof typeDirectiveName === 'string';
1204+
const mode = nameIsString
1205+
? undefined
1206+
: (compiler as any as TSInternal).getModeForFileReference!(
1207+
typeDirectiveName,
1208+
containingFileMode
1209+
);
1210+
const strName = nameIsString
1211+
? typeDirectiveName
1212+
: typeDirectiveName.fileName.toLowerCase();
1213+
return (compiler as any as TSCommon).resolveTypeReferenceDirective(
1214+
strName,
11891215
containingFile,
1190-
compilerOptions,
1216+
options,
11911217
moduleResolutionHost,
11921218
redirectedReference,
1193-
instance.typeReferenceResolutionCache
1219+
undefined,
1220+
mode
11941221
);
1222+
};
11951223
}
11961224

11971225
return (directive, containingFile) =>
11981226
customResolveTypeReferenceDirective(
1199-
directive,
1227+
directive as string, // unsure whether we should evolve this further
12001228
containingFile,
12011229
compilerOptions,
12021230
moduleResolutionHost,

0 commit comments

Comments
 (0)