Skip to content

Commit

Permalink
Improve type inference to allow HKT technique function again
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed May 3, 2023
1 parent 94564cf commit 33aeffb
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
11 changes: 10 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17685,7 +17685,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// eagerly using the constraint type of 'this' at the given location.
if (isGenericIndexType(indexType) || (accessNode && accessNode.kind !== SyntaxKind.IndexedAccessType ?
isGenericTupleType(objectType) && !indexTypeLessThan(indexType, objectType.target.fixedLength) :
isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, objectType.target.fixedLength)) || isGenericReducibleType(objectType))) {
isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, objectType.target.fixedLength)) || !(accessFlags & AccessFlags.ResolveReducibleTypes) && isGenericReducibleType(objectType))) {
if (objectType.flags & TypeFlags.AnyOrUnknown) {
return objectType;
}
Expand Down Expand Up @@ -24511,6 +24511,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
}
// The following is a targeted fix to allow higher-kinded types to be emulated using the technique in #53970.
// Specifically, when an indexed access type was deferred because it has a reducible object type, here we force
// resolution of the type and then infer to the result.
if (target.flags & TypeFlags.IndexedAccess && isGenericReducibleType((target as IndexedAccessType).objectType)) {
const instantiated = getIndexedAccessType((target as IndexedAccessType).objectType, (target as IndexedAccessType).indexType, AccessFlags.ResolveReducibleTypes);
if (instantiated && instantiated !== target) {
inferFromTypes(source, instantiated);
}
}
}
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (
(source as TypeReference).target === (target as TypeReference).target || isArrayType(source) && isArrayType(target)) &&
Expand Down
19 changes: 10 additions & 9 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6593,15 +6593,16 @@ export interface TypeParameter extends InstantiableType {
export const enum AccessFlags {
None = 0,
IncludeUndefined = 1 << 0,
NoIndexSignatures = 1 << 1,
Writing = 1 << 2,
CacheSymbol = 1 << 3,
NoTupleBoundsCheck = 1 << 4,
ExpressionPosition = 1 << 5,
ReportDeprecated = 1 << 6,
SuppressNoImplicitAnyError = 1 << 7,
Contextual = 1 << 8,
Persistent = IncludeUndefined,
ResolveReducibleTypes = 1 << 1,
NoIndexSignatures = 1 << 2,
Writing = 1 << 3,
CacheSymbol = 1 << 4,
NoTupleBoundsCheck = 1 << 5,
ExpressionPosition = 1 << 6,
ReportDeprecated = 1 << 7,
SuppressNoImplicitAnyError = 1 << 8,
Contextual = 1 << 9,
Persistent = IncludeUndefined | ResolveReducibleTypes,
}

// Indexed access types (TypeFlags.IndexedAccess)
Expand Down

0 comments on commit 33aeffb

Please sign in to comment.