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

Regression in invalid-computed-prop detection #9141

Closed
Robloche opened this issue Apr 30, 2024 · 7 comments
Closed

Regression in invalid-computed-prop detection #9141

Robloche opened this issue Apr 30, 2024 · 7 comments

Comments

@Robloche
Copy link

Flow version: 0.235.1

Expected behavior

My code looks like this:

type Dict<T> = {| [string]: T |};
export type BoolDict = Dict<bool>;

Then, in another file, I have:

const bd: BoolDict = { foo: true };
const k = 'foo';
const {[k]: v} = bd;

Until flow-bin v0.234.0, no error was raised.

Actual behavior

Since I upgraded to flow-bin v0.235.1, the line const {[k]: v} = bd; raises the following error:

Cannot access object with computed property using string [1]. [invalid-computed-prop]
[1] k: string,

I tried to reproduce on flow.org/try but to no avail.

But I tried the following code, which does not raise any error:

export type BoolDict = {| [string]: bool |};

The other part remains unchanged:

const bd: BoolDict = { foo: true };
const k = 'foo';
const {[k]: v} = bd;

So my guess is it has something to do with the generic type, or the export, or a combination of both.

Thanks for your help.

@SamChou19815
Copy link
Contributor

This is due to the fact that things like

declare const obj: {foo: string};
declare const key: string;
obj[key]

are never safe, and just returns any before. In the latest Flow version, we choose to start loudly error.

@gkz
Copy link
Member

gkz commented Apr 30, 2024

I tried your initial example, locally over two files, and was not able to reproduce the error.

@Robloche
Copy link
Author

Robloche commented May 2, 2024

I struggled a bit but I eventually understood what I did wrong.
Thanks for your answer, @SamChou19815!

@Robloche
Copy link
Author

Robloche commented May 2, 2024

Well, there's still something bothering me.
What about this example:

enum MyEnum {
    ValFoo = 'foo',
    ValBar = 'bar'
}

declare const obj: {foo: string, bar: string};
declare const key: string;
obj[MyEnum.ValFoo as string]

Why doesn't it work, since MyEnum.ValFoo as string is indeed the string "foo"?

@Robloche
Copy link
Author

Robloche commented May 2, 2024

In fact, I still don't understand the difference between (1):

type Dict<T> = {| [string]: T |};
export type BoolDict = Dict<bool>;

and (2):

export type BoolDict = {| [string]: bool |};

The following code does not work with (1) but is OK with (2):

const bd: BoolDict = { foo: true };
const k = 'foo';
const {[k]: v} = bd;

@SamChou19815
Copy link
Contributor

The enum example is an issue with enum feature. The right solution is to support enum key rather than continue to allow this unsafe access.

In fact, I still don't understand the difference between (1):

type Dict<T> = {| [string]: T |};
export type BoolDict = Dict<bool>;

and (2):

export type BoolDict = {| [string]: bool |};

The following code does not work with (1) but is OK with (2):

const bd: BoolDict = { foo: true };
const k = 'foo';
const {[k]: v} = bd;

I am still unable to reproduce this? Can you provide a try-flow link?

@Robloche
Copy link
Author

Robloche commented May 2, 2024

Unfortunately, I can't.
I think it has something to do with export & import and only fails when the code is spread across multiple files, because it works correctly in try-flow.

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

No branches or pull requests

3 participants