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

Error 2339 with nullish coalescing to empty object #51665

Open
KuSh opened this issue Nov 28, 2022 · 3 comments
Open

Error 2339 with nullish coalescing to empty object #51665

KuSh opened this issue Nov 28, 2022 · 3 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@KuSh
Copy link

KuSh commented Nov 28, 2022

Bug Report

πŸ”Ž Search Terms

2339 Property does not exist on type empty object

πŸ•— Version & Regression Information

Tested on 4.2.3 (version we use on our project) and 4.8.4 (latest available in playground)

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

const ok = (): null | { [param: string]: string } => Math.random() > .5 ? null : {};
const ko = (): null | { uri: string; path: string; [param: string]: string } => Math.random() > .5 ? null : { uri: '', path: '' };

{
    // no errors
    const { oid, pid } = ok() ?? {};
}

{
    // error 2339 - Property does not exist on type '{ [param: string]: string; uri: string; path: string; } | {}'
    const { oid, pid } = ko() ?? {};
}

This is a simplified test case. I did encounter error while using @reach/router useMatch hook API

πŸ™ Actual behavior

Error Property does not exist on type '{ [param: string]: string; uri: string; path: string; } | {}' (2339)

πŸ™‚ Expected behavior

No error expected

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Dec 1, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 1, 2022
@SquareByte
Copy link

After replacing the ?? operator with older-style code I still get an error (TS4.9.5):

const ko_result = ko();
const assert_some_obj = ko_result === null ? {} : ko_result; // same for `ko_result || {}`
const { oid, pid } = assert_some_obj;
// Property 'pid' does not exist on type '{}'. ts(2339)

This is correct, isn't it?

With the same rewrite this also gives no error in the case of the ok() function though. But I'd rather expect an error in both cases and ideally with the union type boiled down to the second union member:

πŸ™‚ Expected behavior

Error Property does not exist on type '{}' (2339) in both examples.


PS:

const { pid } = {};
// Initializer provides no value for this binding element and the binding element has no default value. ts(2525)
// Binding element 'pid' implicitly has an 'any' type. ts(7031)

So this does not look like fully sane code anyway.

@kirkwaiblinger
Copy link

kirkwaiblinger commented Sep 9, 2024

Note that there is a pretty organic repro occurring with regexp parsing:

const re = /.*/;
const str = "matched";

const result = re.exec(str);
if (result != null) {
    const { namedGroup } = result.groups ?? {};
    console.log(namedGroup.toLowerCase()); // runtime error!
}

(playground link)

@kirkwaiblinger
Copy link

kirkwaiblinger commented Sep 9, 2024

(for a more minimal repro)

// this issue is specifically triggered by index signatures
declare const maybeIndexable: { [key: string]: string} | undefined
const { anyThing } = maybeIndexable ?? {};
console.log(anyThing.toLowerCase()); // runtime error!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

4 participants