diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fdb9f928928..3c8c0be77c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -142,7 +142,6 @@ namespace ts { const voidType = createIntrinsicType(TypeFlags.Void, "void"); const neverType = createIntrinsicType(TypeFlags.Never, "never"); const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); - const stringOrNumberType = getUnionType([stringType, numberType]); const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -3219,6 +3218,8 @@ namespace ts { // A variable declared in a for..in statement is always of type string if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) { + // const indexType = getIndexType(checkNonNullExpression((declaration.parent.parent).expression)); + // return indexType.flags & TypeFlags.Index ? indexType : stringType; return stringType; } @@ -4688,7 +4689,6 @@ namespace ts { t.flags & TypeFlags.NumberLike ? globalNumberType : t.flags & TypeFlags.BooleanLike ? globalBooleanType : t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() : - t.flags & TypeFlags.Index ? stringOrNumberType : t; } @@ -5920,8 +5920,7 @@ namespace ts { function getIndexType(type: Type): Type { return type.flags & TypeFlags.TypeParameter ? getIndexTypeForTypeParameter(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : - type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringOrNumberType : - getIndexInfoOfType(type, IndexKind.Number) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type)]) : + type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type); } @@ -6040,10 +6039,9 @@ namespace ts { return indexedAccessTypes[id] || (indexedAccessTypes[id] = createIndexedAccessType(objectType, indexType)); } const apparentObjectType = getApparentType(objectType); - const apparentIndexType = indexType.flags & TypeFlags.Index ? stringOrNumberType : indexType; - if (apparentIndexType.flags & TypeFlags.Union && !(apparentIndexType.flags & TypeFlags.Primitive)) { + if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Primitive)) { const propTypes: Type[] = []; - for (const t of (apparentIndexType).types) { + for (const t of (indexType).types) { const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false); if (propType === unknownType) { return unknownType; @@ -6052,7 +6050,7 @@ namespace ts { } return getUnionType(propTypes); } - return getPropertyTypeForIndexType(apparentObjectType, apparentIndexType, accessNode, /*cacheSymbol*/ true); + return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true); } function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) { @@ -7124,16 +7122,6 @@ namespace ts { if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True; - if (source.flags & TypeFlags.Index) { - // A keyof T is related to a union type containing both string and number - const related = relation === comparableRelation ? - maybeTypeOfKind(target, TypeFlags.String | TypeFlags.Number) : - maybeTypeOfKind(target, TypeFlags.String) && maybeTypeOfKind(target, TypeFlags.Number); - if (related) { - return Ternary.True; - } - } - if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) { if (hasExcessProperties(source, target, reportErrors)) { if (reportErrors) { @@ -15654,7 +15642,7 @@ namespace ts { const type = getTypeFromMappedTypeNode(node); const constraintType = getConstraintTypeFromMappedType(type); const keyType = constraintType.flags & TypeFlags.TypeParameter ? getApparentTypeOfTypeParameter(constraintType) : constraintType; - checkTypeAssignableTo(keyType, stringOrNumberType, node.typeParameter.constraint); + checkTypeAssignableTo(keyType, stringType, node.typeParameter.constraint); } function isPrivateWithinAmbient(node: Node): boolean { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2b8b6fe294e..e79e136ac32 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2789,7 +2789,7 @@ namespace ts { Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never, /* @internal */ Primitive = String | Number | Boolean | Enum | ESSymbol | Void | Undefined | Null | Literal, - StringLike = String | StringLiteral, + StringLike = String | StringLiteral | Index, NumberLike = Number | NumberLiteral | Enum | EnumLiteral, BooleanLike = Boolean | BooleanLiteral, EnumLike = Enum | EnumLiteral,