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

Static class properties not fitting into index signature types #42401

Closed
tetranoir opened this issue Jan 19, 2021 · 6 comments
Closed

Static class properties not fitting into index signature types #42401

tetranoir opened this issue Jan 19, 2021 · 6 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@tetranoir
Copy link

tetranoir commented Jan 19, 2021

Bug Report

🔎 Search Terms

static class index signature missing

🕗 Version & Regression Information

Tested on 3.9 and 4.2

Please keep and fill in the line that best applies:

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about static classes

⏯ Playground Link

Playground link with relevant code

💻 Code

class D {
  static a = 'a';
}

class E {
  static E = {a: 'a'};
}

const F = {
  a: 'a',
};

function fn1<T extends {a: string}>(arg: T) {}
fn1(D);
fn1(E.E);
fn1(F);


function fn2<T extends {[k: string]: string}>(arg: T) {}
fn2(D);  // errors
fn2({ ...D });  // errors
fn2(Object.assign({}, D));  // errors
fn2(E.E);
fn2(F);

🙁 Actual behavior

Each line here

fn2(D);
fn2({ ...D });
fn2(Object.assign({}, D));

errors

Argument of type 'typeof D' is not assignable to parameter of type '{ [k: string]: string; }'.
  Index signature is missing in type 'typeof D'.

🙂 Expected behavior

No type errors. Or at least no errors for { ...D } and Object.assign({}, D) because those both result in { a: 'a' }, without the prototype or new().

@tetranoir
Copy link
Author

My workaround for this esoteric problem has been to create a static property const object with all properties I would have put into the static class.

class D {
  static a = 'a';
}

becomes

class D {
  static _ = { a: 'a' };
}

@MartinJohns
Copy link
Contributor

Possibly related: #6480 / #37797

@RyanCavanaugh
Copy link
Member

There are places where we allow a string index signature to be inferred, and places we don't. The general principle is that declaration merging should not be able to induce an error due to index signature violation, and as you can see from where the errors occur, that's correctly happening.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jan 20, 2021
@tetranoir
Copy link
Author

But, I think fn2({ ...D });should at least work because in object copying, the prototype is stripped out.

@RyanCavanaugh
Copy link
Member

Declaration merging could allow non-prototype writes that would invalidate the signature

@tetranoir
Copy link
Author

tetranoir commented Jan 21, 2021

Makes sense. Thanks for the explanation!

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

3 participants