-
Notifications
You must be signed in to change notification settings - Fork 13k
Open
Labels
Help WantedYou can do thisYou can do thisPossible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some casesThe current behavior isn't wrong, but it's possible to see that it might be better in some cases
Milestone
Description
🔎 Search Terms
generic, type parameter, extends, arbitrary type which could be unrelated, assignment
🕗 Version & Regression Information
- This changed between versions TS 3.8.3 and TS 3.9.7 (well, the pre-3.9 message isn't perfect, tbh but it only becomes fully wrong after that)
⏯ Playground Link
💻 Code
function parameterExtendsOtherParameter<SuperType, SubType extends SuperType>(superType: SuperType, subType: SubType) {
// TS 3.3: Type 'SuperType' is not assignable to type 'SubType'.
//
// TS 3.5: Type 'SuperType' is not assignable to type 'SubType'.
// 'SuperType' is assignable to the constraint of type 'SubType', but 'SubType' could be instantiated with a different subtype of constraint '{}'.
//
// TS 3.9: Type 'SuperType' is not assignable to type 'SubType'.
// 'SubType' could be instantiated with an arbitrary type which could be unrelated to 'SuperType'.
//
// TS 4.8: Type 'SuperType' is not assignable to type 'SubType'.
// 'SubType' could be instantiated with an arbitrary type which could be unrelated to 'SuperType'.
// input.tsx(1, 41): This type parameter might need an `extends V` constraint.
subType = superType;
}
🙁 Actual behavior
Type 'SuperType' is not assignable to type 'SubType'.
'SubType' could be instantiated with an arbitrary type which could be unrelated to 'SuperType'.
input.tsx(1, 41): This type parameter might need an `extends SubType` constraint.
The misleading thing here is that SubType
plainly cannot be unrelated to SuperType
. It's guaranteed to be a subtype of SuperType
, since it extends SuperType
.
🙂 Expected behavior
The TS 3.5 error message was nearly there (just swapped {}
for SuperType
)...
Type 'SuperType' is not assignable to type 'SubType'.
'SuperType' is assignable to the constraint of type 'SubType', but 'SubType' could be instantiated with a different subtype of constraint 'SuperType'.
I might suggest something like this instead though:
type 'SuperType' is not assignable to type 'SubType'.
'SubType' is constrained to be a subtype of 'SuperType'.
input.tsx: You might have swapped the left and right hand sides of the assignment.
This is nearly a garden-variety instance of assigning a wider type to a narrower type, it just looks tricky because of the presence of generics and extends
.
Additional information about the issue
contrast with this example:
(playground)
function parameterExtendsOrdinaryType<StringSubType extends string>(s: string, subType: StringSubType) {
// Type 'string' is not assignable to type 'StringSubType'.
// 'string' is assignable to the constraint of type 'StringSubType', but 'StringSubType' could be instantiated with a different subtype of constraint 'string'
subType = s;
}
cc @controversial (discovered in typescript-eslint/typescript-eslint#10461 (comment))
Metadata
Metadata
Assignees
Labels
Help WantedYou can do thisYou can do thisPossible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some casesThe current behavior isn't wrong, but it's possible to see that it might be better in some cases