microsoft/TypeScript

bug: const type parameter does not work with anonymous classes

Closed this issue ยท 6 comments

๐Ÿ”Ž Search Terms

const type generic parameter class anonymous

๐Ÿ•— Version & Regression Information

  • I was unable to test this on prior versions because it is a TypeScript 5 new feature.

โฏ Playground Link

https://www.typescriptlang.org/play/?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwxAGcMAeMPE+ANXhAA9DVgj4cAjAK3AwD4AKAG5QIyEAC4aASknUA3ACgFFVFWEQsweAF4CxDPwDeSHDkkBtAOTtYlgLrwAvlMXLKGeCSjYwASVTqmjp6JPyQUESshgrwsfAA9PHwAKIwMDgwkgAqAMoA7AAMAExF8JaIppbwWAC2AA4aYFgYEACe8AAWEQStdQiWUKitVezgUMhECM3wwDjE8Kg4Hl2CCFA9ffCDixjeuPiDWliscIggcOggWsBYcJhtbDDVzLc8D1j4zaw4AO6fqM0sCIsAAvc4AOhicS8PngcCgs1QDwqOGCVhsMHsimcrhUVA+Xku-kCWl0hFC4Ui8GicThIAReGRpjR1lsdmxLgUiXgxOBWgwvQkngwMA+AHNzA4CYQEWxEPB0WyFKgQD9noSwCBeRpgPwpOCUQogA

๐Ÿ’ป Code

declare function test<const V extends object>(value: V): V;

const valid = test({ foo: ['bar'] });

const staticInvalid = test(class {
    // Error: TS7022 'foo' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
    static readonly foo = ['bar'];
});

const instanceInvalid = test(class {
    readonly foo = ['bar'];
});
// Invalid type: string[] instead of ['bar']
new instanceInvalid().foo

๐Ÿ™ Actual behavior

  • TS7022 error appears on the static foo property.
  • Type is string[] on the instance foo property.

๐Ÿ™‚ Expected behavior

No error should be emitted, and static/instance foo properties should have the same type as with an object literal: ['bar'].

Additional information about the issue

In practice, both object literal and class static array properties could be changed.
But if const type parameters work on object literal, why not on classes static/instance properties?

It seems like this is a minimal repro of what you're describing? No const needed

declare function test<V>(value: V): V;
const staticInvalid = test(class {
    static foo = ['bar'];
});

Yes, this is it! Didn't even seen that!

from the reported circularity's PoV this is a duplicate of #62552 , but the related PR only fixes the circularity, it doesn't make either of those fields benefit from the const type parameter

I'd probably say that using class expressions with const type parameters is rather esoteric and not worth working on. It's also consistent with as const, class expressions can't be its target:

// A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.(1355)
const Cls = class {
    readonly foo = ['bar'];
} as const;

If somebody would like to change it... they'd have to figure a change that would address what I'm describing here. The main problem there is that the properties of a class expression are checked in a deferred manner and that's outside of the inference context. So there is no clear way of checking if the class expression is contextually typed by a const type variable (cause at that point it's contextually typed by itself)

@Andarist this looks fair IMO since as const is not available for classes (or if implemented, it should be available on both const type and as const).

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.