Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enum in return position have wrong type #3864

Open
sigmaSd opened this issue Mar 1, 2024 · 3 comments
Open

enum in return position have wrong type #3864

sigmaSd opened this issue Mar 1, 2024 · 3 comments
Labels

Comments

@sigmaSd
Copy link

sigmaSd commented Mar 1, 2024

Describe the Bug

rust enums in return position are typed as object, but at runtime they're just a number

Steps to Reproduce

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub enum A {
    B,
    C,
}

#[wasm_bindgen]
pub fn b() -> A {
    return A::B;
}
import { b } from "./dist/b.js";

console.log(typeof b()); //number
console.log(b() === 0); 
error: TS2367 [ERROR]: This comparison appears to be unintentional because the types 'Readonly<{ B: 0; "0": "B"; C: 1; "1": "C"; }>' and 'number' have no overlap.
console.log(b() === 0);
            ~~~~~~~~~

wasm-bindgen 0.2.91

@sigmaSd sigmaSd added the bug label Mar 1, 2024
@Liamolucko
Copy link
Collaborator

Weird. I think this is the bit of the generated code causing the issue:

/**
* @returns {A}
*/
export function b() {
    const ret = wasm.b();
    return ret;
}

/**
*/
export const A = Object.freeze({ B:0,"0":"B",C:1,"1":"C", });

It seems like TypeScript is interpreting the @returns {A} as @returns {typeof A} for some reason.

Is this happening in Deno? I can reproduce it with Deno, but not with plain TSC, I think because TSC automatically checks for b.d.ts and Deno doesn't. If it is, you can get Deno to use the proper type annotations instead of the JSDoc ones with @deno-types:

// @deno-types="./dist/b.d.ts"
import { b } from "./dist/b.js";

console.log(typeof b()); //number
console.log(b() === 0); 

There are 2 approaches to solving this properly:

  1. Add @enum {number} to export const A. This isn't as good as it being a real TypeScript enum, it basically just declares type A = number but it fixes the error.
  2. Add a /// <reference types="..." /> to the JS file when using --target deno so that Deno can pick up the proper type declarations in the first place.

Probably we should do both, since the JSDoc declarations should work if necessary (e.g. --no-typescript is passed) but then the TypeScript declarations should be used if available.

@sigmaSd
Copy link
Author

sigmaSd commented Mar 2, 2024

Yes it's in Deno, I didn't think it's related thank fo investigating, is Deno behavior correct here or should I open a bug report ?

@Liamolucko
Copy link
Collaborator

No, Deno's behaviour is correct. One of their goals is not to magically look up extra files since that might be wasting extra network requests, and so they differ from tsc here. tsc gives the same error if you delete the .d.ts file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants