Skip to content

Commit d0a195a

Browse files
committed
Propagate type comparer function in contextual signature instantiation
1 parent 48d5485 commit d0a195a

File tree

3 files changed

+26
-21
lines changed

3 files changed

+26
-21
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8017,7 +8017,7 @@ namespace ts {
80178017

80188018
function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
80198019
return mapper && isInferenceContext(mapper) ?
8020-
createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.inferences) :
8020+
createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.compareTypes, mapper.inferences) :
80218021
mapper;
80228022
}
80238023

@@ -8458,7 +8458,7 @@ namespace ts {
84588458
ignoreReturnTypes: boolean,
84598459
reportErrors: boolean,
84608460
errorReporter: ErrorReporter,
8461-
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
8461+
compareTypes: TypeComparer): Ternary {
84628462
// TODO (drosen): De-duplicate code between related functions.
84638463
if (source === target) {
84648464
return Ternary.True;
@@ -8468,7 +8468,7 @@ namespace ts {
84688468
}
84698469

84708470
if (source.typeParameters) {
8471-
source = instantiateSignatureInContextOf(source, target);
8471+
source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes);
84728472
}
84738473

84748474
let result = Ternary.True;
@@ -10216,13 +10216,14 @@ namespace ts {
1021610216
}
1021710217
}
1021810218

10219-
function createInferenceContext(signature: Signature, flags: InferenceFlags, baseInferences?: InferenceInfo[]): InferenceContext {
10219+
function createInferenceContext(signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
1022010220
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo);
1022110221
const context = mapper as InferenceContext;
1022210222
context.mappedTypes = signature.typeParameters;
1022310223
context.signature = signature;
1022410224
context.inferences = inferences;
1022510225
context.flags = flags;
10226+
context.compareTypes = compareTypes || compareTypesAssignable;
1022610227
return context;
1022710228

1022810229
function mapper(t: Type): Type {
@@ -10670,7 +10671,7 @@ namespace ts {
1067010671
const constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]);
1067110672
if (constraint) {
1067210673
const instantiatedConstraint = instantiateType(constraint, context);
10673-
if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
10674+
if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
1067410675
inference.inferredType = inferredType = instantiatedConstraint;
1067510676
}
1067610677
}
@@ -15071,8 +15072,8 @@ namespace ts {
1507115072
}
1507215073

1507315074
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
15074-
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper): Signature {
15075-
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes);
15075+
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature {
15076+
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes, compareTypes);
1507615077
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
1507715078
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
1507815079
inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);

src/compiler/core.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,6 @@ namespace ts {
1111

1212
/* @internal */
1313
namespace ts {
14-
/**
15-
* Ternary values are defined such that
16-
* x & y is False if either x or y is False.
17-
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
18-
* x & y is True if both x and y are True.
19-
* x | y is False if both x and y are False.
20-
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
21-
* x | y is True if either x or y is True.
22-
*/
23-
export const enum Ternary {
24-
False = 0,
25-
Maybe = 1,
26-
True = -1
27-
}
2814

2915
// More efficient to create a collator once and use its `compare` than to call `a.localeCompare(b)` many times.
3016
export const collator: { compare(a: string, b: string): number } = typeof Intl === "object" && typeof Intl.Collator === "function" ? new Intl.Collator(/*locales*/ undefined, { usage: "sort", sensitivity: "accent" }) : undefined;

src/compiler/types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,11 +3425,29 @@ namespace ts {
34253425
AnyDefault = 1 << 2, // Infer anyType for no inferences (otherwise emptyObjectType)
34263426
}
34273427

3428+
/**
3429+
* Ternary values are defined such that
3430+
* x & y is False if either x or y is False.
3431+
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
3432+
* x & y is True if both x and y are True.
3433+
* x | y is False if both x and y are False.
3434+
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
3435+
* x | y is True if either x or y is True.
3436+
*/
3437+
export const enum Ternary {
3438+
False = 0,
3439+
Maybe = 1,
3440+
True = -1
3441+
}
3442+
3443+
export type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary;
3444+
34283445
/* @internal */
34293446
export interface InferenceContext extends TypeMapper {
34303447
signature: Signature; // Generic signature for which inferences are made
34313448
inferences: InferenceInfo[]; // Inferences made for each type parameter
34323449
flags: InferenceFlags; // Inference flags
3450+
compareTypes: TypeComparer; // Type comparer function
34333451
}
34343452

34353453
/* @internal */

0 commit comments

Comments
 (0)