TypeStrong / ts-loader

TypeScript loader for webpack
https://johnnyreilly.com/ts-loader-goes-webpack-5
MIT License
3.44k stars 429 forks source link

Add support for using keyword (TypeScript 5.2) #1628

Open dkhovrich opened 9 months ago

dkhovrich commented 9 months ago

TypeScript has introduced a new keyword using in 5.2 release. Seems like ts-loader does not support it. I get the following error:

You may need an additional loader to handle the result of these loaders.
> await using tempFile = await createTempFile(content.value);

Could you please add support for this new keyword?

fregante commented 8 months ago

What's causing this issue? It seems that TS 5.2 is already supported and tested (https://github.com/TypeStrong/ts-loader/pull/1633), so how come ts-loader also needs to be updated?

johnnyreilly commented 8 months ago

Suspect this may be a tsconfig.json issue. No change should be required to ts-loader

fregante commented 8 months ago

You may be right, for some reason tsc itself is failing on the files, even if I use the suggested TypeScript config:

{
    "compilerOptions": {
        "target": "es2022",
        "lib": ["es2022", "esnext.disposable", "dom"]
    }
}

Seen at the bottom of the section https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management

My config is based on @sindresorhus/tsconfig.json.

fregante commented 8 months ago

The error is between the chair and the monitor. 😅

The syntax is:

using tempFile = await createTempFile(content.value);

not

await using tempFile = await createTempFile(content.value);

I think ts-loader is working correctly here. 👍

dkhovrich commented 8 months ago

The syntax is correct when you are using Symbol.asyncDispose. Please take a look at this simplified example from the handbook:

async function doWork() {
    // Do fake work for half a second.
    await new Promise(resolve => setTimeout(resolve, 500));
}
function loggy(id: string): AsyncDisposable {
    console.log(`Constructing ${id}`);
    return {
        async [Symbol.asyncDispose]() {
            console.log(`Disposing (async) ${id}`);
            await doWork();
        },
    }
}
async function func() {
    await using a = loggy("a");
}
func();

And it works as expected when I compile it with esbuild. But Webpack with ts-loader keeps failing with an error:

You may need an additional loader to handle the result of these loaders.
dkhovrich commented 8 months ago

Hm, I could make it work with no error after I changed compilerOptions.target from ESNext to es2022. A bit weird, but I think that's okay. Thanks! :)

mfp22 commented 2 months ago

Does this new keyword collide with my favorite undocumented RxJS function using? Since I haven't found documentation when I've looked for it in the past, I'm always concerned there could be a breaking change with it at some point