You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here's the message accompanying the linked PR for context here:
This commit removes conditional type-checking of unstable APIs.
Before this commit deno check (or any other type-checking command and the LSP) would error out if there was an unstable API in the code, but not --unstable flag provided.
This situation hinders DX and makes it harder to configure Deno. Failing during runtime unless --unstable flag is provided is enough in this case.
I think the change might have been introduced prematurely, as there is no longer a simple way to type-check stable code.
The change completely mitigates one of the useful safety features of type-checking: preventing use of references that won't exist at runtime for stable code (code that does not use the --unstable runtime argument). By including all of the unstable type declarations during type-checking for all programs unconditionally, an entire class of preventable runtime ReferenceErrors are no longer caught. Although I don't have usage data to support it, I expect that the overwhelming majority of Deno users are not running code using the --unstable flag, especially in production.
Here's a contrived example for demonstration which uses the WebSocketStream class, which is a global that's only available when using the --unstable flag since Deno v1.13.0:
example.ts:
constwss=newWebSocketStream("ws://localhost:8000/live");const{ readable }=awaitwss.opened;forawait(const_dataofreadable){// code that handles the socket stream…}
Running the program crashes with an uncaught ReferenceError:
% deno run example.ts
error: Uncaught (in promise) ReferenceError: WebSocketStream is not defined
const wss = new WebSocketStream("ws://localhost:8000/live");
^
at file:///Users/deno/example.ts:1:13
The problem is exaggerated when type-checking is run prior to execution using the --check argument (deno run --check …). The expectation is that a type-checking failure will occur for these kinds of reference errors and prevent execution of the code entirely. From the TypeScript section of the manual (📌):
When using deno runwith the --check argument, type-related diagnostics will prevent the program from running: it will halt on these warnings, and exit the process before executing the code.
This was true in previous releases…
% deno --version
deno 1.39.4 (release, aarch64-apple-darwin)
v8 12.0.267.8
typescript 5.3.3
% deno run --check example.ts
Check file:///Users/deno/example.ts
error: TS2304 [ERROR]: Cannot find name 'WebSocketStream'.
const wss = new WebSocketStream("ws://localhost:8000/live");
~~~~~~~~~~~~~~~
at file:///Users/deno/example.ts:1:17
…but after the change, these unavailable reference errors are not caught prior to runtime, and instead they create exceptions:
% deno --version
deno 1.40.1 (release, aarch64-apple-darwin)
v8 12.1.285.6
typescript 5.3.3
% deno run --check example.ts
Check file:///Users/deno/example.ts
error: Uncaught (in promise) ReferenceError: WebSocketStream is not defined
const wss = new WebSocketStream("ws://localhost:8000/live");
^
at file:///Users/deno/example.ts:1:13
The error occurs almost instantly in the simple, contrived example — but in other typically-complex code, a reference error might not be encountered until a deep, nested condition is met somewhere long after execution starts.
Workarounds are available at present, but tedious — they require modifying every program which doesn't use unstable features in order to emulate the previous default compiler behavior. Options include:
adding triple-slash directives to every entrypoint module:
example.ts:
/// <reference no-default-lib="true" />/// <reference lib="deno.window" />constwss=newWebSocketStream("ws://localhost:8000/live");const{ readable }=awaitwss.opened;forawait(const_dataofreadable){// code that handles the socket stream…}
explicitly configuring compiler options in the program's associated config file:
deno.json:
{
"compilerOptions": {
"lib": ["deno.window"]
}
}
I'm sympathetic to users who want an LSP-enabled experience with less friction while using unstable features… but this change seems like a clear regression, and I hope we can find a better solution.
The text was updated successfully, but these errors were encountered:
I agree that we have to have a way to statically verify that we're not using unstable feats.
OTOH, I think unstable should be opt-out in Deno 1 and opt-in in Deno 2, as Deno 1 has too many unstable feats, some of which are major APIs - even Deno.serve was unstable until recently. I feel like unstable is almost default in Deno 1.
Ref:
Here's the message accompanying the linked PR for context here:
I think the change might have been introduced prematurely, as there is no longer a simple way to type-check stable code.
The change completely mitigates one of the useful safety features of type-checking: preventing use of references that won't exist at runtime for stable code (code that does not use the
--unstable
runtime argument). By including all of the unstable type declarations during type-checking for all programs unconditionally, an entire class of preventable runtimeReferenceError
s are no longer caught. Although I don't have usage data to support it, I expect that the overwhelming majority of Deno users are not running code using the--unstable
flag, especially in production.Here's a contrived example for demonstration which uses the
WebSocketStream
class, which is a global that's only available when using the--unstable
flag since Deno v1.13.0:example.ts
:Type-checking passes (no diagnostics):
Running the program crashes with an uncaught
ReferenceError
:% deno run example.ts error: Uncaught (in promise) ReferenceError: WebSocketStream is not defined const wss = new WebSocketStream("ws://localhost:8000/live"); ^ at file:///Users/deno/example.ts:1:13
The problem is exaggerated when type-checking is run prior to execution using the
--check
argument (deno run --check …
). The expectation is that a type-checking failure will occur for these kinds of reference errors and prevent execution of the code entirely. From the TypeScript section of the manual (📌):This was true in previous releases…
…but after the change, these unavailable reference errors are not caught prior to runtime, and instead they create exceptions:
% deno --version deno 1.40.1 (release, aarch64-apple-darwin) v8 12.1.285.6 typescript 5.3.3 % deno run --check example.ts Check file:///Users/deno/example.ts error: Uncaught (in promise) ReferenceError: WebSocketStream is not defined const wss = new WebSocketStream("ws://localhost:8000/live"); ^ at file:///Users/deno/example.ts:1:13
The error occurs almost instantly in the simple, contrived example — but in other typically-complex code, a reference error might not be encountered until a deep, nested condition is met somewhere long after execution starts.
Workarounds are available at present, but tedious — they require modifying every program which doesn't use unstable features in order to emulate the previous default compiler behavior. Options include:
adding triple-slash directives to every entrypoint module:
example.ts
:explicitly configuring compiler options in the program's associated config file:
deno.json
:I'm sympathetic to users who want an LSP-enabled experience with less friction while using unstable features… but this change seems like a clear regression, and I hope we can find a better solution.
The text was updated successfully, but these errors were encountered: