Skip to content

Commit a8964cb

Browse files
committed
Type parameter with 'unknown' constraint not assignable to '{}'
1 parent 34d9d4b commit a8964cb

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12168,10 +12168,6 @@ namespace ts {
1216812168
return result;
1216912169
}
1217012170

12171-
function getConstraintForRelation(type: Type) {
12172-
return relation === definitelyAssignableRelation ? undefined : getConstraintOfType(type);
12173-
}
12174-
1217512171
function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, isIntersectionConstituent: boolean): Ternary {
1217612172
const flags = source.flags & target.flags;
1217712173
if (relation === identityRelation && !(flags & TypeFlags.Object)) {
@@ -12304,23 +12300,25 @@ namespace ts {
1230412300
return result;
1230512301
}
1230612302
}
12307-
const constraint = getConstraintForRelation(<TypeParameter>source);
12308-
if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.AnyOrUnknown)) {
12309-
// A type variable with no constraint is not related to the non-primitive object type.
12310-
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
12311-
errorInfo = saveErrorInfo;
12312-
return result;
12303+
if (relation !== definitelyAssignableRelation) {
12304+
const constraint = getConstraintOfType(<TypeParameter>source);
12305+
if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
12306+
// A type variable with no constraint is not related to the non-primitive object type.
12307+
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
12308+
errorInfo = saveErrorInfo;
12309+
return result;
12310+
}
1231312311
}
12314-
}
12315-
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
12316-
else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
12312+
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
12313+
else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
12314+
errorInfo = saveErrorInfo;
12315+
return result;
12316+
}
12317+
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
12318+
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
1231712319
errorInfo = saveErrorInfo;
1231812320
return result;
12319-
}
12320-
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
12321-
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
12322-
errorInfo = saveErrorInfo;
12323-
return result;
12321+
}
1232412322
}
1232512323
}
1232612324
else if (source.flags & TypeFlags.Index) {

0 commit comments

Comments
 (0)