TypeScript: Regression: 2.4.1 Generic type mismatch
This is a simplified piece of code which demonstrates the problem. It compiles fine in 2.3.4 & 2.4.0, but produces a not assignable error in 2.4.1 and nightly.
TypeScript Version: 2.4.1 / nightly (2.5.0-dev.20170629)
Code
interface MyInterface {
something: number;
}
class MyClass<T extends MyInterface> {
doIt(data : Partial<T>) {}
}
class MySubClass extends MyClass<MyInterface> {}
function fn(arg: typeof MyClass) {};
fn(MySubClass);
Expected behavior:
No compile error.
Actual behavior:
test.ts(13,4): error TS2345: Argument of type 'typeof MySubClass' is not assignable to parameter of type 'typeof MyClass'.
Type 'MySubClass' is not assignable to type 'MyClass<T>'.
Types of property 'doIt' are incompatible.
Type '(data: Partial<MyInterface>) => void' is not assignable to type '(data: Partial<T>) => void'.
Types of parameters 'data' and 'data' are incompatible.
Type 'Partial<T>' is not assignable to type 'Partial<MyInterface>'.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 37 (14 by maintainers)
This fixes the urgent symptom of the problem, but doesn’t seem to address the underlying problem. To wit: the new generic checks don’t seem to play nicely with class generics and subclasses. My entire data model is predicated on having a generic Model<DataSchema> class to represent a data model and its actions (get / set / reset / etc), and then the user subclassing Model with a concrete instance of Schema, so we know the specific shape of the data returned by get().
I’d prefer to write canonical TS, not stuff that only builds if you turn off default compiler settings.
An
extendsclause requires its argument to be a type reference (a type name possibly followed by type arguments in angle brackets), but you can always satisfy this syntactic restriction by declaring a type alias for the particular type. However, even if you extend (an alias for)typeof UIComponentyou still end up with the constructor signatures from that type, and new ones you add just become additional overloads. But that you could work around by applying a mapped type (which filters out all non-public members and all call and construct signatures). So, this appears to do the trick:@mat3e
@estaub
TestBase<DefinitionBase>is an instance type (members = properties)typeof TestBaseis a class type (members = static properties + constructor)Hi,
since TS 2.4.1, I’m facing errors when using type inference with generic functions.
Example:
Expected result: Both,
TandUshould be inferred to be typestring.Actual result:
tscproduces the following output:Affected versions: 2.4.1 & 2.42
Workaround: I can workaround the described error by setting
noStrictGenericCheckstotrue.I use this pattern quite often to describe a common type interface, which can be configured with concrete implementations. And therefore, I relying on the type inference system in these cases.
Can someone please tell me if this is related to this issue or if I should open a new issue for the problem, of if this is an error at all!?
Thanks in advance 😄
@ericeslinger - yeah, definitely looks like the same kind of problem.
Using
anyis not a solution I would like to use 😃@ikatyang , Mmm, thank you for your explanation, I think I have some misunderstanding about
typeofoperator in TS. Maybe in my case I should change the code to:@estaub
This is true, but if there are some generics, for example:
If
AextendsB<T>Istypeof Aassignable totypeof B?If
typeof Bis consideredtypeof B<any>, thentypeof Ais assignable totypeof BIftypeof Bis consideredtypeof B<T>, thentypeof Ais not assignable totypeof BThis is all about how strict it should be, I have no idea if this is a bug or not.
@Saviio
typeofis a value-level operator, so thattypeof Baseis still consideredtypeof Base<P>instead oftypeof Base<{}>, the following cases are passed, see my comment above for more detail.Reduced reproduction:
@mat3e That error actually looks right to me, but my attempted “fix” for it produces an even stranger error, IMHO.
Changing
AllTestClassesto:results in:
I’m having a similar issue. Seems like stricter checks on generics and
typeofare not the perfect match.Errors:
The only way to make it work with TS 2.4.1 is to use
"noStrictGenericChecks": trueoption. Hard to apply the workaround from @ikatyang…