Merge pull request #24347 from weswigham/constraint-fix

Check for keyof constraint type instead of syntactic check (#24098)
This commit is contained in:
Mohamed Hegazy
2018-05-23 08:42:46 -07:00
committed by GitHub
5 changed files with 195 additions and 15 deletions
+4 -15
View File
@@ -20588,16 +20588,7 @@ namespace ts {
return widened;
}
function isTypeParameterWithKeyofConstraint(type: Type) {
if (type.flags & TypeFlags.TypeParameter) {
const constraintDeclaration = getConstraintDeclaration(<TypeParameter>type);
return constraintDeclaration && constraintDeclaration.kind === SyntaxKind.TypeOperator &&
(<TypeOperatorNode>constraintDeclaration).operator === SyntaxKind.KeyOfKeyword;
}
return false;
}
function isLiteralOfContextualType(candidateType: Type, contextualType: Type): boolean {
function isLiteralOfContextualType(candidateType: Type, contextualType: Type | undefined): boolean {
if (contextualType) {
if (contextualType.flags & TypeFlags.UnionOrIntersection) {
const types = (<UnionType>contextualType).types;
@@ -20608,11 +20599,9 @@ namespace ts {
// this a literal context for literals of that primitive type. For example, given a
// type parameter 'T extends string', infer string literal types for T.
const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
return isTypeParameterWithKeyofConstraint(contextualType) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol) ||
constraint.flags & TypeFlags.String && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
constraint.flags & TypeFlags.Number && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
constraint.flags & TypeFlags.Boolean && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) ||
constraint.flags & TypeFlags.ESSymbol && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol) ||
return maybeTypeOfKind(constraint, TypeFlags.String) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
maybeTypeOfKind(constraint, TypeFlags.Number) && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
maybeTypeOfKind(constraint, TypeFlags.ESSymbol) && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol) ||
isLiteralOfContextualType(candidateType, constraint);
}
// If the contextual type is a literal of a particular primitive type, we consider this a