From bcc9220451f7af0b8700b1255bead698e26cf7ca Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Jun 2016 17:37:14 -0700 Subject: [PATCH 1/2] Improve typing of && operator with --strictNullChecks --- src/compiler/checker.ts | 50 ++++++++++++++++++----------------------- src/compiler/types.ts | 1 + 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b8f078ea9a56b..66e49ffff1337 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2844,7 +2844,7 @@ namespace ts { } // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. - if (strictNullChecks && declaration.initializer && !(getNullableKind(checkExpressionCached(declaration.initializer)) & TypeFlags.Undefined)) { + if (strictNullChecks && declaration.initializer && !(getCombinedTypeFlags(checkExpressionCached(declaration.initializer)) & TypeFlags.Undefined)) { type = getTypeWithFacts(type, TypeFacts.NEUndefined); } return type; @@ -2887,7 +2887,7 @@ namespace ts { } function addOptionality(type: Type, optional: boolean): Type { - return strictNullChecks && optional ? addNullableKind(type, TypeFlags.Undefined) : type; + return strictNullChecks && optional ? addTypeKind(type, TypeFlags.Undefined) : type; } // Return the inferred type for a variable, parameter, or property declaration @@ -3222,7 +3222,7 @@ namespace ts { if (!links.type) { const type = createObjectType(TypeFlags.Anonymous, symbol); links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? - addNullableKind(type, TypeFlags.Undefined) : type; + addTypeKind(type, TypeFlags.Undefined) : type; } return links.type; } @@ -6746,7 +6746,7 @@ namespace ts { return getUnionType(types); } const supertype = forEach(primaryTypes, t => isSupertypeOfEach(t, primaryTypes) ? t : undefined); - return supertype && addNullableKind(supertype, getCombinedFlagsOfTypes(types) & TypeFlags.Nullable); + return supertype && addTypeKind(supertype, getCombinedFlagsOfTypes(types) & TypeFlags.Nullable); } function reportNoCommonSupertypeError(types: Type[], errorLocation: Node, errorMessageChainHead: DiagnosticMessageChain): void { @@ -6817,28 +6817,22 @@ namespace ts { return !!(type.flags & TypeFlags.Tuple); } - function getNullableKind(type: Type): TypeFlags { - let flags = type.flags; - if (flags & TypeFlags.Union) { - for (const t of (type as UnionType).types) { - flags |= t.flags; - } - } - return flags & TypeFlags.Nullable; + function getCombinedTypeFlags(type: Type): TypeFlags { + return type.flags & TypeFlags.Union ? getCombinedFlagsOfTypes((type).types) : type.flags; } - function addNullableKind(type: Type, kind: TypeFlags): Type { - if ((getNullableKind(type) & kind) !== kind) { - const types = [type]; - if (kind & TypeFlags.Undefined) { - types.push(undefinedType); - } - if (kind & TypeFlags.Null) { - types.push(nullType); - } - type = getUnionType(types); + function addTypeKind(type: Type, kind: TypeFlags) { + if ((getCombinedTypeFlags(type) & kind) === kind) { + return type; } - return type; + const types = [type]; + if (kind & TypeFlags.String) types.push(stringType); + if (kind & TypeFlags.Number) types.push(numberType); + if (kind & TypeFlags.Boolean) types.push(booleanType); + if (kind & TypeFlags.Void) types.push(voidType); + if (kind & TypeFlags.Undefined) types.push(undefinedType); + if (kind & TypeFlags.Null) types.push(nullType); + return getUnionType(types); } function getNonNullableType(type: Type): Type { @@ -7667,7 +7661,7 @@ namespace ts { if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) { return declaredType; } - const initialType = assumeInitialized ? declaredType : addNullableKind(declaredType, TypeFlags.Undefined); + const initialType = assumeInitialized ? declaredType : addTypeKind(declaredType, TypeFlags.Undefined); const visitedFlowStart = visitedFlowCount; const result = getTypeAtFlowNode(reference.flowNode); visitedFlowCount = visitedFlowStart; @@ -8163,7 +8157,7 @@ namespace ts { getRootDeclaration(declaration).kind === SyntaxKind.Parameter || isInAmbientContext(declaration) || !isDeclarationIncludedInFlow(node, declaration, includeOuterFunctions); const flowType = getFlowTypeOfReference(node, type, assumeInitialized, includeOuterFunctions); - if (!assumeInitialized && !(getNullableKind(type) & TypeFlags.Undefined) && getNullableKind(flowType) & TypeFlags.Undefined) { + if (!assumeInitialized && !(getCombinedTypeFlags(type) & TypeFlags.Undefined) && getCombinedTypeFlags(flowType) & TypeFlags.Undefined) { error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; @@ -9945,7 +9939,7 @@ namespace ts { function checkNonNullExpression(node: Expression | QualifiedName) { const type = checkExpression(node); if (strictNullChecks) { - const kind = getNullableKind(type); + const kind = getCombinedTypeFlags(type) & TypeFlags.Nullable; if (kind) { error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? Diagnostics.Object_is_possibly_null_or_undefined : @@ -11485,7 +11479,7 @@ namespace ts { if (strictNullChecks) { const declaration = symbol.valueDeclaration; if (declaration && (declaration).initializer) { - return addNullableKind(type, TypeFlags.Undefined); + return addTypeKind(type, TypeFlags.Undefined); } } return type; @@ -12411,7 +12405,7 @@ namespace ts { case SyntaxKind.InKeyword: return checkInExpression(left, right, leftType, rightType); case SyntaxKind.AmpersandAmpersandToken: - return strictNullChecks ? addNullableKind(rightType, getNullableKind(leftType)) : rightType; + return strictNullChecks ? addTypeKind(rightType, getCombinedTypeFlags(leftType) & TypeFlags.Falsy) : rightType; case SyntaxKind.BarBarToken: return getUnionType([getNonNullableType(leftType), rightType]); case SyntaxKind.EqualsToken: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4c0e7a036dbf4..3e8c2378b4ce9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2209,6 +2209,7 @@ namespace ts { /* @internal */ Nullable = Undefined | Null, + Falsy = String | Number | Boolean | Void | Undefined | Null, /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null | Never, /* @internal */ From 13698a99525782f9b2cd80b4a9bed5e20f6759b7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 2 Jun 2016 17:37:25 -0700 Subject: [PATCH 2/2] Add test --- .../reference/logicalAndOperatorStrictMode.js | 156 +++++++ .../logicalAndOperatorStrictMode.symbols | 351 +++++++++++++++ .../logicalAndOperatorStrictMode.types | 423 ++++++++++++++++++ .../logicalAndOperatorStrictMode.ts | 82 ++++ 4 files changed, 1012 insertions(+) create mode 100644 tests/baselines/reference/logicalAndOperatorStrictMode.js create mode 100644 tests/baselines/reference/logicalAndOperatorStrictMode.symbols create mode 100644 tests/baselines/reference/logicalAndOperatorStrictMode.types create mode 100644 tests/cases/conformance/expressions/binaryOperators/logicalAndOperator/logicalAndOperatorStrictMode.ts diff --git a/tests/baselines/reference/logicalAndOperatorStrictMode.js b/tests/baselines/reference/logicalAndOperatorStrictMode.js new file mode 100644 index 0000000000000..ecb5bc1642908 --- /dev/null +++ b/tests/baselines/reference/logicalAndOperatorStrictMode.js @@ -0,0 +1,156 @@ +//// [logicalAndOperatorStrictMode.ts] + +const a = [0]; +const s = ""; +const x = 0; +const b = false; +const v: void = undefined; +const u = undefined; +const n = null; +const z = s || x || u; + +const a1 = a && a; +const a2 = a && s; +const a3 = a && x; +const a4 = a && b; +const a5 = a && v; +const a6 = a && u; +const a7 = a && n; +const a8 = a && z; + +const s1 = s && a; +const s2 = s && s; +const s3 = s && x; +const s4 = s && b; +const s5 = s && v; +const s6 = s && u; +const s7 = s && n; +const s8 = s && z; + +const x1 = x && a; +const x2 = x && s; +const x3 = x && x; +const x4 = x && b; +const x5 = x && v; +const x6 = x && u; +const x7 = x && n; +const x8 = x && z; + +const b1 = b && a; +const b2 = b && s; +const b3 = b && x; +const b4 = b && b; +const b5 = b && v; +const b6 = b && u; +const b7 = b && n; +const b8 = b && z; + +const v1 = v && a; +const v2 = v && s; +const v3 = v && x; +const v4 = v && b; +const v5 = v && v; +const v6 = v && u; +const v7 = v && n; +const v8 = v && z; + +const u1 = u && a; +const u2 = u && s; +const u3 = u && x; +const u4 = u && b; +const u5 = u && v; +const u6 = u && u; +const u7 = u && n; +const u8 = u && z; + +const n1 = n && a; +const n2 = n && s; +const n3 = n && x; +const n4 = n && b; +const n5 = n && v; +const n6 = n && u; +const n7 = n && n; +const n8 = n && z; + +const z1 = z && a; +const z2 = z && s; +const z3 = z && x; +const z4 = z && b; +const z5 = z && v; +const z6 = z && u; +const z7 = z && n; +const z8 = z && z; + +//// [logicalAndOperatorStrictMode.js] +var a = [0]; +var s = ""; +var x = 0; +var b = false; +var v = undefined; +var u = undefined; +var n = null; +var z = s || x || u; +var a1 = a && a; +var a2 = a && s; +var a3 = a && x; +var a4 = a && b; +var a5 = a && v; +var a6 = a && u; +var a7 = a && n; +var a8 = a && z; +var s1 = s && a; +var s2 = s && s; +var s3 = s && x; +var s4 = s && b; +var s5 = s && v; +var s6 = s && u; +var s7 = s && n; +var s8 = s && z; +var x1 = x && a; +var x2 = x && s; +var x3 = x && x; +var x4 = x && b; +var x5 = x && v; +var x6 = x && u; +var x7 = x && n; +var x8 = x && z; +var b1 = b && a; +var b2 = b && s; +var b3 = b && x; +var b4 = b && b; +var b5 = b && v; +var b6 = b && u; +var b7 = b && n; +var b8 = b && z; +var v1 = v && a; +var v2 = v && s; +var v3 = v && x; +var v4 = v && b; +var v5 = v && v; +var v6 = v && u; +var v7 = v && n; +var v8 = v && z; +var u1 = u && a; +var u2 = u && s; +var u3 = u && x; +var u4 = u && b; +var u5 = u && v; +var u6 = u && u; +var u7 = u && n; +var u8 = u && z; +var n1 = n && a; +var n2 = n && s; +var n3 = n && x; +var n4 = n && b; +var n5 = n && v; +var n6 = n && u; +var n7 = n && n; +var n8 = n && z; +var z1 = z && a; +var z2 = z && s; +var z3 = z && x; +var z4 = z && b; +var z5 = z && v; +var z6 = z && u; +var z7 = z && n; +var z8 = z && z; diff --git a/tests/baselines/reference/logicalAndOperatorStrictMode.symbols b/tests/baselines/reference/logicalAndOperatorStrictMode.symbols new file mode 100644 index 0000000000000..e3425a261492b --- /dev/null +++ b/tests/baselines/reference/logicalAndOperatorStrictMode.symbols @@ -0,0 +1,351 @@ +=== tests/cases/conformance/expressions/binaryOperators/logicalAndOperator/logicalAndOperatorStrictMode.ts === + +const a = [0]; +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const s = ""; +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const x = 0; +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const b = false; +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const v: void = undefined; +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>undefined : Symbol(undefined) + +const u = undefined; +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>undefined : Symbol(undefined) + +const n = null; +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const z = s || x || u; +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const a1 = a && a; +>a1 : Symbol(a1, Decl(logicalAndOperatorStrictMode.ts, 10, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const a2 = a && s; +>a2 : Symbol(a2, Decl(logicalAndOperatorStrictMode.ts, 11, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const a3 = a && x; +>a3 : Symbol(a3, Decl(logicalAndOperatorStrictMode.ts, 12, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const a4 = a && b; +>a4 : Symbol(a4, Decl(logicalAndOperatorStrictMode.ts, 13, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const a5 = a && v; +>a5 : Symbol(a5, Decl(logicalAndOperatorStrictMode.ts, 14, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const a6 = a && u; +>a6 : Symbol(a6, Decl(logicalAndOperatorStrictMode.ts, 15, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const a7 = a && n; +>a7 : Symbol(a7, Decl(logicalAndOperatorStrictMode.ts, 16, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const a8 = a && z; +>a8 : Symbol(a8, Decl(logicalAndOperatorStrictMode.ts, 17, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const s1 = s && a; +>s1 : Symbol(s1, Decl(logicalAndOperatorStrictMode.ts, 19, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const s2 = s && s; +>s2 : Symbol(s2, Decl(logicalAndOperatorStrictMode.ts, 20, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const s3 = s && x; +>s3 : Symbol(s3, Decl(logicalAndOperatorStrictMode.ts, 21, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const s4 = s && b; +>s4 : Symbol(s4, Decl(logicalAndOperatorStrictMode.ts, 22, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const s5 = s && v; +>s5 : Symbol(s5, Decl(logicalAndOperatorStrictMode.ts, 23, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const s6 = s && u; +>s6 : Symbol(s6, Decl(logicalAndOperatorStrictMode.ts, 24, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const s7 = s && n; +>s7 : Symbol(s7, Decl(logicalAndOperatorStrictMode.ts, 25, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const s8 = s && z; +>s8 : Symbol(s8, Decl(logicalAndOperatorStrictMode.ts, 26, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const x1 = x && a; +>x1 : Symbol(x1, Decl(logicalAndOperatorStrictMode.ts, 28, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const x2 = x && s; +>x2 : Symbol(x2, Decl(logicalAndOperatorStrictMode.ts, 29, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const x3 = x && x; +>x3 : Symbol(x3, Decl(logicalAndOperatorStrictMode.ts, 30, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const x4 = x && b; +>x4 : Symbol(x4, Decl(logicalAndOperatorStrictMode.ts, 31, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const x5 = x && v; +>x5 : Symbol(x5, Decl(logicalAndOperatorStrictMode.ts, 32, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const x6 = x && u; +>x6 : Symbol(x6, Decl(logicalAndOperatorStrictMode.ts, 33, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const x7 = x && n; +>x7 : Symbol(x7, Decl(logicalAndOperatorStrictMode.ts, 34, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const x8 = x && z; +>x8 : Symbol(x8, Decl(logicalAndOperatorStrictMode.ts, 35, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const b1 = b && a; +>b1 : Symbol(b1, Decl(logicalAndOperatorStrictMode.ts, 37, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const b2 = b && s; +>b2 : Symbol(b2, Decl(logicalAndOperatorStrictMode.ts, 38, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const b3 = b && x; +>b3 : Symbol(b3, Decl(logicalAndOperatorStrictMode.ts, 39, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const b4 = b && b; +>b4 : Symbol(b4, Decl(logicalAndOperatorStrictMode.ts, 40, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const b5 = b && v; +>b5 : Symbol(b5, Decl(logicalAndOperatorStrictMode.ts, 41, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const b6 = b && u; +>b6 : Symbol(b6, Decl(logicalAndOperatorStrictMode.ts, 42, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const b7 = b && n; +>b7 : Symbol(b7, Decl(logicalAndOperatorStrictMode.ts, 43, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const b8 = b && z; +>b8 : Symbol(b8, Decl(logicalAndOperatorStrictMode.ts, 44, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const v1 = v && a; +>v1 : Symbol(v1, Decl(logicalAndOperatorStrictMode.ts, 46, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const v2 = v && s; +>v2 : Symbol(v2, Decl(logicalAndOperatorStrictMode.ts, 47, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const v3 = v && x; +>v3 : Symbol(v3, Decl(logicalAndOperatorStrictMode.ts, 48, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const v4 = v && b; +>v4 : Symbol(v4, Decl(logicalAndOperatorStrictMode.ts, 49, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const v5 = v && v; +>v5 : Symbol(v5, Decl(logicalAndOperatorStrictMode.ts, 50, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const v6 = v && u; +>v6 : Symbol(v6, Decl(logicalAndOperatorStrictMode.ts, 51, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const v7 = v && n; +>v7 : Symbol(v7, Decl(logicalAndOperatorStrictMode.ts, 52, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const v8 = v && z; +>v8 : Symbol(v8, Decl(logicalAndOperatorStrictMode.ts, 53, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const u1 = u && a; +>u1 : Symbol(u1, Decl(logicalAndOperatorStrictMode.ts, 55, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const u2 = u && s; +>u2 : Symbol(u2, Decl(logicalAndOperatorStrictMode.ts, 56, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const u3 = u && x; +>u3 : Symbol(u3, Decl(logicalAndOperatorStrictMode.ts, 57, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const u4 = u && b; +>u4 : Symbol(u4, Decl(logicalAndOperatorStrictMode.ts, 58, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const u5 = u && v; +>u5 : Symbol(u5, Decl(logicalAndOperatorStrictMode.ts, 59, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const u6 = u && u; +>u6 : Symbol(u6, Decl(logicalAndOperatorStrictMode.ts, 60, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const u7 = u && n; +>u7 : Symbol(u7, Decl(logicalAndOperatorStrictMode.ts, 61, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const u8 = u && z; +>u8 : Symbol(u8, Decl(logicalAndOperatorStrictMode.ts, 62, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const n1 = n && a; +>n1 : Symbol(n1, Decl(logicalAndOperatorStrictMode.ts, 64, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const n2 = n && s; +>n2 : Symbol(n2, Decl(logicalAndOperatorStrictMode.ts, 65, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const n3 = n && x; +>n3 : Symbol(n3, Decl(logicalAndOperatorStrictMode.ts, 66, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const n4 = n && b; +>n4 : Symbol(n4, Decl(logicalAndOperatorStrictMode.ts, 67, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const n5 = n && v; +>n5 : Symbol(n5, Decl(logicalAndOperatorStrictMode.ts, 68, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const n6 = n && u; +>n6 : Symbol(n6, Decl(logicalAndOperatorStrictMode.ts, 69, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const n7 = n && n; +>n7 : Symbol(n7, Decl(logicalAndOperatorStrictMode.ts, 70, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const n8 = n && z; +>n8 : Symbol(n8, Decl(logicalAndOperatorStrictMode.ts, 71, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + +const z1 = z && a; +>z1 : Symbol(z1, Decl(logicalAndOperatorStrictMode.ts, 73, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>a : Symbol(a, Decl(logicalAndOperatorStrictMode.ts, 1, 5)) + +const z2 = z && s; +>z2 : Symbol(z2, Decl(logicalAndOperatorStrictMode.ts, 74, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>s : Symbol(s, Decl(logicalAndOperatorStrictMode.ts, 2, 5)) + +const z3 = z && x; +>z3 : Symbol(z3, Decl(logicalAndOperatorStrictMode.ts, 75, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>x : Symbol(x, Decl(logicalAndOperatorStrictMode.ts, 3, 5)) + +const z4 = z && b; +>z4 : Symbol(z4, Decl(logicalAndOperatorStrictMode.ts, 76, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>b : Symbol(b, Decl(logicalAndOperatorStrictMode.ts, 4, 5)) + +const z5 = z && v; +>z5 : Symbol(z5, Decl(logicalAndOperatorStrictMode.ts, 77, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>v : Symbol(v, Decl(logicalAndOperatorStrictMode.ts, 5, 5)) + +const z6 = z && u; +>z6 : Symbol(z6, Decl(logicalAndOperatorStrictMode.ts, 78, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>u : Symbol(u, Decl(logicalAndOperatorStrictMode.ts, 6, 5)) + +const z7 = z && n; +>z7 : Symbol(z7, Decl(logicalAndOperatorStrictMode.ts, 79, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>n : Symbol(n, Decl(logicalAndOperatorStrictMode.ts, 7, 5)) + +const z8 = z && z; +>z8 : Symbol(z8, Decl(logicalAndOperatorStrictMode.ts, 80, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) +>z : Symbol(z, Decl(logicalAndOperatorStrictMode.ts, 8, 5)) + diff --git a/tests/baselines/reference/logicalAndOperatorStrictMode.types b/tests/baselines/reference/logicalAndOperatorStrictMode.types new file mode 100644 index 0000000000000..ca225d4561a3e --- /dev/null +++ b/tests/baselines/reference/logicalAndOperatorStrictMode.types @@ -0,0 +1,423 @@ +=== tests/cases/conformance/expressions/binaryOperators/logicalAndOperator/logicalAndOperatorStrictMode.ts === + +const a = [0]; +>a : number[] +>[0] : number[] +>0 : number + +const s = ""; +>s : string +>"" : string + +const x = 0; +>x : number +>0 : number + +const b = false; +>b : boolean +>false : boolean + +const v: void = undefined; +>v : void +>undefined : undefined + +const u = undefined; +>u : undefined +>undefined : undefined + +const n = null; +>n : null +>null : null + +const z = s || x || u; +>z : string | number | undefined +>s || x || u : string | number | undefined +>s || x : string | number +>s : string +>x : number +>u : undefined + +const a1 = a && a; +>a1 : number[] +>a && a : number[] +>a : number[] +>a : number[] + +const a2 = a && s; +>a2 : string +>a && s : string +>a : number[] +>s : string + +const a3 = a && x; +>a3 : number +>a && x : number +>a : number[] +>x : number + +const a4 = a && b; +>a4 : boolean +>a && b : boolean +>a : number[] +>b : boolean + +const a5 = a && v; +>a5 : void +>a && v : void +>a : number[] +>v : void + +const a6 = a && u; +>a6 : undefined +>a && u : undefined +>a : number[] +>u : undefined + +const a7 = a && n; +>a7 : null +>a && n : null +>a : number[] +>n : null + +const a8 = a && z; +>a8 : string | number | undefined +>a && z : string | number | undefined +>a : number[] +>z : string | number | undefined + +const s1 = s && a; +>s1 : number[] | string +>s && a : number[] | string +>s : string +>a : number[] + +const s2 = s && s; +>s2 : string +>s && s : string +>s : string +>s : string + +const s3 = s && x; +>s3 : number | string +>s && x : number | string +>s : string +>x : number + +const s4 = s && b; +>s4 : boolean | string +>s && b : boolean | string +>s : string +>b : boolean + +const s5 = s && v; +>s5 : void | string +>s && v : void | string +>s : string +>v : void + +const s6 = s && u; +>s6 : string | undefined +>s && u : string | undefined +>s : string +>u : undefined + +const s7 = s && n; +>s7 : string | null +>s && n : string | null +>s : string +>n : null + +const s8 = s && z; +>s8 : string | number | undefined +>s && z : string | number | undefined +>s : string +>z : string | number | undefined + +const x1 = x && a; +>x1 : number[] | number +>x && a : number[] | number +>x : number +>a : number[] + +const x2 = x && s; +>x2 : string | number +>x && s : string | number +>x : number +>s : string + +const x3 = x && x; +>x3 : number +>x && x : number +>x : number +>x : number + +const x4 = x && b; +>x4 : boolean | number +>x && b : boolean | number +>x : number +>b : boolean + +const x5 = x && v; +>x5 : void | number +>x && v : void | number +>x : number +>v : void + +const x6 = x && u; +>x6 : number | undefined +>x && u : number | undefined +>x : number +>u : undefined + +const x7 = x && n; +>x7 : number | null +>x && n : number | null +>x : number +>n : null + +const x8 = x && z; +>x8 : string | number | undefined +>x && z : string | number | undefined +>x : number +>z : string | number | undefined + +const b1 = b && a; +>b1 : number[] | boolean +>b && a : number[] | boolean +>b : boolean +>a : number[] + +const b2 = b && s; +>b2 : string | boolean +>b && s : string | boolean +>b : boolean +>s : string + +const b3 = b && x; +>b3 : number | boolean +>b && x : number | boolean +>b : boolean +>x : number + +const b4 = b && b; +>b4 : boolean +>b && b : boolean +>b : boolean +>b : boolean + +const b5 = b && v; +>b5 : void | boolean +>b && v : void | boolean +>b : boolean +>v : void + +const b6 = b && u; +>b6 : boolean | undefined +>b && u : boolean | undefined +>b : boolean +>u : undefined + +const b7 = b && n; +>b7 : boolean | null +>b && n : boolean | null +>b : boolean +>n : null + +const b8 = b && z; +>b8 : string | number | boolean | undefined +>b && z : string | number | boolean | undefined +>b : boolean +>z : string | number | undefined + +const v1 = v && a; +>v1 : number[] | void +>v && a : number[] | void +>v : void +>a : number[] + +const v2 = v && s; +>v2 : string | void +>v && s : string | void +>v : void +>s : string + +const v3 = v && x; +>v3 : number | void +>v && x : number | void +>v : void +>x : number + +const v4 = v && b; +>v4 : boolean | void +>v && b : boolean | void +>v : void +>b : boolean + +const v5 = v && v; +>v5 : void +>v && v : void +>v : void +>v : never + +const v6 = v && u; +>v6 : void +>v && u : void +>v : void +>u : undefined + +const v7 = v && n; +>v7 : void | null +>v && n : void | null +>v : void +>n : null + +const v8 = v && z; +>v8 : string | number | void +>v && z : string | number | void +>v : void +>z : string | number | undefined + +const u1 = u && a; +>u1 : number[] | undefined +>u && a : number[] | undefined +>u : undefined +>a : number[] + +const u2 = u && s; +>u2 : string | undefined +>u && s : string | undefined +>u : undefined +>s : string + +const u3 = u && x; +>u3 : number | undefined +>u && x : number | undefined +>u : undefined +>x : number + +const u4 = u && b; +>u4 : boolean | undefined +>u && b : boolean | undefined +>u : undefined +>b : boolean + +const u5 = u && v; +>u5 : void +>u && v : void +>u : undefined +>v : void + +const u6 = u && u; +>u6 : undefined +>u && u : undefined +>u : undefined +>u : never + +const u7 = u && n; +>u7 : null | undefined +>u && n : null | undefined +>u : undefined +>n : null + +const u8 = u && z; +>u8 : string | number | undefined +>u && z : string | number | undefined +>u : undefined +>z : string | number | undefined + +const n1 = n && a; +>n1 : number[] | null +>n && a : number[] | null +>n : null +>a : number[] + +const n2 = n && s; +>n2 : string | null +>n && s : string | null +>n : null +>s : string + +const n3 = n && x; +>n3 : number | null +>n && x : number | null +>n : null +>x : number + +const n4 = n && b; +>n4 : boolean | null +>n && b : boolean | null +>n : null +>b : boolean + +const n5 = n && v; +>n5 : void | null +>n && v : void | null +>n : null +>v : void + +const n6 = n && u; +>n6 : null | undefined +>n && u : null | undefined +>n : null +>u : undefined + +const n7 = n && n; +>n7 : null +>n && n : null +>n : null +>n : never + +const n8 = n && z; +>n8 : string | number | null | undefined +>n && z : string | number | null | undefined +>n : null +>z : string | number | undefined + +const z1 = z && a; +>z1 : number[] | string | number | undefined +>z && a : number[] | string | number | undefined +>z : string | number | undefined +>a : number[] + +const z2 = z && s; +>z2 : string | number | undefined +>z && s : string | number | undefined +>z : string | number | undefined +>s : string + +const z3 = z && x; +>z3 : number | string | undefined +>z && x : number | string | undefined +>z : string | number | undefined +>x : number + +const z4 = z && b; +>z4 : boolean | string | number | undefined +>z && b : boolean | string | number | undefined +>z : string | number | undefined +>b : boolean + +const z5 = z && v; +>z5 : void | string | number +>z && v : void | string | number +>z : string | number | undefined +>v : void + +const z6 = z && u; +>z6 : string | number | undefined +>z && u : string | number | undefined +>z : string | number | undefined +>u : undefined + +const z7 = z && n; +>z7 : string | number | null | undefined +>z && n : string | number | null | undefined +>z : string | number | undefined +>n : null + +const z8 = z && z; +>z8 : string | number | undefined +>z && z : string | number | undefined +>z : string | number | undefined +>z : string | number + diff --git a/tests/cases/conformance/expressions/binaryOperators/logicalAndOperator/logicalAndOperatorStrictMode.ts b/tests/cases/conformance/expressions/binaryOperators/logicalAndOperator/logicalAndOperatorStrictMode.ts new file mode 100644 index 0000000000000..a4ad5ca7719e6 --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/logicalAndOperator/logicalAndOperatorStrictMode.ts @@ -0,0 +1,82 @@ +// @strictNullChecks: true + +const a = [0]; +const s = ""; +const x = 0; +const b = false; +const v: void = undefined; +const u = undefined; +const n = null; +const z = s || x || u; + +const a1 = a && a; +const a2 = a && s; +const a3 = a && x; +const a4 = a && b; +const a5 = a && v; +const a6 = a && u; +const a7 = a && n; +const a8 = a && z; + +const s1 = s && a; +const s2 = s && s; +const s3 = s && x; +const s4 = s && b; +const s5 = s && v; +const s6 = s && u; +const s7 = s && n; +const s8 = s && z; + +const x1 = x && a; +const x2 = x && s; +const x3 = x && x; +const x4 = x && b; +const x5 = x && v; +const x6 = x && u; +const x7 = x && n; +const x8 = x && z; + +const b1 = b && a; +const b2 = b && s; +const b3 = b && x; +const b4 = b && b; +const b5 = b && v; +const b6 = b && u; +const b7 = b && n; +const b8 = b && z; + +const v1 = v && a; +const v2 = v && s; +const v3 = v && x; +const v4 = v && b; +const v5 = v && v; +const v6 = v && u; +const v7 = v && n; +const v8 = v && z; + +const u1 = u && a; +const u2 = u && s; +const u3 = u && x; +const u4 = u && b; +const u5 = u && v; +const u6 = u && u; +const u7 = u && n; +const u8 = u && z; + +const n1 = n && a; +const n2 = n && s; +const n3 = n && x; +const n4 = n && b; +const n5 = n && v; +const n6 = n && u; +const n7 = n && n; +const n8 = n && z; + +const z1 = z && a; +const z2 = z && s; +const z3 = z && x; +const z4 = z && b; +const z5 = z && v; +const z6 = z && u; +const z7 = z && n; +const z8 = z && z; \ No newline at end of file