Skip to content

Commit 8dbfe1c

Browse files
Added specific checks for comparing stringlike types.
1 parent 5e23143 commit 8dbfe1c

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

src/compiler/checker.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -9400,7 +9400,12 @@ namespace ts {
94009400
let targetType = getTypeFromTypeNode(node.type);
94019401
if (produceDiagnostics && targetType !== unknownType) {
94029402
let widenedType = getWidenedType(exprType);
9403-
if (!(isTypeAssignableTo(targetType, widenedType))) {
9403+
9404+
// Permit 'number[] | "foo"' to be asserted to 'string'.
9405+
const bothAreStringLike =
9406+
someConstituentTypeHasKind(targetType, TypeFlags.StringLike) &&
9407+
someConstituentTypeHasKind(widenedType, TypeFlags.StringLike);
9408+
if (!bothAreStringLike && !(isTypeAssignableTo(targetType, widenedType))) {
94049409
checkTypeAssignableTo(exprType, targetType, node, Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
94059410
}
94069411
}
@@ -10244,6 +10249,10 @@ namespace ts {
1024410249
case SyntaxKind.ExclamationEqualsToken:
1024510250
case SyntaxKind.EqualsEqualsEqualsToken:
1024610251
case SyntaxKind.ExclamationEqualsEqualsToken:
10252+
// Permit 'number[] | "foo"' to be asserted to 'string'.
10253+
if (someConstituentTypeHasKind(leftType, TypeFlags.StringLike) && someConstituentTypeHasKind(rightType, TypeFlags.StringLike)) {
10254+
return booleanType;
10255+
}
1024710256
if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
1024810257
reportOperatorError();
1024910258
}
@@ -12703,6 +12712,7 @@ namespace ts {
1270312712
let hasDuplicateDefaultClause = false;
1270412713

1270512714
let expressionType = checkExpression(node.expression);
12715+
const expressionTypeIsStringLike = someConstituentTypeHasKind(expressionType, TypeFlags.StringLike);
1270612716
forEach(node.caseBlock.clauses, clause => {
1270712717
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
1270812718
if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) {
@@ -12723,6 +12733,12 @@ namespace ts {
1272312733
// TypeScript 1.0 spec (April 2014):5.9
1272412734
// In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression.
1272512735
let caseType = checkExpression(caseClause.expression);
12736+
12737+
// Permit 'number[] | "foo"' to be asserted to 'string'.
12738+
if (expressionTypeIsStringLike && someConstituentTypeHasKind(caseType, TypeFlags.StringLike)) {
12739+
return;
12740+
}
12741+
1272612742
if (!isTypeAssignableTo(expressionType, caseType)) {
1272712743
// check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails
1272812744
checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);

0 commit comments

Comments
 (0)