microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.07k stars 12.37k forks source link

Taking TypeScript for a spin for first time, errors for resizable ArrayBuffer #59386

Closed guest271314 closed 1 month ago

guest271314 commented 1 month ago

🔎 Search Terms

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?target=99&jsx=0&ssl=9&ssc=65&pln=9&pc=1&filetype=ts#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-QXhOZki8ScqkXiuVCkslTXTswOP0MAQA

💻 Code

const buffer = new ArrayBuffer(0, { maxByteLength: 1024 ** 2 });

🙁 Actual behavior

Expected 1 arguments, but got 2.
Variable 'readable' implicitly has type 'any' in some locations where its type cannot be determined.
Variable 'writable' implicitly has type 'any' in some locations where its type cannot be determined.
Cannot find name 'Deno'.
Cannot find name 'Deno'.
Cannot find name 'Deno'.
Cannot find name 'Deno'.
Cannot find name 'Bun'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`.
Cannot find name 'Bun'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`.
Cannot find name 'Bun'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`.
Cannot find name 'Bun'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`.
Cannot find name 'Deno'.
Cannot find name 'Deno'.
Parameter 'message' implicitly has an 'any' type.
Variable 'readable' implicitly has an 'any' type.
Property 'resize' does not exist on type 'ArrayBuffer'.
Property 'resize' does not exist on type 'ArrayBuffer'.
Property 'resize' does not exist on type 'ArrayBuffer'.
Property 'resize' does not exist on type 'ArrayBuffer'.
Parameter 'message' implicitly has an 'any' type.
Variable 'writable' implicitly has an 'any' type.

🙂 Expected behavior

Resizable ArrayBuffer to work. Dynamic import() to stay dynamic.

Additional information about the issue

I will preface that I am highly skeptical about the potential usefullness of TypeScript in my projects as I actually enjoy writing JavaScript from scratch.

Nonetheless I thought I'd take TypeScript for a spin with a single file I have that I use with node, deno, and bun to process standard input and write to standard output, in this case from Chromium browser.

Looks like resizable ArrayBuffer does not currently work in TypeScript world. From my search this https://github.com/microsoft/TypeScript/pull/58573 is in the queue for fixing the resizable ArrayBuffer error.

I'm not sure what the hold up is. Resizable ArrayBuffer is implemented by Node.js, Deno, Bun, V8 and SpiderMonkey.

I also want to make sure my dynamic import() remains dynamic.

I tried using tsc a few times at the commadline.

I installed @types/bun and @types/node. Doesn't look like there's a @types/deno, at least not using bun install.

So, how do I go about compiling/converting this code that is currently used with node, deno, and bun as it is right now, to TypeScript on the command line or in TypeScript Playground, just so I can see what TypeScript spits out?

Thanks.

nm_host.js

/*
#!/usr/bin/env -S /home/xubuntu/bin/deno run -A /home/xubuntu/bin/nm_host.js
#!/usr/bin/env -S /home/xubuntu/bin/node --experimental-default-type=module /home/xubuntu/bin/nm_host.js
#!/usr/bin/env -S /home/xubuntu/bin/bun run --smol /home/xubuntu/bin/nm_host.js
*/

const runtime = navigator.userAgent;
const buffer = new ArrayBuffer(0, { maxByteLength: 1024 ** 2 });
const view = new DataView(buffer);
const encoder = new TextEncoder();
const { dirname, filename, url } = import.meta;

let readable, writable, exit, args, cwd;

if (runtime.startsWith("Deno")) {
  ({ readable } = Deno.stdin);
  ({ writable } = Deno.stdout);
  ({ exit } = Deno);
  ({ args } = Deno);
}

if (runtime.startsWith("Node")) {
  const { Duplex } = await import("node:stream");
  ({ readable } = Duplex.toWeb(process.stdin));
  ({ writable } = Duplex.toWeb(process.stdout));
  ({ exit } = process);
  ({ argv: args } = process);
}

if (runtime.startsWith("Bun")) {
  readable = Bun.stdin.stream();
  writable = new WritableStream({
    async write(value) {
      await Bun.write(Bun.stdout, value);
    },
  }, new CountQueuingStrategy({ highWaterMark: Infinity }));
  ({ exit } = process);
  ({ argv: args } = Bun);
}

const hostdir = args.at(-2).slice(0, args.at(-2).lastIndexOf("/"));

if (runtime.startsWith("Bun") || runtime.startsWith("Node")) {
  process.chdir(hostdir);
  cwd = process.cwd();
}

if (runtime.startsWith("Deno")) {
  await Deno.chdir(hostdir);
  cwd = Deno.cwd();
}

function encodeMessage(message) {
  return encoder.encode(JSON.stringify(message));
}

async function* getMessage() {
  let messageLength = 0;
  let readOffset = 0;
  for await (let message of readable) {
    if (buffer.byteLength === 0) {
      buffer.resize(4);
      for (let i = 0; i < 4; i++) {
        view.setUint8(i, message[i]);
      }
      messageLength = view.getUint32(0, true);
      message = message.subarray(4);
      buffer.resize(0);
    }
    buffer.resize(buffer.byteLength + message.length);
    for (let i = 0; i < message.length; i++, readOffset++) {
      view.setUint8(readOffset, message[i]);
    }
    if (buffer.byteLength === messageLength) {
      yield new Uint8Array(buffer);
      messageLength = 0;
      readOffset = 0;
      buffer.resize(0);
    }
  }
}

async function sendMessage(message) {
  await new Blob([
    new Uint8Array(new Uint32Array([message.length]).buffer),
    message,
  ])
    .stream()
    .pipeTo(writable, { preventClose: true });
}

try {
  await sendMessage(encodeMessage([{ dirname, filename, url }, { cwd }, ...args]));
  for await (const message of getMessage()) {
    await sendMessage(message);
  }
} catch (e) {
  exit();
}

/*
export {
  args,
  encodeMessage,
  exit,
  getMessage,
  readable,
  sendMessage,
  writable,
};
*/
guest271314 commented 1 month ago

That Bun.stdin.stream() should be Bun.file("/dev/stdin").stream() in the code above. They behave differently for some unknown reason. At some point the online TypeScript Playground spit out this for nm_host.js from here https://github.com/guest271314/NativeMessagingHosts/blob/main/nm_host.js

/*
#!/usr/bin/env -S /home/xubuntu/bin/deno run -A /home/xubuntu/bin/nm_host.js
#!/usr/bin/env -S /home/xubuntu/bin/node --experimental-default-type=module /home/xubuntu/bin/nm_host.js
#!/usr/bin/env -S /home/xubuntu/bin/bun run --smol /home/xubuntu/bin/nm_host.js
*/
var __asyncValues = (this && this.__asyncValues) || function (o) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var m = o[Symbol.asyncIterator], i;
    return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var g = generator.apply(thisArg, _arguments || []), i, q = [];
    return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
    function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
    function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
    function fulfill(value) { resume("next", value); }
    function reject(value) { resume("throw", value); }
    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
var _a, e_1, _b, _c;
const runtime = navigator.userAgent;
const buffer = new ArrayBuffer(0, { maxByteLength: 1024 ** 2 });
const view = new DataView(buffer);
const encoder = new TextEncoder();
const { dirname, filename, url } = import.meta;
let readable, writable, exit, args, cwd;
if (runtime.startsWith("Deno")) {
    ({ readable } = Deno.stdin);
    ({ writable } = Deno.stdout);
    ({ exit } = Deno);
    ({ args } = Deno);
}
if (runtime.startsWith("Node")) {
    const { Duplex } = await import("node:stream");
    ({ readable } = Duplex.toWeb(process.stdin));
    ({ writable } = Duplex.toWeb(process.stdout));
    ({ exit } = process);
    ({ argv: args } = process);
}
if (runtime.startsWith("Bun")) {
    readable = Bun.file("/dev/stdin").stream();
    writable = new WritableStream({
        async write(value) {
            await Bun.write(Bun.stdout, value);
        },
    }, new CountQueuingStrategy({ highWaterMark: Infinity }));
    ({ exit } = process);
    ({ argv: args } = Bun);
}
const hostdir = args.at(-2).slice(0, args.at(-2).lastIndexOf("/"));
if (runtime.startsWith("Bun") || runtime.startsWith("Node")) {
    process.chdir(hostdir);
    cwd = process.cwd();
}
if (runtime.startsWith("Deno")) {
    await Deno.chdir(hostdir);
    cwd = Deno.cwd();
}
function encodeMessage(message) {
    return encoder.encode(JSON.stringify(message));
}
function getMessage() {
    return __asyncGenerator(this, arguments, function* getMessage_1() {
        var _a, e_2, _b, _c;
        let messageLength = 0;
        let readOffset = 0;
        try {
            for (var _d = true, readable_1 = __asyncValues(readable), readable_1_1; readable_1_1 = yield __await(readable_1.next()), _a = readable_1_1.done, !_a; _d = true) {
                _c = readable_1_1.value;
                _d = false;
                let message = _c;
                if (buffer.byteLength === 0) {
                    buffer.resize(4);
                    for (let i = 0; i < 4; i++) {
                        view.setUint8(i, message[i]);
                    }
                    messageLength = view.getUint32(0, true);
                    message = message.subarray(4);
                    buffer.resize(0);
                }
                buffer.resize(buffer.byteLength + message.length);
                for (let i = 0; i < message.length; i++, readOffset++) {
                    view.setUint8(readOffset, message[i]);
                }
                if (buffer.byteLength === messageLength) {
                    yield yield __await(new Uint8Array(buffer));
                    messageLength = 0;
                    readOffset = 0;
                    buffer.resize(0);
                }
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (!_d && !_a && (_b = readable_1.return)) yield __await(_b.call(readable_1));
            }
            finally { if (e_2) throw e_2.error; }
        }
    });
}
async function sendMessage(message) {
    await new Blob([
        new Uint8Array(new Uint32Array([message.length]).buffer),
        message,
    ])
        .stream()
        .pipeTo(writable, { preventClose: true });
}
try {
    await sendMessage(encodeMessage([{ dirname, filename, url }, { cwd }, ...args]));
    try {
        for (var _d = true, _e = __asyncValues(getMessage()), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
            _c = _f.value;
            _d = false;
            const message = _c;
            await sendMessage(message);
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
        }
        finally { if (e_1) throw e_1.error; }
    }
}
catch (e) {
    exit();
}
export {};
/*
export {
  args,
  encodeMessage,
  exit,
  getMessage,
  readable,
  sendMessage,
  writable,
};
*/

So I'm gathering this is the JavaScript representation of what TypeScript outputs.

Testing the .js, with .ts extension in bun, deno work. node doesn't work with .ts extension. I'll probably use some Node.js loader code I already have to start making that so without tsc or other dependency.

Dynamic import() preserved.

I'm not in to type checking, or linting, really, but just for completeness

$ deno lint ./nm_host_ts_playground.ts
error[no-var]: `var` keyword is not allowed.
 --> /home/xubuntu/bin/nm_host_ts_playground.ts:6:1
  | 
6 | var __asyncValues = (this && this.__asyncValues) || function (o) {
  | ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-var]: `var` keyword is not allowed.
 --> /home/xubuntu/bin/nm_host_ts_playground.ts:8:5
  | 
8 |     var m = o[Symbol.asyncIterator], i;
  |     ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-var]: `var` keyword is not allowed.
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:13:1
   | 
13 | var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
   | ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-var]: `var` keyword is not allowed.
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:14:1
   | 
14 | var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
   | ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-var]: `var` keyword is not allowed.
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:16:5
   | 
16 |     var g = generator.apply(thisArg, _arguments || []), i, q = [];
   |     ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-var]: `var` keyword is not allowed.
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:26:1
   | 
26 | var _a, e_1, _b, _c;
   | ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-var]: `var` keyword is not allowed.
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:70:9
   | 
70 |         var _a, e_2, _b, _c;
   |         ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-inner-declarations]: Move variable declaration to function root
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:74:18
   | 
74 |             for (var _d = true, readable_1 = __asyncValues(readable), readable_1_1; readable_1_1 = yield __await(readable_1.next()), _a = readable_1_1.done, !_a; _d = true) {
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = hint: Move the declaration up into the correct scope

  docs: https://lint.deno.land/rules/no-inner-declarations

error[no-var]: `var` keyword is not allowed.
  --> /home/xubuntu/bin/nm_host_ts_playground.ts:74:18
   | 
74 |             for (var _d = true, readable_1 = __asyncValues(readable), readable_1_1; readable_1_1 = yield __await(readable_1.next()), _a = readable_1_1.done, !_a; _d = true) {
   |                  ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-unsafe-finally]: Unsafe usage of throw statement
   --> /home/xubuntu/bin/nm_host_ts_playground.ts:104:32
    | 
104 |             finally { if (e_2) throw e_2.error; }
    |                                ^^^^^^^^^^^^^^^^
    = hint: Use of the control flow statements (`return`, `throw`, `break` and `continue`) in a `finally` blockwill most likely lead to undesired behavior.

  docs: https://lint.deno.land/rules/no-unsafe-finally

error[no-inner-declarations]: Move variable declaration to module root
   --> /home/xubuntu/bin/nm_host_ts_playground.ts:119:14
    | 
119 |         for (var _d = true, _e = __asyncValues(getMessage()), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = hint: Move the declaration up into the correct scope

  docs: https://lint.deno.land/rules/no-inner-declarations

error[no-var]: `var` keyword is not allowed.
   --> /home/xubuntu/bin/nm_host_ts_playground.ts:119:14
    | 
119 |         for (var _d = true, _e = __asyncValues(getMessage()), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
    |              ^^^

  docs: https://lint.deno.land/rules/no-var

error[no-unsafe-finally]: Unsafe usage of throw statement
   --> /home/xubuntu/bin/nm_host_ts_playground.ts:131:28
    | 
131 |         finally { if (e_1) throw e_1.error; }
    |                            ^^^^^^^^^^^^^^^^
    = hint: Use of the control flow statements (`return`, `throw`, `break` and `continue`) in a `finally` blockwill most likely lead to undesired behavior.

  docs: https://lint.deno.land/rules/no-unsafe-finally

error[no-unused-vars]: `e` is never used
   --> /home/xubuntu/bin/nm_host_ts_playground.ts:134:8
    | 
134 | catch (e) {
    |        ^
    = hint: If this is intentional, prefix it with an underscore like `_e`

  docs: https://lint.deno.land/rules/no-unused-vars

Found 14 problems
Checked 1 file

Let's check the original .js file I wrote

deno lint ./nm_host.js
error[no-unused-vars]: `e` is never used
  --> /home/xubuntu/bin/nm_host.js:99:10
   | 
99 | } catch (e) {
   |          ^
   = hint: If this is intentional, prefix it with an underscore like `_e`

  docs: https://lint.deno.land/rules/no-unused-vars

Found 1 problem
Checked 1 file

fair enough, e is unused in the JavaScript version. I'm trying to create a TypeScript version, just for experimentation and testing.

RyanCavanaugh commented 1 month ago

Duplicate #54636, I guess? There's a lot of text here and this isn't particularly actionable as a bug report.

guest271314 commented 1 month ago

Duplicate https://github.com/microsoft/TypeScript/issues/54636, I guess?

Well, yes, I did expect resizable ArrayBuffer to be defined in TypeScript, if TypeScript claims to be a "superset" of JavaScript as specified in ECMA-262.

That's part one (1) of what's going on here. We can't get past that because TypeScript hasn't implemented resizable ArrayBuffer, yet.

Part two (2) is I want to make sure that my dynamic import() doesn't get messed with.

There's a lot of text here and this isn't particularly actionable as a bug report.

Basically I want to compile my working JavaScript to TypeScript for two purposes, 1) just to see what TypeScript spits out; 2) after I see what TypeScript spits out I will decide if TypeScript is useful or not in my lab.

As I said, I am highly skeptical of TypeScript usefulness in general, and specifically in my projects, because I know how to and enjoy writing JavaScript from scratch.

So the gist is where and how can I compile/convert my working JavaScript single script that I run in Node.js, Deno, and Bun as-is, officially, to TypeScript?

guest271314 commented 1 month ago

@RyanCavanaugh

There's a lot of text here and this isn't particularly actionable as a bug report.

It's actionable if you read the content and want to understand what's going on.

I am trying to do the opposite of what appears to be the common pattern for people that use TypeScript.

What I see is people use TypeScript to compile to JavaScript. I don't have an issue writing error-free JavaScript from scratch.

Nonetheless, I have this particular case where I have a single script that I use in multiple JavaScript runtimes.

I want to see if TypeScript brings anything useful into the script.

Long-term one of my goals is to specify and implement reading standard input streams and writing strandard output streams and handling standard error for JavaScript as a whole. So TypeScript could potentially be used to define the steps, in code, even though I could do that in JavaScript alone.

I'm basically just trying out TypeScript even though I don;t really have a use for TypeScript.

My first attempt and TypeScript, for whatever reason, is not keeping pace with JavaScript. Resizable ArrayBuffers have been shipped for a while now.

Additionally, in Deno dynamic import() throws for raw string specifier, when we dynamically create the specifier and/or script in the running script. I can reliably make Deno throw when using import(). The rationale from Deno is that TypeScript is the reason, because folks want to statically analyze even raw string specifiers for dynamic import() https://github.com/denoland/deno/issues/20945.

I want to see, from the source, you folks, if that is really a TypeScript driven reason to make import("./index.js") throw in Deno, or if it is just a Deno decision. I know Bun supports TypeScript and doesn't throw in that case. I only want to import node:stream when the script is run in Node.js, instead of creating a top-level static import as unofficial online JavaScript to TypeScript compilers might do.

Example in code Deno dynamic import("./exports") throws module not found for "exports.js" dynamically created in the script

// Deno dynamic import("./exports") throws module not found for "exports.js" dynamically created in the script
// dynamic_import_always_throws.js
// References: https://www.reddit.com/r/Deno/comments/18unb03/comment/kfsszsw/ https://github.com/denoland/deno/issues/20945
// Usage:
// deno run -A dynamic_import_always_throws.js
// bun run dynamic_import_always_throws.js
// node --experimental-default-type=module dynamic_import_always_throws.js
import { open, unlink } from "node:fs/promises";
const runtime = navigator.userAgent;
const encoder = new TextEncoder();
try {
  const script = `export default 1;`;
  // deno
  if (runtime.includes("Deno")) {
    await Deno.writeFile("exports.js", encoder.encode(script));
  }
  // node
  if (runtime.includes("Node")) {
    const dynamic = await open("./exports.js", "w");
    await dynamic.write(script);
    await dynamic.close();
  }
  // bun
  if (runtime.includes("Bun")) {
    await Bun.write("exports.js", encoder.encode(script));
  }
  const { default: module } = await import("./exports.js"); // Raw string specifier
  console.log({ module });
  console.log({ runtime });
} catch (e) {
  console.log("Deno always throws.");
  console.log({ runtime });
  console.trace();
  console.log(e.stack);
} finally {
  console.log("Finally");
  // node, bun
  if (runtime.includes("Node") || runtime.includes("Bun")) {
    await unlink("./exports.js");
  } // deno
  else if (runtime.includes("Deno")) {
    await Deno.remove("./exports.js");
  }
}

Make sense to you now?

RyanCavanaugh commented 1 month ago

Thanks for the context. This is an issue tracker for reporting bugs in TypeScript, not a support/discussion forum. If you find any additional actionable bugs, please log them separately. Thanks!

guest271314 commented 1 month ago

Then I guess this is about TypeScript not supporting resizable ArrayBuffer, and because of that TypeScript Playground throws errors, thus I can't compile JavaScript to TypeScript. That's a bug. Thank you.

guest271314 commented 1 month ago

Duplicate of https://github.com/microsoft/TypeScript/issues/54636

guest271314 commented 1 month ago

@RyanCavanaugh I figured it out https://github.com/guest271314/native-messaging-typescript. Thanks.