From 550e11e009aa9a2e1d18332747a984e2ffae9d03 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 11 Jul 2024 21:00:07 +0000 Subject: [PATCH] Avoid caching long-ish string literal types from expressions. --- src/compiler/checker.ts | 43 ++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 86851cd9648..2b4ed3192c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19618,10 +19618,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return !!(type.flags & TypeFlags.Freshable) && (type as LiteralType).freshType === type; } - function getStringLiteralType(value: string): StringLiteralType { - let type; - return stringLiteralTypes.get(value) || - (stringLiteralTypes.set(value, type = createLiteralType(TypeFlags.StringLiteral, value) as StringLiteralType), type); + function getStringLiteralType(value: string, avoidCache?: boolean): StringLiteralType { + let type = stringLiteralTypes.get(value); + if (type === undefined) { + type = createLiteralType(TypeFlags.StringLiteral, value) as StringLiteralType; + } + if (!avoidCache) { + stringLiteralTypes.set(value, type); + } + return type; } function getNumberLiteralType(value: number): NumberLiteralType { @@ -21521,7 +21526,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (t & TypeFlags.Never) return false; if (s & TypeFlags.StringLike && t & TypeFlags.String) return true; if ( - s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral && + s & TypeFlags.StringLiteral && t & TypeFlags.StringLiteral && !(t & TypeFlags.EnumLiteral) && (source as StringLiteralType).value === (target as StringLiteralType).value ) return true; @@ -24860,17 +24865,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return t.flags & TypeFlags.Intersection ? some((t as IntersectionType).types, isUnitType) : isUnitType(t); } - function typeMayWitnessLiteralTypes(target: Type): boolean { - if (target.flags & TypeFlags.Union) { - return some((target as UnionType).types, typeMayWitnessLiteralTypes); - } - - // We do not account for `any` because `getContextFreeTypeOfExpression` - // specifically pushes a cached `any`. - const nonBaseFlags = ~(TypeFlags.Unknown | TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt | TypeFlags.Never | TypeFlags.Nullable); - return (target.flags & nonBaseFlags) !== 0; - } - function extractUnitType(type: Type) { return type.flags & TypeFlags.Intersection ? find((type as IntersectionType).types, isUnitType) || type : type; } @@ -40595,24 +40589,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return nullWideningType; case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.StringLiteral: { - const contextualType = getContextualType(node, ContextFlags.NoConstraints); - if (contextualType !== undefined && !typeMayWitnessLiteralTypes(contextualType)) return stringType; - + const stringLiteralText = (node as StringLiteralLike).text; return hasSkipDirectInferenceFlag(node) ? blockedStringType : - getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text)); + getFreshTypeOfLiteralType( + getStringLiteralType( + stringLiteralText, + /*avoidCache*/ stringLiteralText.length >= 32 && node.parent.kind !== SyntaxKind.LiteralType, + ), + ); } case SyntaxKind.NumericLiteral: { - const contextualType = getContextualType(node, ContextFlags.NoConstraints); - if (contextualType !== undefined && !typeMayWitnessLiteralTypes(contextualType)) return numberType; - checkGrammarNumericLiteral(node as NumericLiteral); return getFreshTypeOfLiteralType(getNumberLiteralType(+(node as NumericLiteral).text)); } case SyntaxKind.BigIntLiteral: - const contextualType = getContextualType(node, ContextFlags.NoConstraints); - if (contextualType !== undefined && !typeMayWitnessLiteralTypes(contextualType)) return bigintType; - checkGrammarBigIntLiteral(node as BigIntLiteral); return getFreshTypeOfLiteralType(getBigIntLiteralType({ negative: false,