From eb1e7ec6db612b87e8fc087eb2ba5abd2e050522 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 8 Apr 2019 09:36:34 -1000 Subject: [PATCH] Optimize T[K] where T has string index signature and no other members --- src/compiler/checker.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 94e9fd30a79..955dacfbb89 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10145,6 +10145,11 @@ namespace ts { if (objectType === wildcardType || indexType === wildcardType) { return wildcardType; } + // If the object type has a string index signature and no other members we know that the result will + // always be the type of that index signature and we can simplify accordingly. + if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { + indexType = stringType; + } // If the index type is generic, or if the object type is generic and doesn't originate in an expression, // we are performing a higher-order index access where we cannot meaningfully access the properties of the // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in @@ -12022,6 +12027,12 @@ namespace ts { return !!(getObjectFlags(type) & ObjectFlags.Anonymous) && isEmptyObjectType(type); } + function isStringIndexSignatureOnlyType(type: Type): boolean { + return type.flags & TypeFlags.Object && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, IndexKind.String) && !getIndexInfoOfType(type, IndexKind.Number) || + type.flags & TypeFlags.UnionOrIntersection && every((type).types, isStringIndexSignatureOnlyType) || + false; + } + function isEnumTypeRelatedTo(sourceSymbol: Symbol, targetSymbol: Symbol, errorReporter?: ErrorReporter) { if (sourceSymbol === targetSymbol) { return true;