Skip to content

Broken inference of empty object as Record #39630

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

Closed
javiertury opened this issue Jul 17, 2020 · 2 comments
Closed

Broken inference of empty object as Record #39630

javiertury opened this issue Jul 17, 2020 · 2 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@javiertury
Copy link

TypeScript Version: 3.9.7

Search Terms: empty object, broken inference, Record

Code

export class Bar <
  Key extends string,
  Value extends string
> {
  get foo (): Record<Key, Value> {
    return {}; // [tsserver 2322] [E] Type '{}' is not assignable to type 'Record<Key, Value>'.
  }
}

Expected behavior:

The empty object type should be inferred as Record<Key, Value>

Actual behavior:

[tsserver 2322] [E] Type '{}' is not assignable to type 'Record<Key, Value>'.

Playground Link:

https://www.typescriptlang.org/play/#code/KYDwDg9gTgLgBAYwDYEMDOa4CEVTgHgCg44BpYATzlBmADsATTNGKASzoHMAaYuANRRIArsGohajZqw6dCAPjgBvPp2DwAZhAhwAFAEoAXHABKwBNAb5yFbgKGjFKkiSjrhUOsoC+Abj7ehN5AA

I used the default version in the playground because the nightly version is completely broken and very slow.

Cannot find name 'Record'.(2304)
Return type of public getter 'foo' from exported class has or is using private name 'Record'.(4043)

Related Issues:

This problem is similar but not equal to #14930

@RyanCavanaugh
Copy link
Member

This is a correct error.

export class Bar <
  Key extends string,
  Value extends string
> {
  get foo (): Record<Key, Value> {
    return {}; // [tsserver 2322] [E] Type '{}' is not assignable to type 'Record<Key, Value>'.
  }
}
const k = new Bar<"bla", "baz">();
// No error, crashes
k.foo.bla.toLowerCase();

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jul 17, 2020
@javiertury
Copy link
Author

javiertury commented Jul 17, 2020

I thought Record didn't require the property to be defined. Most of the time it's used like this:

type Foo = Record<string, number>;
const foo: Foo = {}; // Ok

But investigating further I see that you are right and this is the expected behavior when the key is a string literal union. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants