You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
typeAnyCtor=new(...a: any[])=>anyfunctionFoo<TextendsAnyCtor>(Base: T){returnclassFooextendsBase{foo(){}}}functionBar<TextendsAnyCtor>(Base: T){returnclassBarextendsBase{bar(){}}}functionOne<TextendsAnyCtor>(Base: T){returnclassOneextendsBase{one(){}}}functionTwo<TextendsAnyCtor>(Base: T){returnclassTwoextendsBase{two(){}}}functionThree<TextendsAnyCtor>(Base: T){returnclassThreeextendsOne(Two(Base)){three(){}}}classMyClassextendsThree(Foo(Bar(Object))){test(){// @ts-expect-errorthis.foo(123)// @ts-expect-errorthis.bar(123)// @ts-expect-error // ERRORthis.one(123)// this.one is type `any`!// @ts-expect-error // ERRORthis.two(123)// this.two is type `any`!// @ts-expect-errorthis.three(123)console.log('no runtime errors')}}constm=newMyClass()m.test()
Expected behavior:
There should be an error on all the lines marked with // @ts-expect-error
Actual behavior:
There is no type error on the lines with this.one and this.two because this.one and this.two are seen as type any.
The expectation is that the one and two methods have the proper type (with zero parameters) which would therefore cause a type error from passing in arguments.
Someone from the Discord chat thought perhaps #29571might be related, but not with 100% certainty. They do however think this is a bug.
Ultimately, making mixins in TypeScript is too hard. It's too easy to get them wrong and they become a very inconvenient in TypeScript (whereas they are very convenient in plain JavaScript).
The following might be a hint at the bug: when we change type AnyCtor = new (...a: any[]) => any to type AnyCtor = new (...a: any[]) => object, then the example works as expected:
It doesn't seem that a generic constraint should dictate what the type of a generic arg actually is. It seems a generic arg should only be constrained. Once a generic arg passes the constraint and is allowed to be passed in, then the type of the generic parameter should be based on what the passed-in arg's type actually is, not what it is constrained to.
I'd say this is a bug, because regardless if the constructor return constraint is any or object, it should be the actual T that informs the final type. That's my feeling from an end user perspective.
TypeScript Version: 3.9.2
Search Terms:
typescript mixin method is any
Code
Expected behavior:
There should be an error on all the lines marked with
// @ts-expect-error
Actual behavior:
There is no type error on the lines with
this.one
andthis.two
becausethis.one
andthis.two
are seen as typeany
.The expectation is that the
one
andtwo
methods have the proper type (with zero parameters) which would therefore cause a type error from passing in arguments.Playground Link
Related Issues:
Someone from the Discord chat thought perhaps #29571 might be related, but not with 100% certainty. They do however think this is a bug.
Ultimately, making mixins in TypeScript is too hard. It's too easy to get them wrong and they become a very inconvenient in TypeScript (whereas they are very convenient in plain JavaScript).
Also related: #32080
The text was updated successfully, but these errors were encountered: