mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-18 07:29:16 -05:00
Make keyof T a string-like type
This commit is contained in:
@@ -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((<ForInStatement>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(<TypeParameter>type) :
|
||||
getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(<MappedType>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 (<UnionType>apparentIndexType).types) {
|
||||
for (const t of (<UnionType>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(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
@@ -15654,7 +15642,7 @@ namespace ts {
|
||||
const type = <MappedType>getTypeFromMappedTypeNode(node);
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
const keyType = constraintType.flags & TypeFlags.TypeParameter ? getApparentTypeOfTypeParameter(<TypeParameter>constraintType) : constraintType;
|
||||
checkTypeAssignableTo(keyType, stringOrNumberType, node.typeParameter.constraint);
|
||||
checkTypeAssignableTo(keyType, stringType, node.typeParameter.constraint);
|
||||
}
|
||||
|
||||
function isPrivateWithinAmbient(node: Node): boolean {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user