From b7dd10eab38c1a9d072f4a35f9e9bf366001df68 Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Tue, 18 Dec 2018 02:14:49 -0500 Subject: [PATCH 1/7] Add basic support for numeric range types The syntax of a range is `(OP N)`, where OP is one of <, <=, >, or >=, and N is a numeric literal. The parentheses are mandatory. The parser refers to these as a HalfRangeType. The rules for them are as follows: Assigning to a range from a number or an enum is not allowed. In the future, enums may be supported directly, while numbers will have to be done through control flow analysis. Assigning to a range from a number literal (including enum literals) is allowed if the literal is within the range. Assigning from BigInt literals is not supported as the compiler only treats them as strings. Assigning from a range to another is only allowed if the source range is contained entirely within the target range. For example, assigning from (>= 0) to (> 0) is not allowed, because 0 would be valid in the source but not the target. Assigning from (> 0) to (> 1) is not allowed, but the reverse is. Assigning from a range to a generic number is always allowed. Assigning to an enum is not. Internally, the compiler represents all ranges as "full" ranges, e.g. [0, 1) in interval notation. In the future this will be used in union and intersection types to "merge" ranges. For example, the union of (>= 0) and (< 1) should be [0, 1), while the intersection should be `never`. These should still work normally, but there isn't any special support for them that would support such narrowing. Right now, these "full" ranges are not actually supported in the syntax, nor is this planned. Since this is a first draft, there's not yet any support for language services, and there's very limited diagnostic information available. In the future, control flow analysis will be done to automatically widen and narrow numbers and ranges as necessary. --- src/compiler/checker.ts | 107 ++++++ src/compiler/emitter.ts | 10 + src/compiler/factoryPublic.ts | 14 + src/compiler/parser.ts | 57 ++- src/compiler/types.ts | 31 +- .../reference/api/tsserverlibrary.d.ts | 345 +++++++++--------- tests/baselines/reference/api/typescript.d.ts | 345 +++++++++--------- .../reference/rangeTypeAssignment.errors.txt | 32 ++ .../reference/rangeTypeAssignment.js | 39 ++ .../reference/rangeTypeAssignment.symbols | 59 +++ .../reference/rangeTypeAssignment.types | 61 ++++ .../reference/rangeTypeBasics.errors.txt | 109 ++++++ tests/baselines/reference/rangeTypeBasics.js | 78 ++++ .../reference/rangeTypeBasics.symbols | 108 ++++++ .../baselines/reference/rangeTypeBasics.types | 145 ++++++++ .../reference/rangeTypeDeclaration.errors.txt | 51 +++ .../reference/rangeTypeDeclaration.js | 53 +++ .../reference/rangeTypeDeclaration.symbols | 84 +++++ .../reference/rangeTypeDeclaration.types | 98 +++++ .../rangeTypeFunctionDeclarations.errors.txt | 34 ++ .../rangeTypeFunctionDeclarations.js | 34 ++ .../rangeTypeFunctionDeclarations.symbols | 53 +++ .../rangeTypeFunctionDeclarations.types | 65 ++++ .../reference/rangeTypeFunctions.errors.txt | 69 ++++ .../baselines/reference/rangeTypeFunctions.js | 80 ++++ .../reference/rangeTypeFunctions.symbols | 101 +++++ .../reference/rangeTypeFunctions.types | 124 +++++++ tests/cases/compiler/rangeTypeAssignment.ts | 19 + tests/cases/compiler/rangeTypeBasics.ts | 42 +++ tests/cases/compiler/rangeTypeDeclaration.ts | 29 ++ .../compiler/rangeTypeFunctionDeclarations.ts | 18 + tests/cases/compiler/rangeTypeFunctions.ts | 44 +++ 32 files changed, 2204 insertions(+), 334 deletions(-) create mode 100644 tests/baselines/reference/rangeTypeAssignment.errors.txt create mode 100644 tests/baselines/reference/rangeTypeAssignment.js create mode 100644 tests/baselines/reference/rangeTypeAssignment.symbols create mode 100644 tests/baselines/reference/rangeTypeAssignment.types create mode 100644 tests/baselines/reference/rangeTypeBasics.errors.txt create mode 100644 tests/baselines/reference/rangeTypeBasics.js create mode 100644 tests/baselines/reference/rangeTypeBasics.symbols create mode 100644 tests/baselines/reference/rangeTypeBasics.types create mode 100644 tests/baselines/reference/rangeTypeDeclaration.errors.txt create mode 100644 tests/baselines/reference/rangeTypeDeclaration.js create mode 100644 tests/baselines/reference/rangeTypeDeclaration.symbols create mode 100644 tests/baselines/reference/rangeTypeDeclaration.types create mode 100644 tests/baselines/reference/rangeTypeFunctionDeclarations.errors.txt create mode 100644 tests/baselines/reference/rangeTypeFunctionDeclarations.js create mode 100644 tests/baselines/reference/rangeTypeFunctionDeclarations.symbols create mode 100644 tests/baselines/reference/rangeTypeFunctionDeclarations.types create mode 100644 tests/baselines/reference/rangeTypeFunctions.errors.txt create mode 100644 tests/baselines/reference/rangeTypeFunctions.js create mode 100644 tests/baselines/reference/rangeTypeFunctions.symbols create mode 100644 tests/baselines/reference/rangeTypeFunctions.types create mode 100644 tests/cases/compiler/rangeTypeAssignment.ts create mode 100644 tests/cases/compiler/rangeTypeBasics.ts create mode 100644 tests/cases/compiler/rangeTypeDeclaration.ts create mode 100644 tests/cases/compiler/rangeTypeFunctionDeclarations.ts create mode 100644 tests/cases/compiler/rangeTypeFunctions.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ad3f3b71f29fb..bc07cfd3e9c0d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4238,6 +4238,20 @@ namespace ts { if (type.flags & TypeFlags.Substitution) { return typeToTypeNodeHelper((type).typeVariable, context); } + if (type.flags & TypeFlags.Range) { + let operator; + let basis; + if ((type).min && !(type).max) { + operator = (type).minOpen ? createToken(SyntaxKind.GreaterThanToken) : createToken(SyntaxKind.GreaterThanEqualsToken); + basis = createLiteral((type).min!.value); + return createHalfRangeTypeNode(operator, basis); + } + else if (!(type).min && (type).max) { + operator = (type).maxOpen ? createToken(SyntaxKind.LessThanToken) : createToken(SyntaxKind.LessThanEqualsToken); + basis = createLiteral((type).max!.value); + return createHalfRangeTypeNode(operator, basis); + } // TODO: "full" range handling (e.g. union) + } return Debug.fail("Should be unreachable."); @@ -13217,6 +13231,37 @@ namespace ts { return links.resolvedType; } + function getRangeTypeFromHalfRangeTypeNode(node: HalfRangeTypeNode): Type { + const links = getNodeLinks(node); + if (!links.resolvedType) { + let value: NumberLiteralType; + if (isPrefixUnaryExpression(node.basis)) { + value = getLiteralType(-(node.basis.operand as NumericLiteral).text); + } + else { + value = getLiteralType(+node.basis.text); + } + + const type = createType(TypeFlags.Range); + + switch (node.operator.kind) { + case SyntaxKind.LessThanToken: + type.maxOpen = true; + // falls through + case SyntaxKind.LessThanEqualsToken: + type.max = value; + break; + case SyntaxKind.GreaterThanToken: + type.minOpen = true; + // falls through + case SyntaxKind.GreaterThanEqualsToken: + type.min = value; + } + links.resolvedType = type; + } + return links.resolvedType; + } + function getTypeFromTypeNode(node: TypeNode): Type { switch (node.kind) { case SyntaxKind.AnyKeyword: @@ -13298,6 +13343,8 @@ namespace ts { return getTypeFromInferTypeNode(node); case SyntaxKind.ImportType: return getTypeFromImportTypeNode(node); + case SyntaxKind.HalfRangeType: + return getRangeTypeFromHalfRangeTypeNode(node); // This function assumes that an identifier or qualified name is a type expression // Callers should first ensure this by calling isTypeNode case SyntaxKind.Identifier: @@ -14696,9 +14743,54 @@ namespace ts { if (s & (TypeFlags.Number | TypeFlags.NumberLiteral) && !(s & TypeFlags.EnumLiteral) && ( t & TypeFlags.Enum || t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral)) return true; } + if (s & TypeFlags.NumberLike && t & TypeFlags.Range) { + return isRangeTypeRelatedTo(source, target, relation); + } return false; } + function isRangeTypeRelatedTo(source: Type, target: RangeType, relation: Map) { + if (relation === comparableRelation) return true; + if (relation === assignableRelation) { + if (source.flags & TypeFlags.Range) { + return isRangeContainedBy(source, target); + } + if (source.flags & TypeFlags.NumberLiteral) { + return isValueInRange(target, (source).value); + } + } + return false; + } + + // A range "contained" by another is essentially a subtype of it + function isRangeContainedBy(source: RangeType, target: RangeType) { + if (!source.min && target.min) return false; + if (!source.max && target.max) return false; + if (source.min && target.min) { + if ((source.min.value === target.min.value && !source.minOpen && target.minOpen + || source.min.value < target.min.value)) { + return false; + } + } + if (source.max && target.max) { + if ((source.max.value === target.max.value && !source.maxOpen && target.maxOpen + || source.max.value > target.max.value)) { + return false; + } + } + return true; + } + + function isValueInRange(range: RangeType, value: number) { + if (range.min && (range.minOpen && value === range.min.value || value < range.min.value)) { + return false; + } + if (range.max && (range.maxOpen && value === range.max.value || value > range.max.value)) { + return false; + } + return true; + } + function isTypeRelatedTo(source: Type, target: Type, relation: Map) { if (isFreshLiteralType(source)) { source = (source).regularType; @@ -15229,6 +15321,15 @@ namespace ts { } } } + if (flags & TypeFlags.Range) { + // assert types + const src = source; + const tgt = target; + if (src.min === tgt.min && src.minOpen === tgt.minOpen + && src.max === tgt.max && tgt.maxOpen === tgt.maxOpen) { + return Ternary.True; + } + } return Ternary.False; } @@ -29122,6 +29223,10 @@ namespace ts { forEach(node.types, checkSourceElement); } + function checkHalfRangeType(node: HalfRangeTypeNode) { + forEachChild(node, checkSourceElement); + } + function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) { if (!(type.flags & TypeFlags.IndexedAccess)) { return type; @@ -33627,6 +33732,8 @@ namespace ts { case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: return checkUnionOrIntersectionType(node); + case SyntaxKind.HalfRangeType: + return checkHalfRangeType(node); case SyntaxKind.ParenthesizedType: case SyntaxKind.OptionalType: case SyntaxKind.RestType: diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a5eb13647e92f..2cc951f75f9b9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1344,6 +1344,8 @@ namespace ts { return emitIndexedAccessType(node); case SyntaxKind.MappedType: return emitMappedType(node); + case SyntaxKind.HalfRangeType: + return emitHalfRangeType(node); case SyntaxKind.LiteralType: return emitLiteralType(node); case SyntaxKind.ImportType: @@ -2196,6 +2198,14 @@ namespace ts { writePunctuation("}"); } + function emitHalfRangeType(node: HalfRangeTypeNode) { + writePunctuation("("); + writeTokenNode(node.operator, writeOperator); + writeSpace(); + emit(node.basis); + writePunctuation(")"); + } + function emitLiteralType(node: LiteralTypeNode) { emitExpression(node.literal); } diff --git a/src/compiler/factoryPublic.ts b/src/compiler/factoryPublic.ts index 2c59abbb494dc..f14590f938565 100644 --- a/src/compiler/factoryPublic.ts +++ b/src/compiler/factoryPublic.ts @@ -983,6 +983,20 @@ namespace ts { : node; } + export function createHalfRangeTypeNode(operator: HalfRangeTypeNode["operator"], basis: HalfRangeTypeNode["basis"]) { + const node = createSynthesizedNode(SyntaxKind.HalfRangeType) as HalfRangeTypeNode; + node.operator = operator; + node.basis = basis; + return node; + } + + export function updateHalfRangeTypeNode(node: HalfRangeTypeNode, operator: HalfRangeTypeNode["operator"], basis: HalfRangeTypeNode["basis"]) { + return node.operator !== operator + || node.basis !== basis + ? updateNode(createHalfRangeTypeNode(operator, basis), node) + : node; + } + export function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) { const node = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; node.literal = literal; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e990c0f675c32..a7076c79d58f6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -205,6 +205,9 @@ namespace ts { visitNode(cbNode, (node).typeParameter) || visitNode(cbNode, (node).questionToken) || visitNode(cbNode, (node).type); + case SyntaxKind.HalfRangeType: + return visitNode(cbNode, (node).operator) || + visitNode(cbNode, (node).basis); case SyntaxKind.LiteralType: return visitNode(cbNode, (node).literal); case SyntaxKind.ObjectBindingPattern: @@ -2993,6 +2996,42 @@ namespace ts { return finishNode(node); } + function parseParenthesizedOrHalfRangeType(): TypeNode { + if (lookAhead(isStartOfHalfRangeType)) { + return tryParse(parseHalfRangeType) || parseParenthesizedType(); + } + return parseParenthesizedType(); + } + + function parseHalfRangeType(): TypeNode | undefined { + const node = createNode(SyntaxKind.HalfRangeType); + parseExpected(SyntaxKind.OpenParenToken); + reScanGreaterToken(); + node.operator = parseTokenNode(); + + let unaryMinus: PrefixUnaryExpression | undefined; + if (token() === SyntaxKind.MinusToken) { + unaryMinus = createNode(SyntaxKind.PrefixUnaryExpression); + unaryMinus.operator = SyntaxKind.MinusToken; + nextToken(); + } + + if (token() !== SyntaxKind.NumericLiteral) { + return undefined; + } + let basis: NumericLiteral | PrefixUnaryExpression = parseLiteralNode(); + + if (unaryMinus !== undefined) { + unaryMinus.operand = basis; + finishNode(unaryMinus); + basis = unaryMinus; + } + + node.basis = basis; + parseExpected(SyntaxKind.CloseParenToken); + return finishNode(node); + } + function parseParenthesizedType(): TypeNode { const node = createNode(SyntaxKind.ParenthesizedType); parseExpected(SyntaxKind.OpenParenToken); @@ -3119,7 +3158,7 @@ namespace ts { case SyntaxKind.OpenBracketToken: return parseTupleType(); case SyntaxKind.OpenParenToken: - return parseParenthesizedType(); + return parseParenthesizedOrHalfRangeType(); case SyntaxKind.ImportKeyword: return parseImportType(); case SyntaxKind.AssertsKeyword: @@ -3173,7 +3212,7 @@ namespace ts { case SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && (lookAhead(isStartOfHalfRangeType) || lookAhead(isStartOfParenthesizedOrFunctionType)); default: return isIdentifier(); } @@ -3184,6 +3223,20 @@ namespace ts { return token() === SyntaxKind.CloseParenToken || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType(); } + function isStartOfHalfRangeType(): boolean { + nextToken(); + switch (token()) { + case SyntaxKind.LessThanToken: + case SyntaxKind.LessThanEqualsToken: + return true; + case SyntaxKind.GreaterThanToken: + reScanGreaterToken(); + return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.GreaterThanEqualsToken; + default: + return false; + } + } + function parsePostfixTypeOrHigher(): TypeNode { let type = parseNonArrayType(); while (!scanner.hasPrecedingLineBreak()) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9b913c2f17d00..ef622ee512e51 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -328,6 +328,7 @@ namespace ts { IndexedAccessType, MappedType, LiteralType, + HalfRangeType, ImportType, // Binding patterns ObjectBindingPattern, @@ -768,6 +769,10 @@ namespace ts { export type PlusToken = Token; export type MinusToken = Token; export type AssertsToken = Token; + export type GreaterThanToken = Token; + export type GreaterThanEqualsToken = Token; + export type LessThanToken = Token; + export type LessThanEqualsToken = Token; export type Modifier = Token @@ -1345,6 +1350,12 @@ namespace ts { literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression; } + export interface HalfRangeTypeNode extends TypeNode { + kind: SyntaxKind.HalfRangeType; + operator: LessThanToken | LessThanEqualsToken | GreaterThanToken | GreaterThanEqualsToken; + basis: NumericLiteral | PrefixUnaryExpression; + } + export interface StringLiteral extends LiteralExpression, Declaration { kind: SyntaxKind.StringLiteral; /* @internal */ textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). @@ -4276,11 +4287,12 @@ namespace ts { Object = 1 << 19, // Object type Union = 1 << 20, // Union (T | U) Intersection = 1 << 21, // Intersection (T & U) - Index = 1 << 22, // keyof T - IndexedAccess = 1 << 23, // T[K] - Conditional = 1 << 24, // T extends U ? X : Y - Substitution = 1 << 25, // Type parameter substitution - NonPrimitive = 1 << 26, // intrinsic object type + Range = 1 << 22, // Range type (< N), (>= N), etc. + Index = 1 << 23, // keyof T + IndexedAccess = 1 << 24, // T[K] + Conditional = 1 << 25, // T extends U ? X : Y + Substitution = 1 << 26, // Type parameter substitution + NonPrimitive = 1 << 27, // intrinsic object type /* @internal */ AnyOrUnknown = Any | Unknown, @@ -4299,7 +4311,7 @@ namespace ts { /* @internal */ Primitive = String | Number | BigInt | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol, StringLike = String | StringLiteral, - NumberLike = Number | NumberLiteral | Enum, + NumberLike = Number | NumberLiteral | Enum | Range, BigIntLike = BigInt | BigIntLiteral, BooleanLike = Boolean | BooleanLiteral, EnumLike = Enum | EnumLiteral, @@ -4411,6 +4423,13 @@ namespace ts { value: PseudoBigInt; } + export interface RangeType extends Type { + min?: NumberLiteralType; + minOpen?: boolean; + max?: NumberLiteralType; + maxOpen?: boolean; + } + // Enum types (TypeFlags.Enum) export interface EnumType extends Type { } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0e09f5469fe13..9f47c99fd3d53 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -263,149 +263,150 @@ declare namespace ts { IndexedAccessType = 185, MappedType = 186, LiteralType = 187, - ImportType = 188, - ObjectBindingPattern = 189, - ArrayBindingPattern = 190, - BindingElement = 191, - ArrayLiteralExpression = 192, - ObjectLiteralExpression = 193, - PropertyAccessExpression = 194, - ElementAccessExpression = 195, - CallExpression = 196, - NewExpression = 197, - TaggedTemplateExpression = 198, - TypeAssertionExpression = 199, - ParenthesizedExpression = 200, - FunctionExpression = 201, - ArrowFunction = 202, - DeleteExpression = 203, - TypeOfExpression = 204, - VoidExpression = 205, - AwaitExpression = 206, - PrefixUnaryExpression = 207, - PostfixUnaryExpression = 208, - BinaryExpression = 209, - ConditionalExpression = 210, - TemplateExpression = 211, - YieldExpression = 212, - SpreadElement = 213, - ClassExpression = 214, - OmittedExpression = 215, - ExpressionWithTypeArguments = 216, - AsExpression = 217, - NonNullExpression = 218, - MetaProperty = 219, - SyntheticExpression = 220, - TemplateSpan = 221, - SemicolonClassElement = 222, - Block = 223, - EmptyStatement = 224, - VariableStatement = 225, - ExpressionStatement = 226, - IfStatement = 227, - DoStatement = 228, - WhileStatement = 229, - ForStatement = 230, - ForInStatement = 231, - ForOfStatement = 232, - ContinueStatement = 233, - BreakStatement = 234, - ReturnStatement = 235, - WithStatement = 236, - SwitchStatement = 237, - LabeledStatement = 238, - ThrowStatement = 239, - TryStatement = 240, - DebuggerStatement = 241, - VariableDeclaration = 242, - VariableDeclarationList = 243, - FunctionDeclaration = 244, - ClassDeclaration = 245, - InterfaceDeclaration = 246, - TypeAliasDeclaration = 247, - EnumDeclaration = 248, - ModuleDeclaration = 249, - ModuleBlock = 250, - CaseBlock = 251, - NamespaceExportDeclaration = 252, - ImportEqualsDeclaration = 253, - ImportDeclaration = 254, - ImportClause = 255, - NamespaceImport = 256, - NamedImports = 257, - ImportSpecifier = 258, - ExportAssignment = 259, - ExportDeclaration = 260, - NamedExports = 261, - NamespaceExport = 262, - ExportSpecifier = 263, - MissingDeclaration = 264, - ExternalModuleReference = 265, - JsxElement = 266, - JsxSelfClosingElement = 267, - JsxOpeningElement = 268, - JsxClosingElement = 269, - JsxFragment = 270, - JsxOpeningFragment = 271, - JsxClosingFragment = 272, - JsxAttribute = 273, - JsxAttributes = 274, - JsxSpreadAttribute = 275, - JsxExpression = 276, - CaseClause = 277, - DefaultClause = 278, - HeritageClause = 279, - CatchClause = 280, - PropertyAssignment = 281, - ShorthandPropertyAssignment = 282, - SpreadAssignment = 283, - EnumMember = 284, - UnparsedPrologue = 285, - UnparsedPrepend = 286, - UnparsedText = 287, - UnparsedInternalText = 288, - UnparsedSyntheticReference = 289, - SourceFile = 290, - Bundle = 291, - UnparsedSource = 292, - InputFiles = 293, - JSDocTypeExpression = 294, - JSDocAllType = 295, - JSDocUnknownType = 296, - JSDocNullableType = 297, - JSDocNonNullableType = 298, - JSDocOptionalType = 299, - JSDocFunctionType = 300, - JSDocVariadicType = 301, - JSDocNamepathType = 302, - JSDocComment = 303, - JSDocTypeLiteral = 304, - JSDocSignature = 305, - JSDocTag = 306, - JSDocAugmentsTag = 307, - JSDocAuthorTag = 308, - JSDocClassTag = 309, - JSDocPublicTag = 310, - JSDocPrivateTag = 311, - JSDocProtectedTag = 312, - JSDocReadonlyTag = 313, - JSDocCallbackTag = 314, - JSDocEnumTag = 315, - JSDocParameterTag = 316, - JSDocReturnTag = 317, - JSDocThisTag = 318, - JSDocTypeTag = 319, - JSDocTemplateTag = 320, - JSDocTypedefTag = 321, - JSDocPropertyTag = 322, - SyntaxList = 323, - NotEmittedStatement = 324, - PartiallyEmittedExpression = 325, - CommaListExpression = 326, - MergeDeclarationMarker = 327, - EndOfDeclarationMarker = 328, - SyntheticReferenceExpression = 329, - Count = 330, + HalfRangeType = 188, + ImportType = 189, + ObjectBindingPattern = 190, + ArrayBindingPattern = 191, + BindingElement = 192, + ArrayLiteralExpression = 193, + ObjectLiteralExpression = 194, + PropertyAccessExpression = 195, + ElementAccessExpression = 196, + CallExpression = 197, + NewExpression = 198, + TaggedTemplateExpression = 199, + TypeAssertionExpression = 200, + ParenthesizedExpression = 201, + FunctionExpression = 202, + ArrowFunction = 203, + DeleteExpression = 204, + TypeOfExpression = 205, + VoidExpression = 206, + AwaitExpression = 207, + PrefixUnaryExpression = 208, + PostfixUnaryExpression = 209, + BinaryExpression = 210, + ConditionalExpression = 211, + TemplateExpression = 212, + YieldExpression = 213, + SpreadElement = 214, + ClassExpression = 215, + OmittedExpression = 216, + ExpressionWithTypeArguments = 217, + AsExpression = 218, + NonNullExpression = 219, + MetaProperty = 220, + SyntheticExpression = 221, + TemplateSpan = 222, + SemicolonClassElement = 223, + Block = 224, + EmptyStatement = 225, + VariableStatement = 226, + ExpressionStatement = 227, + IfStatement = 228, + DoStatement = 229, + WhileStatement = 230, + ForStatement = 231, + ForInStatement = 232, + ForOfStatement = 233, + ContinueStatement = 234, + BreakStatement = 235, + ReturnStatement = 236, + WithStatement = 237, + SwitchStatement = 238, + LabeledStatement = 239, + ThrowStatement = 240, + TryStatement = 241, + DebuggerStatement = 242, + VariableDeclaration = 243, + VariableDeclarationList = 244, + FunctionDeclaration = 245, + ClassDeclaration = 246, + InterfaceDeclaration = 247, + TypeAliasDeclaration = 248, + EnumDeclaration = 249, + ModuleDeclaration = 250, + ModuleBlock = 251, + CaseBlock = 252, + NamespaceExportDeclaration = 253, + ImportEqualsDeclaration = 254, + ImportDeclaration = 255, + ImportClause = 256, + NamespaceImport = 257, + NamedImports = 258, + ImportSpecifier = 259, + ExportAssignment = 260, + ExportDeclaration = 261, + NamedExports = 262, + NamespaceExport = 263, + ExportSpecifier = 264, + MissingDeclaration = 265, + ExternalModuleReference = 266, + JsxElement = 267, + JsxSelfClosingElement = 268, + JsxOpeningElement = 269, + JsxClosingElement = 270, + JsxFragment = 271, + JsxOpeningFragment = 272, + JsxClosingFragment = 273, + JsxAttribute = 274, + JsxAttributes = 275, + JsxSpreadAttribute = 276, + JsxExpression = 277, + CaseClause = 278, + DefaultClause = 279, + HeritageClause = 280, + CatchClause = 281, + PropertyAssignment = 282, + ShorthandPropertyAssignment = 283, + SpreadAssignment = 284, + EnumMember = 285, + UnparsedPrologue = 286, + UnparsedPrepend = 287, + UnparsedText = 288, + UnparsedInternalText = 289, + UnparsedSyntheticReference = 290, + SourceFile = 291, + Bundle = 292, + UnparsedSource = 293, + InputFiles = 294, + JSDocTypeExpression = 295, + JSDocAllType = 296, + JSDocUnknownType = 297, + JSDocNullableType = 298, + JSDocNonNullableType = 299, + JSDocOptionalType = 300, + JSDocFunctionType = 301, + JSDocVariadicType = 302, + JSDocNamepathType = 303, + JSDocComment = 304, + JSDocTypeLiteral = 305, + JSDocSignature = 306, + JSDocTag = 307, + JSDocAugmentsTag = 308, + JSDocAuthorTag = 309, + JSDocClassTag = 310, + JSDocPublicTag = 311, + JSDocPrivateTag = 312, + JSDocProtectedTag = 313, + JSDocReadonlyTag = 314, + JSDocCallbackTag = 315, + JSDocEnumTag = 316, + JSDocParameterTag = 317, + JSDocReturnTag = 318, + JSDocThisTag = 319, + JSDocTypeTag = 320, + JSDocTemplateTag = 321, + JSDocTypedefTag = 322, + JSDocPropertyTag = 323, + SyntaxList = 324, + NotEmittedStatement = 325, + PartiallyEmittedExpression = 326, + CommaListExpression = 327, + MergeDeclarationMarker = 328, + EndOfDeclarationMarker = 329, + SyntheticReferenceExpression = 330, + Count = 331, FirstAssignment = 62, LastAssignment = 74, FirstCompoundAssignment = 63, @@ -417,7 +418,7 @@ declare namespace ts { FirstFutureReservedWord = 113, LastFutureReservedWord = 121, FirstTypeNode = 168, - LastTypeNode = 188, + LastTypeNode = 189, FirstPunctuation = 18, LastPunctuation = 74, FirstToken = 0, @@ -430,13 +431,13 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 29, LastBinaryOperator = 74, - FirstStatement = 225, - LastStatement = 241, + FirstStatement = 226, + LastStatement = 242, FirstNode = 153, - FirstJSDocNode = 294, - LastJSDocNode = 322, - FirstJSDocTagNode = 306, - LastJSDocTagNode = 322, + FirstJSDocNode = 295, + LastJSDocNode = 323, + FirstJSDocTagNode = 307, + LastJSDocTagNode = 323, } export enum NodeFlags { None = 0, @@ -532,6 +533,10 @@ declare namespace ts { export type PlusToken = Token; export type MinusToken = Token; export type AssertsToken = Token; + export type GreaterThanToken = Token; + export type GreaterThanEqualsToken = Token; + export type LessThanToken = Token; + export type LessThanEqualsToken = Token; export type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; export type ModifiersArray = NodeArray; export interface Identifier extends PrimaryExpression, Declaration { @@ -862,6 +867,11 @@ declare namespace ts { kind: SyntaxKind.LiteralType; literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression; } + export interface HalfRangeTypeNode extends TypeNode { + kind: SyntaxKind.HalfRangeType; + operator: LessThanToken | LessThanEqualsToken | GreaterThanToken | GreaterThanEqualsToken; + basis: NumericLiteral | PrefixUnaryExpression; + } export interface StringLiteral extends LiteralExpression, Declaration { kind: SyntaxKind.StringLiteral; } @@ -2342,17 +2352,18 @@ declare namespace ts { Object = 524288, Union = 1048576, Intersection = 2097152, - Index = 4194304, - IndexedAccess = 8388608, - Conditional = 16777216, - Substitution = 33554432, - NonPrimitive = 67108864, + Range = 4194304, + Index = 8388608, + IndexedAccess = 16777216, + Conditional = 33554432, + Substitution = 67108864, + NonPrimitive = 134217728, Literal = 2944, Unit = 109440, StringOrNumberLiteral = 384, PossiblyFalsy = 117724, StringLike = 132, - NumberLike = 296, + NumberLike = 4194600, BigIntLike = 2112, BooleanLike = 528, EnumLike = 1056, @@ -2360,13 +2371,13 @@ declare namespace ts { VoidLike = 49152, UnionOrIntersection = 3145728, StructuredType = 3670016, - TypeVariable = 8650752, - InstantiableNonPrimitive = 58982400, - InstantiablePrimitive = 4194304, - Instantiable = 63176704, - StructuredOrInstantiable = 66846720, - Narrowable = 133970943, - NotUnionOrUnit = 67637251, + TypeVariable = 17039360, + InstantiableNonPrimitive = 117702656, + InstantiablePrimitive = 8388608, + Instantiable = 126091264, + StructuredOrInstantiable = 129761280, + Narrowable = 268188671, + NotUnionOrUnit = 134746115, } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; export interface Type { @@ -2394,6 +2405,12 @@ declare namespace ts { export interface BigIntLiteralType extends LiteralType { value: PseudoBigInt; } + export interface RangeType extends Type { + min?: NumberLiteralType; + minOpen?: boolean; + max?: NumberLiteralType; + maxOpen?: boolean; + } export interface EnumType extends Type { } export enum ObjectFlags { @@ -4055,6 +4072,8 @@ declare namespace ts { function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + function createHalfRangeTypeNode(operator: HalfRangeTypeNode["operator"], basis: HalfRangeTypeNode["basis"]): HalfRangeTypeNode; + function updateHalfRangeTypeNode(node: HalfRangeTypeNode, operator: HalfRangeTypeNode["operator"], basis: HalfRangeTypeNode["basis"]): HalfRangeTypeNode; function createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; function createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 86288e69e6041..dd6015c81ae18 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -263,149 +263,150 @@ declare namespace ts { IndexedAccessType = 185, MappedType = 186, LiteralType = 187, - ImportType = 188, - ObjectBindingPattern = 189, - ArrayBindingPattern = 190, - BindingElement = 191, - ArrayLiteralExpression = 192, - ObjectLiteralExpression = 193, - PropertyAccessExpression = 194, - ElementAccessExpression = 195, - CallExpression = 196, - NewExpression = 197, - TaggedTemplateExpression = 198, - TypeAssertionExpression = 199, - ParenthesizedExpression = 200, - FunctionExpression = 201, - ArrowFunction = 202, - DeleteExpression = 203, - TypeOfExpression = 204, - VoidExpression = 205, - AwaitExpression = 206, - PrefixUnaryExpression = 207, - PostfixUnaryExpression = 208, - BinaryExpression = 209, - ConditionalExpression = 210, - TemplateExpression = 211, - YieldExpression = 212, - SpreadElement = 213, - ClassExpression = 214, - OmittedExpression = 215, - ExpressionWithTypeArguments = 216, - AsExpression = 217, - NonNullExpression = 218, - MetaProperty = 219, - SyntheticExpression = 220, - TemplateSpan = 221, - SemicolonClassElement = 222, - Block = 223, - EmptyStatement = 224, - VariableStatement = 225, - ExpressionStatement = 226, - IfStatement = 227, - DoStatement = 228, - WhileStatement = 229, - ForStatement = 230, - ForInStatement = 231, - ForOfStatement = 232, - ContinueStatement = 233, - BreakStatement = 234, - ReturnStatement = 235, - WithStatement = 236, - SwitchStatement = 237, - LabeledStatement = 238, - ThrowStatement = 239, - TryStatement = 240, - DebuggerStatement = 241, - VariableDeclaration = 242, - VariableDeclarationList = 243, - FunctionDeclaration = 244, - ClassDeclaration = 245, - InterfaceDeclaration = 246, - TypeAliasDeclaration = 247, - EnumDeclaration = 248, - ModuleDeclaration = 249, - ModuleBlock = 250, - CaseBlock = 251, - NamespaceExportDeclaration = 252, - ImportEqualsDeclaration = 253, - ImportDeclaration = 254, - ImportClause = 255, - NamespaceImport = 256, - NamedImports = 257, - ImportSpecifier = 258, - ExportAssignment = 259, - ExportDeclaration = 260, - NamedExports = 261, - NamespaceExport = 262, - ExportSpecifier = 263, - MissingDeclaration = 264, - ExternalModuleReference = 265, - JsxElement = 266, - JsxSelfClosingElement = 267, - JsxOpeningElement = 268, - JsxClosingElement = 269, - JsxFragment = 270, - JsxOpeningFragment = 271, - JsxClosingFragment = 272, - JsxAttribute = 273, - JsxAttributes = 274, - JsxSpreadAttribute = 275, - JsxExpression = 276, - CaseClause = 277, - DefaultClause = 278, - HeritageClause = 279, - CatchClause = 280, - PropertyAssignment = 281, - ShorthandPropertyAssignment = 282, - SpreadAssignment = 283, - EnumMember = 284, - UnparsedPrologue = 285, - UnparsedPrepend = 286, - UnparsedText = 287, - UnparsedInternalText = 288, - UnparsedSyntheticReference = 289, - SourceFile = 290, - Bundle = 291, - UnparsedSource = 292, - InputFiles = 293, - JSDocTypeExpression = 294, - JSDocAllType = 295, - JSDocUnknownType = 296, - JSDocNullableType = 297, - JSDocNonNullableType = 298, - JSDocOptionalType = 299, - JSDocFunctionType = 300, - JSDocVariadicType = 301, - JSDocNamepathType = 302, - JSDocComment = 303, - JSDocTypeLiteral = 304, - JSDocSignature = 305, - JSDocTag = 306, - JSDocAugmentsTag = 307, - JSDocAuthorTag = 308, - JSDocClassTag = 309, - JSDocPublicTag = 310, - JSDocPrivateTag = 311, - JSDocProtectedTag = 312, - JSDocReadonlyTag = 313, - JSDocCallbackTag = 314, - JSDocEnumTag = 315, - JSDocParameterTag = 316, - JSDocReturnTag = 317, - JSDocThisTag = 318, - JSDocTypeTag = 319, - JSDocTemplateTag = 320, - JSDocTypedefTag = 321, - JSDocPropertyTag = 322, - SyntaxList = 323, - NotEmittedStatement = 324, - PartiallyEmittedExpression = 325, - CommaListExpression = 326, - MergeDeclarationMarker = 327, - EndOfDeclarationMarker = 328, - SyntheticReferenceExpression = 329, - Count = 330, + HalfRangeType = 188, + ImportType = 189, + ObjectBindingPattern = 190, + ArrayBindingPattern = 191, + BindingElement = 192, + ArrayLiteralExpression = 193, + ObjectLiteralExpression = 194, + PropertyAccessExpression = 195, + ElementAccessExpression = 196, + CallExpression = 197, + NewExpression = 198, + TaggedTemplateExpression = 199, + TypeAssertionExpression = 200, + ParenthesizedExpression = 201, + FunctionExpression = 202, + ArrowFunction = 203, + DeleteExpression = 204, + TypeOfExpression = 205, + VoidExpression = 206, + AwaitExpression = 207, + PrefixUnaryExpression = 208, + PostfixUnaryExpression = 209, + BinaryExpression = 210, + ConditionalExpression = 211, + TemplateExpression = 212, + YieldExpression = 213, + SpreadElement = 214, + ClassExpression = 215, + OmittedExpression = 216, + ExpressionWithTypeArguments = 217, + AsExpression = 218, + NonNullExpression = 219, + MetaProperty = 220, + SyntheticExpression = 221, + TemplateSpan = 222, + SemicolonClassElement = 223, + Block = 224, + EmptyStatement = 225, + VariableStatement = 226, + ExpressionStatement = 227, + IfStatement = 228, + DoStatement = 229, + WhileStatement = 230, + ForStatement = 231, + ForInStatement = 232, + ForOfStatement = 233, + ContinueStatement = 234, + BreakStatement = 235, + ReturnStatement = 236, + WithStatement = 237, + SwitchStatement = 238, + LabeledStatement = 239, + ThrowStatement = 240, + TryStatement = 241, + DebuggerStatement = 242, + VariableDeclaration = 243, + VariableDeclarationList = 244, + FunctionDeclaration = 245, + ClassDeclaration = 246, + InterfaceDeclaration = 247, + TypeAliasDeclaration = 248, + EnumDeclaration = 249, + ModuleDeclaration = 250, + ModuleBlock = 251, + CaseBlock = 252, + NamespaceExportDeclaration = 253, + ImportEqualsDeclaration = 254, + ImportDeclaration = 255, + ImportClause = 256, + NamespaceImport = 257, + NamedImports = 258, + ImportSpecifier = 259, + ExportAssignment = 260, + ExportDeclaration = 261, + NamedExports = 262, + NamespaceExport = 263, + ExportSpecifier = 264, + MissingDeclaration = 265, + ExternalModuleReference = 266, + JsxElement = 267, + JsxSelfClosingElement = 268, + JsxOpeningElement = 269, + JsxClosingElement = 270, + JsxFragment = 271, + JsxOpeningFragment = 272, + JsxClosingFragment = 273, + JsxAttribute = 274, + JsxAttributes = 275, + JsxSpreadAttribute = 276, + JsxExpression = 277, + CaseClause = 278, + DefaultClause = 279, + HeritageClause = 280, + CatchClause = 281, + PropertyAssignment = 282, + ShorthandPropertyAssignment = 283, + SpreadAssignment = 284, + EnumMember = 285, + UnparsedPrologue = 286, + UnparsedPrepend = 287, + UnparsedText = 288, + UnparsedInternalText = 289, + UnparsedSyntheticReference = 290, + SourceFile = 291, + Bundle = 292, + UnparsedSource = 293, + InputFiles = 294, + JSDocTypeExpression = 295, + JSDocAllType = 296, + JSDocUnknownType = 297, + JSDocNullableType = 298, + JSDocNonNullableType = 299, + JSDocOptionalType = 300, + JSDocFunctionType = 301, + JSDocVariadicType = 302, + JSDocNamepathType = 303, + JSDocComment = 304, + JSDocTypeLiteral = 305, + JSDocSignature = 306, + JSDocTag = 307, + JSDocAugmentsTag = 308, + JSDocAuthorTag = 309, + JSDocClassTag = 310, + JSDocPublicTag = 311, + JSDocPrivateTag = 312, + JSDocProtectedTag = 313, + JSDocReadonlyTag = 314, + JSDocCallbackTag = 315, + JSDocEnumTag = 316, + JSDocParameterTag = 317, + JSDocReturnTag = 318, + JSDocThisTag = 319, + JSDocTypeTag = 320, + JSDocTemplateTag = 321, + JSDocTypedefTag = 322, + JSDocPropertyTag = 323, + SyntaxList = 324, + NotEmittedStatement = 325, + PartiallyEmittedExpression = 326, + CommaListExpression = 327, + MergeDeclarationMarker = 328, + EndOfDeclarationMarker = 329, + SyntheticReferenceExpression = 330, + Count = 331, FirstAssignment = 62, LastAssignment = 74, FirstCompoundAssignment = 63, @@ -417,7 +418,7 @@ declare namespace ts { FirstFutureReservedWord = 113, LastFutureReservedWord = 121, FirstTypeNode = 168, - LastTypeNode = 188, + LastTypeNode = 189, FirstPunctuation = 18, LastPunctuation = 74, FirstToken = 0, @@ -430,13 +431,13 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 29, LastBinaryOperator = 74, - FirstStatement = 225, - LastStatement = 241, + FirstStatement = 226, + LastStatement = 242, FirstNode = 153, - FirstJSDocNode = 294, - LastJSDocNode = 322, - FirstJSDocTagNode = 306, - LastJSDocTagNode = 322, + FirstJSDocNode = 295, + LastJSDocNode = 323, + FirstJSDocTagNode = 307, + LastJSDocTagNode = 323, } export enum NodeFlags { None = 0, @@ -532,6 +533,10 @@ declare namespace ts { export type PlusToken = Token; export type MinusToken = Token; export type AssertsToken = Token; + export type GreaterThanToken = Token; + export type GreaterThanEqualsToken = Token; + export type LessThanToken = Token; + export type LessThanEqualsToken = Token; export type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; export type ModifiersArray = NodeArray; export interface Identifier extends PrimaryExpression, Declaration { @@ -862,6 +867,11 @@ declare namespace ts { kind: SyntaxKind.LiteralType; literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression; } + export interface HalfRangeTypeNode extends TypeNode { + kind: SyntaxKind.HalfRangeType; + operator: LessThanToken | LessThanEqualsToken | GreaterThanToken | GreaterThanEqualsToken; + basis: NumericLiteral | PrefixUnaryExpression; + } export interface StringLiteral extends LiteralExpression, Declaration { kind: SyntaxKind.StringLiteral; } @@ -2342,17 +2352,18 @@ declare namespace ts { Object = 524288, Union = 1048576, Intersection = 2097152, - Index = 4194304, - IndexedAccess = 8388608, - Conditional = 16777216, - Substitution = 33554432, - NonPrimitive = 67108864, + Range = 4194304, + Index = 8388608, + IndexedAccess = 16777216, + Conditional = 33554432, + Substitution = 67108864, + NonPrimitive = 134217728, Literal = 2944, Unit = 109440, StringOrNumberLiteral = 384, PossiblyFalsy = 117724, StringLike = 132, - NumberLike = 296, + NumberLike = 4194600, BigIntLike = 2112, BooleanLike = 528, EnumLike = 1056, @@ -2360,13 +2371,13 @@ declare namespace ts { VoidLike = 49152, UnionOrIntersection = 3145728, StructuredType = 3670016, - TypeVariable = 8650752, - InstantiableNonPrimitive = 58982400, - InstantiablePrimitive = 4194304, - Instantiable = 63176704, - StructuredOrInstantiable = 66846720, - Narrowable = 133970943, - NotUnionOrUnit = 67637251, + TypeVariable = 17039360, + InstantiableNonPrimitive = 117702656, + InstantiablePrimitive = 8388608, + Instantiable = 126091264, + StructuredOrInstantiable = 129761280, + Narrowable = 268188671, + NotUnionOrUnit = 134746115, } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; export interface Type { @@ -2394,6 +2405,12 @@ declare namespace ts { export interface BigIntLiteralType extends LiteralType { value: PseudoBigInt; } + export interface RangeType extends Type { + min?: NumberLiteralType; + minOpen?: boolean; + max?: NumberLiteralType; + maxOpen?: boolean; + } export interface EnumType extends Type { } export enum ObjectFlags { @@ -4055,6 +4072,8 @@ declare namespace ts { function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + function createHalfRangeTypeNode(operator: HalfRangeTypeNode["operator"], basis: HalfRangeTypeNode["basis"]): HalfRangeTypeNode; + function updateHalfRangeTypeNode(node: HalfRangeTypeNode, operator: HalfRangeTypeNode["operator"], basis: HalfRangeTypeNode["basis"]): HalfRangeTypeNode; function createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; function createObjectBindingPattern(elements: readonly BindingElement[]): ObjectBindingPattern; diff --git a/tests/baselines/reference/rangeTypeAssignment.errors.txt b/tests/baselines/reference/rangeTypeAssignment.errors.txt new file mode 100644 index 0000000000000..8caf243ead58f --- /dev/null +++ b/tests/baselines/reference/rangeTypeAssignment.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/rangeTypeAssignment.ts(8,5): error TS2322: Type 'number' is not assignable to type '(< 0)'. +tests/cases/compiler/rangeTypeAssignment.ts(9,5): error TS2322: Type 'number' is not assignable to type '(> 0)'. +tests/cases/compiler/rangeTypeAssignment.ts(19,5): error TS2322: Type '(>= 0)' is not assignable to type 'C'. + + +==== tests/cases/compiler/rangeTypeAssignment.ts (3 errors) ==== + let a1: (> 0) = 1; + let a2: number = a1; + let a3: (> -1) = a1; + let a4: (>= 0) = a1; + let a5: (> 0) = a1; + + let b1: number = 0; + let b2: (< 0) = b1; + ~~ +!!! error TS2322: Type 'number' is not assignable to type '(< 0)'. + let b3: (> 0) = b1; + ~~ +!!! error TS2322: Type 'number' is not assignable to type '(> 0)'. + + enum C { + foo, + bar + } + + let c1: C = C.foo; + let c2: (>= 0) = C.foo; + + let c3: C = c2; + ~~ +!!! error TS2322: Type '(>= 0)' is not assignable to type 'C'. + \ No newline at end of file diff --git a/tests/baselines/reference/rangeTypeAssignment.js b/tests/baselines/reference/rangeTypeAssignment.js new file mode 100644 index 0000000000000..db9075e56a62d --- /dev/null +++ b/tests/baselines/reference/rangeTypeAssignment.js @@ -0,0 +1,39 @@ +//// [rangeTypeAssignment.ts] +let a1: (> 0) = 1; +let a2: number = a1; +let a3: (> -1) = a1; +let a4: (>= 0) = a1; +let a5: (> 0) = a1; + +let b1: number = 0; +let b2: (< 0) = b1; +let b3: (> 0) = b1; + +enum C { + foo, + bar +} + +let c1: C = C.foo; +let c2: (>= 0) = C.foo; + +let c3: C = c2; + + +//// [rangeTypeAssignment.js] +var a1 = 1; +var a2 = a1; +var a3 = a1; +var a4 = a1; +var a5 = a1; +var b1 = 0; +var b2 = b1; +var b3 = b1; +var C; +(function (C) { + C[C["foo"] = 0] = "foo"; + C[C["bar"] = 1] = "bar"; +})(C || (C = {})); +var c1 = C.foo; +var c2 = C.foo; +var c3 = c2; diff --git a/tests/baselines/reference/rangeTypeAssignment.symbols b/tests/baselines/reference/rangeTypeAssignment.symbols new file mode 100644 index 0000000000000..f61d5c5deba29 --- /dev/null +++ b/tests/baselines/reference/rangeTypeAssignment.symbols @@ -0,0 +1,59 @@ +=== tests/cases/compiler/rangeTypeAssignment.ts === +let a1: (> 0) = 1; +>a1 : Symbol(a1, Decl(rangeTypeAssignment.ts, 0, 3)) + +let a2: number = a1; +>a2 : Symbol(a2, Decl(rangeTypeAssignment.ts, 1, 3)) +>a1 : Symbol(a1, Decl(rangeTypeAssignment.ts, 0, 3)) + +let a3: (> -1) = a1; +>a3 : Symbol(a3, Decl(rangeTypeAssignment.ts, 2, 3)) +>a1 : Symbol(a1, Decl(rangeTypeAssignment.ts, 0, 3)) + +let a4: (>= 0) = a1; +>a4 : Symbol(a4, Decl(rangeTypeAssignment.ts, 3, 3)) +>a1 : Symbol(a1, Decl(rangeTypeAssignment.ts, 0, 3)) + +let a5: (> 0) = a1; +>a5 : Symbol(a5, Decl(rangeTypeAssignment.ts, 4, 3)) +>a1 : Symbol(a1, Decl(rangeTypeAssignment.ts, 0, 3)) + +let b1: number = 0; +>b1 : Symbol(b1, Decl(rangeTypeAssignment.ts, 6, 3)) + +let b2: (< 0) = b1; +>b2 : Symbol(b2, Decl(rangeTypeAssignment.ts, 7, 3)) +>b1 : Symbol(b1, Decl(rangeTypeAssignment.ts, 6, 3)) + +let b3: (> 0) = b1; +>b3 : Symbol(b3, Decl(rangeTypeAssignment.ts, 8, 3)) +>b1 : Symbol(b1, Decl(rangeTypeAssignment.ts, 6, 3)) + +enum C { +>C : Symbol(C, Decl(rangeTypeAssignment.ts, 8, 19)) + + foo, +>foo : Symbol(C.foo, Decl(rangeTypeAssignment.ts, 10, 8)) + + bar +>bar : Symbol(C.bar, Decl(rangeTypeAssignment.ts, 11, 8)) +} + +let c1: C = C.foo; +>c1 : Symbol(c1, Decl(rangeTypeAssignment.ts, 15, 3)) +>C : Symbol(C, Decl(rangeTypeAssignment.ts, 8, 19)) +>C.foo : Symbol(C.foo, Decl(rangeTypeAssignment.ts, 10, 8)) +>C : Symbol(C, Decl(rangeTypeAssignment.ts, 8, 19)) +>foo : Symbol(C.foo, Decl(rangeTypeAssignment.ts, 10, 8)) + +let c2: (>= 0) = C.foo; +>c2 : Symbol(c2, Decl(rangeTypeAssignment.ts, 16, 3)) +>C.foo : Symbol(C.foo, Decl(rangeTypeAssignment.ts, 10, 8)) +>C : Symbol(C, Decl(rangeTypeAssignment.ts, 8, 19)) +>foo : Symbol(C.foo, Decl(rangeTypeAssignment.ts, 10, 8)) + +let c3: C = c2; +>c3 : Symbol(c3, Decl(rangeTypeAssignment.ts, 18, 3)) +>C : Symbol(C, Decl(rangeTypeAssignment.ts, 8, 19)) +>c2 : Symbol(c2, Decl(rangeTypeAssignment.ts, 16, 3)) + diff --git a/tests/baselines/reference/rangeTypeAssignment.types b/tests/baselines/reference/rangeTypeAssignment.types new file mode 100644 index 0000000000000..813782dac90e2 --- /dev/null +++ b/tests/baselines/reference/rangeTypeAssignment.types @@ -0,0 +1,61 @@ +=== tests/cases/compiler/rangeTypeAssignment.ts === +let a1: (> 0) = 1; +>a1 : (> 0) +>1 : 1 + +let a2: number = a1; +>a2 : number +>a1 : (> 0) + +let a3: (> -1) = a1; +>a3 : (> -1) +>-1 : -1 +>1 : 1 +>a1 : (> 0) + +let a4: (>= 0) = a1; +>a4 : (>= 0) +>a1 : (> 0) + +let a5: (> 0) = a1; +>a5 : (> 0) +>a1 : (> 0) + +let b1: number = 0; +>b1 : number +>0 : 0 + +let b2: (< 0) = b1; +>b2 : (< 0) +>b1 : number + +let b3: (> 0) = b1; +>b3 : (> 0) +>b1 : number + +enum C { +>C : C + + foo, +>foo : C.foo + + bar +>bar : C.bar +} + +let c1: C = C.foo; +>c1 : C +>C.foo : C.foo +>C : typeof C +>foo : C.foo + +let c2: (>= 0) = C.foo; +>c2 : (>= 0) +>C.foo : C.foo +>C : typeof C +>foo : C.foo + +let c3: C = c2; +>c3 : C +>c2 : (>= 0) + diff --git a/tests/baselines/reference/rangeTypeBasics.errors.txt b/tests/baselines/reference/rangeTypeBasics.errors.txt new file mode 100644 index 0000000000000..81d5b51cc88f1 --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasics.errors.txt @@ -0,0 +1,109 @@ +tests/cases/compiler/rangeTypeBasics.ts(35,12): error TS1110: Type expected. +tests/cases/compiler/rangeTypeBasics.ts(35,27): error TS1005: ';' expected. +tests/cases/compiler/rangeTypeBasics.ts(36,12): error TS1110: Type expected. +tests/cases/compiler/rangeTypeBasics.ts(36,18): error TS1005: ';' expected. +tests/cases/compiler/rangeTypeBasics.ts(37,14): error TS1005: ')' expected. +tests/cases/compiler/rangeTypeBasics.ts(37,15): error TS1109: Expression expected. +tests/cases/compiler/rangeTypeBasics.ts(38,14): error TS1139: Type parameter declaration expected. +tests/cases/compiler/rangeTypeBasics.ts(38,15): error TS1109: Expression expected. +tests/cases/compiler/rangeTypeBasics.ts(39,12): error TS1110: Type expected. +tests/cases/compiler/rangeTypeBasics.ts(39,15): error TS1109: Expression expected. +tests/cases/compiler/rangeTypeBasics.ts(40,12): error TS1110: Type expected. +tests/cases/compiler/rangeTypeBasics.ts(40,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +tests/cases/compiler/rangeTypeBasics.ts(40,14): error TS1109: Expression expected. +tests/cases/compiler/rangeTypeBasics.ts(40,15): error TS1109: Expression expected. +tests/cases/compiler/rangeTypeBasics.ts(41,12): error TS1110: Type expected. +tests/cases/compiler/rangeTypeBasics.ts(41,15): error TS1109: Expression expected. +tests/cases/compiler/rangeTypeBasics.ts(42,14): error TS1139: Type parameter declaration expected. +tests/cases/compiler/rangeTypeBasics.ts(42,15): error TS1139: Type parameter declaration expected. +tests/cases/compiler/rangeTypeBasics.ts(42,16): error TS1110: Type expected. +tests/cases/compiler/rangeTypeBasics.ts(43,1): error TS1005: ')' expected. +tests/cases/compiler/rangeTypeBasics.ts(43,1): error TS1005: '>' expected. + + +==== tests/cases/compiler/rangeTypeBasics.ts (21 errors) ==== + let a1: (< 1); + let a2: (< -1); + let a3: (<= 1); + let a4: (<= -1); + let a5: (> 1); + let a6: (> -1); + let a7: (>= 1); + let a8: (>= -1); + + let a9: ((> 0)); + let a10: (((> 0))); + + declare function b1(): (> -3.14); + declare function b2(b2arg: (>= 42)): void; + declare function b3(b3arg: (< 7.4)): (> 10); + + interface C { + c1: (>= 4); + c2(c2arg: (> -6)): void; + c3(): (> 9.6); + c4(c4arg: (<= -2)): (> 100); + } + + class D { + public d1: (> 0); + d2(d2arg: (> 0)) { + return d2arg; + } + } + + type E1 = (> 4); + type E2 = (<= 10); + type E3 = (>= -42); + + type F1 = (<= "notanumber"); + ~~ +!!! error TS1110: Type expected. + ~ +!!! error TS1005: ';' expected. + type F2 = (>= "0"); + ~ +!!! error TS1110: Type expected. + ~ +!!! error TS1005: ';' expected. + type F3 = (<4>); + ~ +!!! error TS1005: ')' expected. + ~ +!!! error TS1109: Expression expected. + type F4 = (< +); + ~ +!!! error TS1139: Type parameter declaration expected. + ~ +!!! error TS1109: Expression expected. + type F5 = (> +); + ~ +!!! error TS1110: Type expected. + ~ +!!! error TS1109: Expression expected. + type F6 = (> &); + ~ +!!! error TS1110: Type expected. + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + type F7 = (>= ); + ~ +!!! error TS1110: Type expected. + ~ +!!! error TS1109: Expression expected. + type F8 = (< ); + ~ +!!! error TS1139: Type parameter declaration expected. + ~ +!!! error TS1139: Type parameter declaration expected. + +!!! error TS1110: Type expected. + + +!!! error TS1005: ')' expected. + +!!! error TS1005: '>' expected. \ No newline at end of file diff --git a/tests/baselines/reference/rangeTypeBasics.js b/tests/baselines/reference/rangeTypeBasics.js new file mode 100644 index 0000000000000..c0e95c253e833 --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasics.js @@ -0,0 +1,78 @@ +//// [rangeTypeBasics.ts] +let a1: (< 1); +let a2: (< -1); +let a3: (<= 1); +let a4: (<= -1); +let a5: (> 1); +let a6: (> -1); +let a7: (>= 1); +let a8: (>= -1); + +let a9: ((> 0)); +let a10: (((> 0))); + +declare function b1(): (> -3.14); +declare function b2(b2arg: (>= 42)): void; +declare function b3(b3arg: (< 7.4)): (> 10); + +interface C { + c1: (>= 4); + c2(c2arg: (> -6)): void; + c3(): (> 9.6); + c4(c4arg: (<= -2)): (> 100); +} + +class D { + public d1: (> 0); + d2(d2arg: (> 0)) { + return d2arg; + } +} + +type E1 = (> 4); +type E2 = (<= 10); +type E3 = (>= -42); + +type F1 = (<= "notanumber"); +type F2 = (>= "0"); +type F3 = (<4>); +type F4 = (< +); +type F5 = (> +); +type F6 = (> &); +type F7 = (>= ); +type F8 = (< ); + + +//// [rangeTypeBasics.js] +var a1; +var a2; +var a3; +var a4; +var a5; +var a6; +var a7; +var a8; +var a9; +var a10; +var D = /** @class */ (function () { + function D() { + } + D.prototype.d2 = function (d2arg) { + return d2arg; + }; + return D; +}()); + <= "notanumber"; +; + >= "0"; +; + > ; +; ++; +; + > +; +; + > & ; +; + >= ; +; diff --git a/tests/baselines/reference/rangeTypeBasics.symbols b/tests/baselines/reference/rangeTypeBasics.symbols new file mode 100644 index 0000000000000..2efc75b1c5d4b --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasics.symbols @@ -0,0 +1,108 @@ +=== tests/cases/compiler/rangeTypeBasics.ts === +let a1: (< 1); +>a1 : Symbol(a1, Decl(rangeTypeBasics.ts, 0, 3)) + +let a2: (< -1); +>a2 : Symbol(a2, Decl(rangeTypeBasics.ts, 1, 3)) + +let a3: (<= 1); +>a3 : Symbol(a3, Decl(rangeTypeBasics.ts, 2, 3)) + +let a4: (<= -1); +>a4 : Symbol(a4, Decl(rangeTypeBasics.ts, 3, 3)) + +let a5: (> 1); +>a5 : Symbol(a5, Decl(rangeTypeBasics.ts, 4, 3)) + +let a6: (> -1); +>a6 : Symbol(a6, Decl(rangeTypeBasics.ts, 5, 3)) + +let a7: (>= 1); +>a7 : Symbol(a7, Decl(rangeTypeBasics.ts, 6, 3)) + +let a8: (>= -1); +>a8 : Symbol(a8, Decl(rangeTypeBasics.ts, 7, 3)) + +let a9: ((> 0)); +>a9 : Symbol(a9, Decl(rangeTypeBasics.ts, 9, 3)) + +let a10: (((> 0))); +>a10 : Symbol(a10, Decl(rangeTypeBasics.ts, 10, 3)) + +declare function b1(): (> -3.14); +>b1 : Symbol(b1, Decl(rangeTypeBasics.ts, 10, 19)) + +declare function b2(b2arg: (>= 42)): void; +>b2 : Symbol(b2, Decl(rangeTypeBasics.ts, 12, 33)) +>b2arg : Symbol(b2arg, Decl(rangeTypeBasics.ts, 13, 20)) + +declare function b3(b3arg: (< 7.4)): (> 10); +>b3 : Symbol(b3, Decl(rangeTypeBasics.ts, 13, 42)) +>b3arg : Symbol(b3arg, Decl(rangeTypeBasics.ts, 14, 20)) + +interface C { +>C : Symbol(C, Decl(rangeTypeBasics.ts, 14, 44)) + + c1: (>= 4); +>c1 : Symbol(C.c1, Decl(rangeTypeBasics.ts, 16, 13)) + + c2(c2arg: (> -6)): void; +>c2 : Symbol(C.c2, Decl(rangeTypeBasics.ts, 17, 15)) +>c2arg : Symbol(c2arg, Decl(rangeTypeBasics.ts, 18, 7)) + + c3(): (> 9.6); +>c3 : Symbol(C.c3, Decl(rangeTypeBasics.ts, 18, 28)) + + c4(c4arg: (<= -2)): (> 100); +>c4 : Symbol(C.c4, Decl(rangeTypeBasics.ts, 19, 18)) +>c4arg : Symbol(c4arg, Decl(rangeTypeBasics.ts, 20, 7)) +} + +class D { +>D : Symbol(D, Decl(rangeTypeBasics.ts, 21, 1)) + + public d1: (> 0); +>d1 : Symbol(D.d1, Decl(rangeTypeBasics.ts, 23, 9)) + + d2(d2arg: (> 0)) { +>d2 : Symbol(D.d2, Decl(rangeTypeBasics.ts, 24, 21)) +>d2arg : Symbol(d2arg, Decl(rangeTypeBasics.ts, 25, 7)) + + return d2arg; +>d2arg : Symbol(d2arg, Decl(rangeTypeBasics.ts, 25, 7)) + } +} + +type E1 = (> 4); +>E1 : Symbol(E1, Decl(rangeTypeBasics.ts, 28, 1)) + +type E2 = (<= 10); +>E2 : Symbol(E2, Decl(rangeTypeBasics.ts, 30, 16)) + +type E3 = (>= -42); +>E3 : Symbol(E3, Decl(rangeTypeBasics.ts, 31, 18)) + +type F1 = (<= "notanumber"); +>F1 : Symbol(F1, Decl(rangeTypeBasics.ts, 32, 19)) + +type F2 = (>= "0"); +>F2 : Symbol(F2, Decl(rangeTypeBasics.ts, 34, 28)) + +type F3 = (<4>); +>F3 : Symbol(F3, Decl(rangeTypeBasics.ts, 35, 19)) + +type F4 = (< +); +>F4 : Symbol(F4, Decl(rangeTypeBasics.ts, 36, 16)) + +type F5 = (> +); +>F5 : Symbol(F5, Decl(rangeTypeBasics.ts, 37, 16)) + +type F6 = (> &); +>F6 : Symbol(F6, Decl(rangeTypeBasics.ts, 38, 16)) + +type F7 = (>= ); +>F7 : Symbol(F7, Decl(rangeTypeBasics.ts, 39, 16)) + +type F8 = (< ); +>F8 : Symbol(F8, Decl(rangeTypeBasics.ts, 40, 16)) + diff --git a/tests/baselines/reference/rangeTypeBasics.types b/tests/baselines/reference/rangeTypeBasics.types new file mode 100644 index 0000000000000..41137172d20d0 --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasics.types @@ -0,0 +1,145 @@ +=== tests/cases/compiler/rangeTypeBasics.ts === +let a1: (< 1); +>a1 : (< 1) + +let a2: (< -1); +>a2 : (< -1) +>-1 : -1 +>1 : 1 + +let a3: (<= 1); +>a3 : (<= 1) + +let a4: (<= -1); +>a4 : (<= -1) +>-1 : -1 +>1 : 1 + +let a5: (> 1); +>a5 : (> 1) + +let a6: (> -1); +>a6 : (> -1) +>-1 : -1 +>1 : 1 + +let a7: (>= 1); +>a7 : (>= 1) + +let a8: (>= -1); +>a8 : (>= -1) +>-1 : -1 +>1 : 1 + +let a9: ((> 0)); +>a9 : (> 0) + +let a10: (((> 0))); +>a10 : (> 0) + +declare function b1(): (> -3.14); +>b1 : () => (> -3.14) +>-3.14 : -3.14 +>3.14 : 3.14 + +declare function b2(b2arg: (>= 42)): void; +>b2 : (b2arg: (>= 42)) => void +>b2arg : (>= 42) + +declare function b3(b3arg: (< 7.4)): (> 10); +>b3 : (b3arg: (< 7.4)) => (> 10) +>b3arg : (< 7.4) + +interface C { + c1: (>= 4); +>c1 : (>= 4) + + c2(c2arg: (> -6)): void; +>c2 : (c2arg: (> -6)) => void +>c2arg : (> -6) +>-6 : -6 +>6 : 6 + + c3(): (> 9.6); +>c3 : () => (> 9.6) + + c4(c4arg: (<= -2)): (> 100); +>c4 : (c4arg: (<= -2)) => (> 100) +>c4arg : (<= -2) +>-2 : -2 +>2 : 2 +} + +class D { +>D : D + + public d1: (> 0); +>d1 : (> 0) + + d2(d2arg: (> 0)) { +>d2 : (d2arg: (> 0)) => (> 0) +>d2arg : (> 0) + + return d2arg; +>d2arg : (> 0) + } +} + +type E1 = (> 4); +>E1 : (> 4) + +type E2 = (<= 10); +>E2 : (<= 10) + +type E3 = (>= -42); +>E3 : (>= -42) +>-42 : -42 +>42 : 42 + +type F1 = (<= "notanumber"); +>F1 : any +><= "notanumber" : boolean +> : any +>"notanumber" : "notanumber" + +type F2 = (>= "0"); +>F2 : any +>>= "0" : boolean +> : any +>"0" : "0" + +type F3 = (<4>); +>F3 : (< 4) +>> : boolean +> : any +> : any + +type F4 = (< +); +>F4 : () => any +>+ : number +> : any + +type F5 = (> +); +>F5 : any +>> + : boolean +> : any +>+ : number +> : any + +type F6 = (> &); +>F6 : any +>> & : number +>> : boolean +> : any +> : any +> : any + +type F7 = (>= ); +>F7 : any +>>= : boolean +> : any +> : any + +type F8 = (< ); +>F8 : () => any + diff --git a/tests/baselines/reference/rangeTypeDeclaration.errors.txt b/tests/baselines/reference/rangeTypeDeclaration.errors.txt new file mode 100644 index 0000000000000..b41b850af22e7 --- /dev/null +++ b/tests/baselines/reference/rangeTypeDeclaration.errors.txt @@ -0,0 +1,51 @@ +tests/cases/compiler/rangeTypeDeclaration.ts(4,5): error TS2322: Type 'number' is not assignable to type '(<= 4.5)'. +tests/cases/compiler/rangeTypeDeclaration.ts(8,5): error TS2322: Type '1.2' is not assignable to type '(> 1.2)'. +tests/cases/compiler/rangeTypeDeclaration.ts(9,5): error TS2322: Type '1.2' is not assignable to type '(< 1.2)'. +tests/cases/compiler/rangeTypeDeclaration.ts(10,5): error TS2322: Type '-1' is not assignable to type '(>= 0)'. +tests/cases/compiler/rangeTypeDeclaration.ts(11,5): error TS2322: Type '42' is not assignable to type '(< 0)'. +tests/cases/compiler/rangeTypeDeclaration.ts(29,5): error TS2322: Type 'D.bar' is not assignable to type '(<= 0)'. + + +==== tests/cases/compiler/rangeTypeDeclaration.ts (6 errors) ==== + let a1: (> -1) = 0; + let a2: (< 1) = -10; + let a4: (> 0.1) = 0.5; + let a5: (<= 4.5) = Math.E; + ~~ +!!! error TS2322: Type 'number' is not assignable to type '(<= 4.5)'. + let a6: (>= -4) = 1.5; + let a7: (>= 2) = 2; + + let b1: (> 1.2) = 1.2; + ~~ +!!! error TS2322: Type '1.2' is not assignable to type '(> 1.2)'. + let b2: (< 1.2) = 1.2; + ~~ +!!! error TS2322: Type '1.2' is not assignable to type '(< 1.2)'. + let b3: (>= 0) = -1; + ~~ +!!! error TS2322: Type '-1' is not assignable to type '(>= 0)'. + let b4: (< 0) = 42; + ~~ +!!! error TS2322: Type '42' is not assignable to type '(< 0)'. + + enum C { + foo, + bar + } + + let c1: (>= 0) = C.foo; + let c2: C = c1; + + const enum D { + foo, + bar + } + + let d1: (>= 0) = D.foo; + let d2: (<= 0) = D.foo; + + let d3: (<= 0) = D.bar; + ~~ +!!! error TS2322: Type 'D.bar' is not assignable to type '(<= 0)'. + \ No newline at end of file diff --git a/tests/baselines/reference/rangeTypeDeclaration.js b/tests/baselines/reference/rangeTypeDeclaration.js new file mode 100644 index 0000000000000..fd06c330c3f1e --- /dev/null +++ b/tests/baselines/reference/rangeTypeDeclaration.js @@ -0,0 +1,53 @@ +//// [rangeTypeDeclaration.ts] +let a1: (> -1) = 0; +let a2: (< 1) = -10; +let a4: (> 0.1) = 0.5; +let a5: (<= 4.5) = Math.E; +let a6: (>= -4) = 1.5; +let a7: (>= 2) = 2; + +let b1: (> 1.2) = 1.2; +let b2: (< 1.2) = 1.2; +let b3: (>= 0) = -1; +let b4: (< 0) = 42; + +enum C { + foo, + bar +} + +let c1: (>= 0) = C.foo; +let c2: C = c1; + +const enum D { + foo, + bar +} + +let d1: (>= 0) = D.foo; +let d2: (<= 0) = D.foo; + +let d3: (<= 0) = D.bar; + + +//// [rangeTypeDeclaration.js] +var a1 = 0; +var a2 = -10; +var a4 = 0.5; +var a5 = Math.E; +var a6 = 1.5; +var a7 = 2; +var b1 = 1.2; +var b2 = 1.2; +var b3 = -1; +var b4 = 42; +var C; +(function (C) { + C[C["foo"] = 0] = "foo"; + C[C["bar"] = 1] = "bar"; +})(C || (C = {})); +var c1 = C.foo; +var c2 = c1; +var d1 = 0 /* foo */; +var d2 = 0 /* foo */; +var d3 = 1 /* bar */; diff --git a/tests/baselines/reference/rangeTypeDeclaration.symbols b/tests/baselines/reference/rangeTypeDeclaration.symbols new file mode 100644 index 0000000000000..5d906cf443d83 --- /dev/null +++ b/tests/baselines/reference/rangeTypeDeclaration.symbols @@ -0,0 +1,84 @@ +=== tests/cases/compiler/rangeTypeDeclaration.ts === +let a1: (> -1) = 0; +>a1 : Symbol(a1, Decl(rangeTypeDeclaration.ts, 0, 3)) + +let a2: (< 1) = -10; +>a2 : Symbol(a2, Decl(rangeTypeDeclaration.ts, 1, 3)) + +let a4: (> 0.1) = 0.5; +>a4 : Symbol(a4, Decl(rangeTypeDeclaration.ts, 2, 3)) + +let a5: (<= 4.5) = Math.E; +>a5 : Symbol(a5, Decl(rangeTypeDeclaration.ts, 3, 3)) +>Math.E : Symbol(Math.E, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>E : Symbol(Math.E, Decl(lib.es5.d.ts, --, --)) + +let a6: (>= -4) = 1.5; +>a6 : Symbol(a6, Decl(rangeTypeDeclaration.ts, 4, 3)) + +let a7: (>= 2) = 2; +>a7 : Symbol(a7, Decl(rangeTypeDeclaration.ts, 5, 3)) + +let b1: (> 1.2) = 1.2; +>b1 : Symbol(b1, Decl(rangeTypeDeclaration.ts, 7, 3)) + +let b2: (< 1.2) = 1.2; +>b2 : Symbol(b2, Decl(rangeTypeDeclaration.ts, 8, 3)) + +let b3: (>= 0) = -1; +>b3 : Symbol(b3, Decl(rangeTypeDeclaration.ts, 9, 3)) + +let b4: (< 0) = 42; +>b4 : Symbol(b4, Decl(rangeTypeDeclaration.ts, 10, 3)) + +enum C { +>C : Symbol(C, Decl(rangeTypeDeclaration.ts, 10, 19)) + + foo, +>foo : Symbol(C.foo, Decl(rangeTypeDeclaration.ts, 12, 8)) + + bar +>bar : Symbol(C.bar, Decl(rangeTypeDeclaration.ts, 13, 8)) +} + +let c1: (>= 0) = C.foo; +>c1 : Symbol(c1, Decl(rangeTypeDeclaration.ts, 17, 3)) +>C.foo : Symbol(C.foo, Decl(rangeTypeDeclaration.ts, 12, 8)) +>C : Symbol(C, Decl(rangeTypeDeclaration.ts, 10, 19)) +>foo : Symbol(C.foo, Decl(rangeTypeDeclaration.ts, 12, 8)) + +let c2: C = c1; +>c2 : Symbol(c2, Decl(rangeTypeDeclaration.ts, 18, 3)) +>C : Symbol(C, Decl(rangeTypeDeclaration.ts, 10, 19)) +>C : Symbol(C, Decl(rangeTypeDeclaration.ts, 10, 19)) +>c1 : Symbol(c1, Decl(rangeTypeDeclaration.ts, 17, 3)) + +const enum D { +>D : Symbol(D, Decl(rangeTypeDeclaration.ts, 18, 18)) + + foo, +>foo : Symbol(D.foo, Decl(rangeTypeDeclaration.ts, 20, 14)) + + bar +>bar : Symbol(D.bar, Decl(rangeTypeDeclaration.ts, 21, 8)) +} + +let d1: (>= 0) = D.foo; +>d1 : Symbol(d1, Decl(rangeTypeDeclaration.ts, 25, 3)) +>D.foo : Symbol(D.foo, Decl(rangeTypeDeclaration.ts, 20, 14)) +>D : Symbol(D, Decl(rangeTypeDeclaration.ts, 18, 18)) +>foo : Symbol(D.foo, Decl(rangeTypeDeclaration.ts, 20, 14)) + +let d2: (<= 0) = D.foo; +>d2 : Symbol(d2, Decl(rangeTypeDeclaration.ts, 26, 3)) +>D.foo : Symbol(D.foo, Decl(rangeTypeDeclaration.ts, 20, 14)) +>D : Symbol(D, Decl(rangeTypeDeclaration.ts, 18, 18)) +>foo : Symbol(D.foo, Decl(rangeTypeDeclaration.ts, 20, 14)) + +let d3: (<= 0) = D.bar; +>d3 : Symbol(d3, Decl(rangeTypeDeclaration.ts, 28, 3)) +>D.bar : Symbol(D.bar, Decl(rangeTypeDeclaration.ts, 21, 8)) +>D : Symbol(D, Decl(rangeTypeDeclaration.ts, 18, 18)) +>bar : Symbol(D.bar, Decl(rangeTypeDeclaration.ts, 21, 8)) + diff --git a/tests/baselines/reference/rangeTypeDeclaration.types b/tests/baselines/reference/rangeTypeDeclaration.types new file mode 100644 index 0000000000000..6ef99a74c63de --- /dev/null +++ b/tests/baselines/reference/rangeTypeDeclaration.types @@ -0,0 +1,98 @@ +=== tests/cases/compiler/rangeTypeDeclaration.ts === +let a1: (> -1) = 0; +>a1 : (> -1) +>-1 : -1 +>1 : 1 +>0 : 0 + +let a2: (< 1) = -10; +>a2 : (< 1) +>-10 : -10 +>10 : 10 + +let a4: (> 0.1) = 0.5; +>a4 : (> 0.1) +>0.5 : 0.5 + +let a5: (<= 4.5) = Math.E; +>a5 : (<= 4.5) +>Math.E : number +>Math : Math +>E : number + +let a6: (>= -4) = 1.5; +>a6 : (>= -4) +>-4 : -4 +>4 : 4 +>1.5 : 1.5 + +let a7: (>= 2) = 2; +>a7 : (>= 2) +>2 : 2 + +let b1: (> 1.2) = 1.2; +>b1 : (> 1.2) +>1.2 : 1.2 + +let b2: (< 1.2) = 1.2; +>b2 : (< 1.2) +>1.2 : 1.2 + +let b3: (>= 0) = -1; +>b3 : (>= 0) +>-1 : -1 +>1 : 1 + +let b4: (< 0) = 42; +>b4 : (< 0) +>42 : 42 + +enum C { +>C : C + + foo, +>foo : C.foo + + bar +>bar : C.bar +} + +let c1: (>= 0) = C.foo; +>c1 : (>= 0) +>C.foo : C.foo +>C : typeof C +>foo : C.foo + +let c2: C = c1; +>c2 : C +>c1 : C +>c1 : (>= 0) + +const enum D { +>D : D + + foo, +>foo : D.foo + + bar +>bar : D.bar +} + +let d1: (>= 0) = D.foo; +>d1 : (>= 0) +>D.foo : D.foo +>D : typeof D +>foo : D.foo + +let d2: (<= 0) = D.foo; +>d2 : (<= 0) +>D.foo : D.foo +>D : typeof D +>foo : D.foo + +let d3: (<= 0) = D.bar; +>d3 : (<= 0) +>D.bar : D.bar +>D : typeof D +>bar : D.bar + diff --git a/tests/baselines/reference/rangeTypeFunctionDeclarations.errors.txt b/tests/baselines/reference/rangeTypeFunctionDeclarations.errors.txt new file mode 100644 index 0000000000000..ba2137e9332e8 --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctionDeclarations.errors.txt @@ -0,0 +1,34 @@ +tests/cases/compiler/rangeTypeFunctionDeclarations.ts(3,3): error TS2345: Argument of type 'number' is not assignable to parameter of type '(> 0)'. +tests/cases/compiler/rangeTypeFunctionDeclarations.ts(8,3): error TS2345: Argument of type 'number' is not assignable to parameter of type '(> 0)'. +tests/cases/compiler/rangeTypeFunctionDeclarations.ts(10,3): error TS2345: Argument of type '(>= 0)' is not assignable to parameter of type '(> 0)'. +tests/cases/compiler/rangeTypeFunctionDeclarations.ts(18,5): error TS2322: Type '(< 1)' is not assignable to type '(< 0)'. + + +==== tests/cases/compiler/rangeTypeFunctionDeclarations.ts (4 errors) ==== + declare function a(arg: (> 0)): void; + let a1 = 1; + a(a1); + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type '(> 0)'. + let a2: (> 1) = 2; + a(a2); + + let a3 = 0; + a(a3); + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type '(> 0)'. + let a4: (>= 0) = 0; + a(a4); + ~~ +!!! error TS2345: Argument of type '(>= 0)' is not assignable to parameter of type '(> 0)'. + + + declare function b(): (< 1); + let b1: (< 1) = b(); + let b2: (<= 1) = b(); + let b3: (< 2) = b(); + + let b4: (< 0) = b(); + ~~ +!!! error TS2322: Type '(< 1)' is not assignable to type '(< 0)'. + \ No newline at end of file diff --git a/tests/baselines/reference/rangeTypeFunctionDeclarations.js b/tests/baselines/reference/rangeTypeFunctionDeclarations.js new file mode 100644 index 0000000000000..1fa525b1d51bb --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctionDeclarations.js @@ -0,0 +1,34 @@ +//// [rangeTypeFunctionDeclarations.ts] +declare function a(arg: (> 0)): void; +let a1 = 1; +a(a1); +let a2: (> 1) = 2; +a(a2); + +let a3 = 0; +a(a3); +let a4: (>= 0) = 0; +a(a4); + + +declare function b(): (< 1); +let b1: (< 1) = b(); +let b2: (<= 1) = b(); +let b3: (< 2) = b(); + +let b4: (< 0) = b(); + + +//// [rangeTypeFunctionDeclarations.js] +var a1 = 1; +a(a1); +var a2 = 2; +a(a2); +var a3 = 0; +a(a3); +var a4 = 0; +a(a4); +var b1 = b(); +var b2 = b(); +var b3 = b(); +var b4 = b(); diff --git a/tests/baselines/reference/rangeTypeFunctionDeclarations.symbols b/tests/baselines/reference/rangeTypeFunctionDeclarations.symbols new file mode 100644 index 0000000000000..7795d00150a6b --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctionDeclarations.symbols @@ -0,0 +1,53 @@ +=== tests/cases/compiler/rangeTypeFunctionDeclarations.ts === +declare function a(arg: (> 0)): void; +>a : Symbol(a, Decl(rangeTypeFunctionDeclarations.ts, 0, 0)) +>arg : Symbol(arg, Decl(rangeTypeFunctionDeclarations.ts, 0, 19)) + +let a1 = 1; +>a1 : Symbol(a1, Decl(rangeTypeFunctionDeclarations.ts, 1, 3)) + +a(a1); +>a : Symbol(a, Decl(rangeTypeFunctionDeclarations.ts, 0, 0)) +>a1 : Symbol(a1, Decl(rangeTypeFunctionDeclarations.ts, 1, 3)) + +let a2: (> 1) = 2; +>a2 : Symbol(a2, Decl(rangeTypeFunctionDeclarations.ts, 3, 3)) + +a(a2); +>a : Symbol(a, Decl(rangeTypeFunctionDeclarations.ts, 0, 0)) +>a2 : Symbol(a2, Decl(rangeTypeFunctionDeclarations.ts, 3, 3)) + +let a3 = 0; +>a3 : Symbol(a3, Decl(rangeTypeFunctionDeclarations.ts, 6, 3)) + +a(a3); +>a : Symbol(a, Decl(rangeTypeFunctionDeclarations.ts, 0, 0)) +>a3 : Symbol(a3, Decl(rangeTypeFunctionDeclarations.ts, 6, 3)) + +let a4: (>= 0) = 0; +>a4 : Symbol(a4, Decl(rangeTypeFunctionDeclarations.ts, 8, 3)) + +a(a4); +>a : Symbol(a, Decl(rangeTypeFunctionDeclarations.ts, 0, 0)) +>a4 : Symbol(a4, Decl(rangeTypeFunctionDeclarations.ts, 8, 3)) + + +declare function b(): (< 1); +>b : Symbol(b, Decl(rangeTypeFunctionDeclarations.ts, 9, 6)) + +let b1: (< 1) = b(); +>b1 : Symbol(b1, Decl(rangeTypeFunctionDeclarations.ts, 13, 3)) +>b : Symbol(b, Decl(rangeTypeFunctionDeclarations.ts, 9, 6)) + +let b2: (<= 1) = b(); +>b2 : Symbol(b2, Decl(rangeTypeFunctionDeclarations.ts, 14, 3)) +>b : Symbol(b, Decl(rangeTypeFunctionDeclarations.ts, 9, 6)) + +let b3: (< 2) = b(); +>b3 : Symbol(b3, Decl(rangeTypeFunctionDeclarations.ts, 15, 3)) +>b : Symbol(b, Decl(rangeTypeFunctionDeclarations.ts, 9, 6)) + +let b4: (< 0) = b(); +>b4 : Symbol(b4, Decl(rangeTypeFunctionDeclarations.ts, 17, 3)) +>b : Symbol(b, Decl(rangeTypeFunctionDeclarations.ts, 9, 6)) + diff --git a/tests/baselines/reference/rangeTypeFunctionDeclarations.types b/tests/baselines/reference/rangeTypeFunctionDeclarations.types new file mode 100644 index 0000000000000..c403f138cb1d5 --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctionDeclarations.types @@ -0,0 +1,65 @@ +=== tests/cases/compiler/rangeTypeFunctionDeclarations.ts === +declare function a(arg: (> 0)): void; +>a : (arg: (> 0)) => void +>arg : (> 0) + +let a1 = 1; +>a1 : number +>1 : 1 + +a(a1); +>a(a1) : void +>a : (arg: (> 0)) => void +>a1 : number + +let a2: (> 1) = 2; +>a2 : (> 1) +>2 : 2 + +a(a2); +>a(a2) : void +>a : (arg: (> 0)) => void +>a2 : (> 1) + +let a3 = 0; +>a3 : number +>0 : 0 + +a(a3); +>a(a3) : void +>a : (arg: (> 0)) => void +>a3 : number + +let a4: (>= 0) = 0; +>a4 : (>= 0) +>0 : 0 + +a(a4); +>a(a4) : void +>a : (arg: (> 0)) => void +>a4 : (>= 0) + + +declare function b(): (< 1); +>b : () => (< 1) + +let b1: (< 1) = b(); +>b1 : (< 1) +>b() : (< 1) +>b : () => (< 1) + +let b2: (<= 1) = b(); +>b2 : (<= 1) +>b() : (< 1) +>b : () => (< 1) + +let b3: (< 2) = b(); +>b3 : (< 2) +>b() : (< 1) +>b : () => (< 1) + +let b4: (< 0) = b(); +>b4 : (< 0) +>b() : (< 1) +>b : () => (< 1) + diff --git a/tests/baselines/reference/rangeTypeFunctions.errors.txt b/tests/baselines/reference/rangeTypeFunctions.errors.txt new file mode 100644 index 0000000000000..31a7b19ee7292 --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctions.errors.txt @@ -0,0 +1,69 @@ +tests/cases/compiler/rangeTypeFunctions.ts(10,5): error TS2322: Type '(> 1)' is not assignable to type '(> 2)'. +tests/cases/compiler/rangeTypeFunctions.ts(11,5): error TS2322: Type '(> 1)' is not assignable to type '(< 4)'. +tests/cases/compiler/rangeTypeFunctions.ts(21,5): error TS2322: Type '(>= 0)' is not assignable to type '(> 0)'. +tests/cases/compiler/rangeTypeFunctions.ts(22,5): error TS2322: Type '(>= 0)' is not assignable to type '(>= 1)'. +tests/cases/compiler/rangeTypeFunctions.ts(26,5): error TS2322: Type '0' is not assignable to type '(> 0)'. +tests/cases/compiler/rangeTypeFunctions.ts(36,12): error TS2345: Argument of type '0' is not assignable to parameter of type '(> 0)'. +tests/cases/compiler/rangeTypeFunctions.ts(44,12): error TS2345: Argument of type '0' is not assignable to parameter of type '(> 0)'. + + +==== tests/cases/compiler/rangeTypeFunctions.ts (7 errors) ==== + function a(): (> 1) { + return 3; + } + let a0 = a(); + let a1: number = a(); + let a2: (> 1) = a(); + let a3: (>= 1) = a(); + let a4: (> 0) = a(); + + let a5: (> 2) = a(); + ~~ +!!! error TS2322: Type '(> 1)' is not assignable to type '(> 2)'. + let a6: (< 4) = a(); + ~~ +!!! error TS2322: Type '(> 1)' is not assignable to type '(< 4)'. + + + function b(): (>= 0) { + return 0; + } + let b0 = b(); + let b1: number = b(); + let b2: (>= 0) = b(); + + let b3: (> 0) = b(); + ~~ +!!! error TS2322: Type '(>= 0)' is not assignable to type '(> 0)'. + let b4: (>= 1) = b(); + ~~ +!!! error TS2322: Type '(>= 0)' is not assignable to type '(>= 1)'. + + + function c(): (> 0) { + return 0; + ~~~~~~~~~ +!!! error TS2322: Type '0' is not assignable to type '(> 0)'. + } + + + function d(arg: (> 0)): void { + arg; + return; + } + let d1 = d(1); + + let d2 = d(0); + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '(> 0)'. + + + function e(arg: (> 0)): (> 0) { + return arg; + } + let e1 = e(1); + + let e2 = e(0); + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '(> 0)'. + \ No newline at end of file diff --git a/tests/baselines/reference/rangeTypeFunctions.js b/tests/baselines/reference/rangeTypeFunctions.js new file mode 100644 index 0000000000000..5996faa4d83d2 --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctions.js @@ -0,0 +1,80 @@ +//// [rangeTypeFunctions.ts] +function a(): (> 1) { + return 3; +} +let a0 = a(); +let a1: number = a(); +let a2: (> 1) = a(); +let a3: (>= 1) = a(); +let a4: (> 0) = a(); + +let a5: (> 2) = a(); +let a6: (< 4) = a(); + + +function b(): (>= 0) { + return 0; +} +let b0 = b(); +let b1: number = b(); +let b2: (>= 0) = b(); + +let b3: (> 0) = b(); +let b4: (>= 1) = b(); + + +function c(): (> 0) { + return 0; +} + + +function d(arg: (> 0)): void { + arg; + return; +} +let d1 = d(1); + +let d2 = d(0); + + +function e(arg: (> 0)): (> 0) { + return arg; +} +let e1 = e(1); + +let e2 = e(0); + + +//// [rangeTypeFunctions.js] +function a() { + return 3; +} +var a0 = a(); +var a1 = a(); +var a2 = a(); +var a3 = a(); +var a4 = a(); +var a5 = a(); +var a6 = a(); +function b() { + return 0; +} +var b0 = b(); +var b1 = b(); +var b2 = b(); +var b3 = b(); +var b4 = b(); +function c() { + return 0; +} +function d(arg) { + arg; + return; +} +var d1 = d(1); +var d2 = d(0); +function e(arg) { + return arg; +} +var e1 = e(1); +var e2 = e(0); diff --git a/tests/baselines/reference/rangeTypeFunctions.symbols b/tests/baselines/reference/rangeTypeFunctions.symbols new file mode 100644 index 0000000000000..cd3641654949a --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctions.symbols @@ -0,0 +1,101 @@ +=== tests/cases/compiler/rangeTypeFunctions.ts === +function a(): (> 1) { +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + + return 3; +} +let a0 = a(); +>a0 : Symbol(a0, Decl(rangeTypeFunctions.ts, 3, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + +let a1: number = a(); +>a1 : Symbol(a1, Decl(rangeTypeFunctions.ts, 4, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + +let a2: (> 1) = a(); +>a2 : Symbol(a2, Decl(rangeTypeFunctions.ts, 5, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + +let a3: (>= 1) = a(); +>a3 : Symbol(a3, Decl(rangeTypeFunctions.ts, 6, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + +let a4: (> 0) = a(); +>a4 : Symbol(a4, Decl(rangeTypeFunctions.ts, 7, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + +let a5: (> 2) = a(); +>a5 : Symbol(a5, Decl(rangeTypeFunctions.ts, 9, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + +let a6: (< 4) = a(); +>a6 : Symbol(a6, Decl(rangeTypeFunctions.ts, 10, 3)) +>a : Symbol(a, Decl(rangeTypeFunctions.ts, 0, 0)) + + +function b(): (>= 0) { +>b : Symbol(b, Decl(rangeTypeFunctions.ts, 10, 20)) + + return 0; +} +let b0 = b(); +>b0 : Symbol(b0, Decl(rangeTypeFunctions.ts, 16, 3)) +>b : Symbol(b, Decl(rangeTypeFunctions.ts, 10, 20)) + +let b1: number = b(); +>b1 : Symbol(b1, Decl(rangeTypeFunctions.ts, 17, 3)) +>b : Symbol(b, Decl(rangeTypeFunctions.ts, 10, 20)) + +let b2: (>= 0) = b(); +>b2 : Symbol(b2, Decl(rangeTypeFunctions.ts, 18, 3)) +>b : Symbol(b, Decl(rangeTypeFunctions.ts, 10, 20)) + +let b3: (> 0) = b(); +>b3 : Symbol(b3, Decl(rangeTypeFunctions.ts, 20, 3)) +>b : Symbol(b, Decl(rangeTypeFunctions.ts, 10, 20)) + +let b4: (>= 1) = b(); +>b4 : Symbol(b4, Decl(rangeTypeFunctions.ts, 21, 3)) +>b : Symbol(b, Decl(rangeTypeFunctions.ts, 10, 20)) + + +function c(): (> 0) { +>c : Symbol(c, Decl(rangeTypeFunctions.ts, 21, 21)) + + return 0; +} + + +function d(arg: (> 0)): void { +>d : Symbol(d, Decl(rangeTypeFunctions.ts, 26, 1)) +>arg : Symbol(arg, Decl(rangeTypeFunctions.ts, 29, 11)) + + arg; +>arg : Symbol(arg, Decl(rangeTypeFunctions.ts, 29, 11)) + + return; +} +let d1 = d(1); +>d1 : Symbol(d1, Decl(rangeTypeFunctions.ts, 33, 3)) +>d : Symbol(d, Decl(rangeTypeFunctions.ts, 26, 1)) + +let d2 = d(0); +>d2 : Symbol(d2, Decl(rangeTypeFunctions.ts, 35, 3)) +>d : Symbol(d, Decl(rangeTypeFunctions.ts, 26, 1)) + + +function e(arg: (> 0)): (> 0) { +>e : Symbol(e, Decl(rangeTypeFunctions.ts, 35, 14)) +>arg : Symbol(arg, Decl(rangeTypeFunctions.ts, 38, 11)) + + return arg; +>arg : Symbol(arg, Decl(rangeTypeFunctions.ts, 38, 11)) +} +let e1 = e(1); +>e1 : Symbol(e1, Decl(rangeTypeFunctions.ts, 41, 3)) +>e : Symbol(e, Decl(rangeTypeFunctions.ts, 35, 14)) + +let e2 = e(0); +>e2 : Symbol(e2, Decl(rangeTypeFunctions.ts, 43, 3)) +>e : Symbol(e, Decl(rangeTypeFunctions.ts, 35, 14)) + diff --git a/tests/baselines/reference/rangeTypeFunctions.types b/tests/baselines/reference/rangeTypeFunctions.types new file mode 100644 index 0000000000000..8d1eb4fc41ada --- /dev/null +++ b/tests/baselines/reference/rangeTypeFunctions.types @@ -0,0 +1,124 @@ +=== tests/cases/compiler/rangeTypeFunctions.ts === +function a(): (> 1) { +>a : () => (> 1) + + return 3; +>3 : 3 +} +let a0 = a(); +>a0 : (> 1) +>a() : (> 1) +>a : () => (> 1) + +let a1: number = a(); +>a1 : number +>a() : (> 1) +>a : () => (> 1) + +let a2: (> 1) = a(); +>a2 : (> 1) +>a() : (> 1) +>a : () => (> 1) + +let a3: (>= 1) = a(); +>a3 : (>= 1) +>a() : (> 1) +>a : () => (> 1) + +let a4: (> 0) = a(); +>a4 : (> 0) +>a() : (> 1) +>a : () => (> 1) + +let a5: (> 2) = a(); +>a5 : (> 2) +>a() : (> 1) +>a : () => (> 1) + +let a6: (< 4) = a(); +>a6 : (< 4) +>a() : (> 1) +>a : () => (> 1) + + +function b(): (>= 0) { +>b : () => (>= 0) + + return 0; +>0 : 0 +} +let b0 = b(); +>b0 : (>= 0) +>b() : (>= 0) +>b : () => (>= 0) + +let b1: number = b(); +>b1 : number +>b() : (>= 0) +>b : () => (>= 0) + +let b2: (>= 0) = b(); +>b2 : (>= 0) +>b() : (>= 0) +>b : () => (>= 0) + +let b3: (> 0) = b(); +>b3 : (> 0) +>b() : (>= 0) +>b : () => (>= 0) + +let b4: (>= 1) = b(); +>b4 : (>= 1) +>b() : (>= 0) +>b : () => (>= 0) + + +function c(): (> 0) { +>c : () => (> 0) + + return 0; +>0 : 0 +} + + +function d(arg: (> 0)): void { +>d : (arg: (> 0)) => void +>arg : (> 0) + + arg; +>arg : (> 0) + + return; +} +let d1 = d(1); +>d1 : void +>d(1) : void +>d : (arg: (> 0)) => void +>1 : 1 + +let d2 = d(0); +>d2 : void +>d(0) : void +>d : (arg: (> 0)) => void +>0 : 0 + + +function e(arg: (> 0)): (> 0) { +>e : (arg: (> 0)) => (> 0) +>arg : (> 0) + + return arg; +>arg : (> 0) +} +let e1 = e(1); +>e1 : (> 0) +>e(1) : (> 0) +>e : (arg: (> 0)) => (> 0) +>1 : 1 + +let e2 = e(0); +>e2 : (> 0) +>e(0) : (> 0) +>e : (arg: (> 0)) => (> 0) +>0 : 0 + diff --git a/tests/cases/compiler/rangeTypeAssignment.ts b/tests/cases/compiler/rangeTypeAssignment.ts new file mode 100644 index 0000000000000..f331bde12616b --- /dev/null +++ b/tests/cases/compiler/rangeTypeAssignment.ts @@ -0,0 +1,19 @@ +let a1: (> 0) = 1; +let a2: number = a1; +let a3: (> -1) = a1; +let a4: (>= 0) = a1; +let a5: (> 0) = a1; + +let b1: number = 0; +let b2: (< 0) = b1; +let b3: (> 0) = b1; + +enum C { + foo, + bar +} + +let c1: C = C.foo; +let c2: (>= 0) = C.foo; + +let c3: C = c2; diff --git a/tests/cases/compiler/rangeTypeBasics.ts b/tests/cases/compiler/rangeTypeBasics.ts new file mode 100644 index 0000000000000..b15f715e79fbc --- /dev/null +++ b/tests/cases/compiler/rangeTypeBasics.ts @@ -0,0 +1,42 @@ +let a1: (< 1); +let a2: (< -1); +let a3: (<= 1); +let a4: (<= -1); +let a5: (> 1); +let a6: (> -1); +let a7: (>= 1); +let a8: (>= -1); + +let a9: ((> 0)); +let a10: (((> 0))); + +declare function b1(): (> -3.14); +declare function b2(b2arg: (>= 42)): void; +declare function b3(b3arg: (< 7.4)): (> 10); + +interface C { + c1: (>= 4); + c2(c2arg: (> -6)): void; + c3(): (> 9.6); + c4(c4arg: (<= -2)): (> 100); +} + +class D { + public d1: (> 0); + d2(d2arg: (> 0)) { + return d2arg; + } +} + +type E1 = (> 4); +type E2 = (<= 10); +type E3 = (>= -42); + +type F1 = (<= "notanumber"); +type F2 = (>= "0"); +type F3 = (<4>); +type F4 = (< +); +type F5 = (> +); +type F6 = (> &); +type F7 = (>= ); +type F8 = (< ); diff --git a/tests/cases/compiler/rangeTypeDeclaration.ts b/tests/cases/compiler/rangeTypeDeclaration.ts new file mode 100644 index 0000000000000..781c46f4912eb --- /dev/null +++ b/tests/cases/compiler/rangeTypeDeclaration.ts @@ -0,0 +1,29 @@ +let a1: (> -1) = 0; +let a2: (< 1) = -10; +let a4: (> 0.1) = 0.5; +let a5: (<= 4.5) = Math.E; +let a6: (>= -4) = 1.5; +let a7: (>= 2) = 2; + +let b1: (> 1.2) = 1.2; +let b2: (< 1.2) = 1.2; +let b3: (>= 0) = -1; +let b4: (< 0) = 42; + +enum C { + foo, + bar +} + +let c1: (>= 0) = C.foo; +let c2: C = c1; + +const enum D { + foo, + bar +} + +let d1: (>= 0) = D.foo; +let d2: (<= 0) = D.foo; + +let d3: (<= 0) = D.bar; diff --git a/tests/cases/compiler/rangeTypeFunctionDeclarations.ts b/tests/cases/compiler/rangeTypeFunctionDeclarations.ts new file mode 100644 index 0000000000000..d9882cf2a6e72 --- /dev/null +++ b/tests/cases/compiler/rangeTypeFunctionDeclarations.ts @@ -0,0 +1,18 @@ +declare function a(arg: (> 0)): void; +let a1 = 1; +a(a1); +let a2: (> 1) = 2; +a(a2); + +let a3 = 0; +a(a3); +let a4: (>= 0) = 0; +a(a4); + + +declare function b(): (< 1); +let b1: (< 1) = b(); +let b2: (<= 1) = b(); +let b3: (< 2) = b(); + +let b4: (< 0) = b(); diff --git a/tests/cases/compiler/rangeTypeFunctions.ts b/tests/cases/compiler/rangeTypeFunctions.ts new file mode 100644 index 0000000000000..c709fc8d9eb1d --- /dev/null +++ b/tests/cases/compiler/rangeTypeFunctions.ts @@ -0,0 +1,44 @@ +function a(): (> 1) { + return 3; +} +let a0 = a(); +let a1: number = a(); +let a2: (> 1) = a(); +let a3: (>= 1) = a(); +let a4: (> 0) = a(); + +let a5: (> 2) = a(); +let a6: (< 4) = a(); + + +function b(): (>= 0) { + return 0; +} +let b0 = b(); +let b1: number = b(); +let b2: (>= 0) = b(); + +let b3: (> 0) = b(); +let b4: (>= 1) = b(); + + +function c(): (> 0) { + return 0; +} + + +function d(arg: (> 0)): void { + arg; + return; +} +let d1 = d(1); + +let d2 = d(0); + + +function e(arg: (> 0)): (> 0) { + return arg; +} +let e1 = e(1); + +let e2 = e(0); From 678117711578bdfb1623cc2442f4f57da3da3ac6 Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Tue, 18 Dec 2018 05:10:53 -0500 Subject: [PATCH 2/7] Add basic operator test for ranges --- .../reference/rangeTypeBasicOperators.js | 33 ++++++++ .../reference/rangeTypeBasicOperators.symbols | 70 ++++++++++++++++ .../reference/rangeTypeBasicOperators.types | 83 +++++++++++++++++++ .../cases/compiler/rangeTypeBasicOperators.ts | 16 ++++ 4 files changed, 202 insertions(+) create mode 100644 tests/baselines/reference/rangeTypeBasicOperators.js create mode 100644 tests/baselines/reference/rangeTypeBasicOperators.symbols create mode 100644 tests/baselines/reference/rangeTypeBasicOperators.types create mode 100644 tests/cases/compiler/rangeTypeBasicOperators.ts diff --git a/tests/baselines/reference/rangeTypeBasicOperators.js b/tests/baselines/reference/rangeTypeBasicOperators.js new file mode 100644 index 0000000000000..1298b37d91bbe --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasicOperators.js @@ -0,0 +1,33 @@ +//// [rangeTypeBasicOperators.ts] +declare var a: (> 42); +declare var b: (<= 3); + +let a1 = a + b; +let a2 = a - b; +let a3 = a * b; +let a4 = a / b; +let a5 = a % b; +let a6 = a & b; +let a7 = a | b; +let a8 = a ^ b; +let a9 = a << b; +let a10 = a >> b; +let a11 = a >>> b; +let a12 = ~a; +let a13 = -a; + + +//// [rangeTypeBasicOperators.js] +var a1 = a + b; +var a2 = a - b; +var a3 = a * b; +var a4 = a / b; +var a5 = a % b; +var a6 = a & b; +var a7 = a | b; +var a8 = a ^ b; +var a9 = a << b; +var a10 = a >> b; +var a11 = a >>> b; +var a12 = ~a; +var a13 = -a; diff --git a/tests/baselines/reference/rangeTypeBasicOperators.symbols b/tests/baselines/reference/rangeTypeBasicOperators.symbols new file mode 100644 index 0000000000000..54914ea5cd484 --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasicOperators.symbols @@ -0,0 +1,70 @@ +=== tests/cases/compiler/rangeTypeBasicOperators.ts === +declare var a: (> 42); +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) + +declare var b: (<= 3); +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a1 = a + b; +>a1 : Symbol(a1, Decl(rangeTypeBasicOperators.ts, 3, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a2 = a - b; +>a2 : Symbol(a2, Decl(rangeTypeBasicOperators.ts, 4, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a3 = a * b; +>a3 : Symbol(a3, Decl(rangeTypeBasicOperators.ts, 5, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a4 = a / b; +>a4 : Symbol(a4, Decl(rangeTypeBasicOperators.ts, 6, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a5 = a % b; +>a5 : Symbol(a5, Decl(rangeTypeBasicOperators.ts, 7, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a6 = a & b; +>a6 : Symbol(a6, Decl(rangeTypeBasicOperators.ts, 8, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a7 = a | b; +>a7 : Symbol(a7, Decl(rangeTypeBasicOperators.ts, 9, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a8 = a ^ b; +>a8 : Symbol(a8, Decl(rangeTypeBasicOperators.ts, 10, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a9 = a << b; +>a9 : Symbol(a9, Decl(rangeTypeBasicOperators.ts, 11, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a10 = a >> b; +>a10 : Symbol(a10, Decl(rangeTypeBasicOperators.ts, 12, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a11 = a >>> b; +>a11 : Symbol(a11, Decl(rangeTypeBasicOperators.ts, 13, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) +>b : Symbol(b, Decl(rangeTypeBasicOperators.ts, 1, 11)) + +let a12 = ~a; +>a12 : Symbol(a12, Decl(rangeTypeBasicOperators.ts, 14, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) + +let a13 = -a; +>a13 : Symbol(a13, Decl(rangeTypeBasicOperators.ts, 15, 3)) +>a : Symbol(a, Decl(rangeTypeBasicOperators.ts, 0, 11)) + diff --git a/tests/baselines/reference/rangeTypeBasicOperators.types b/tests/baselines/reference/rangeTypeBasicOperators.types new file mode 100644 index 0000000000000..479c3bc3256a9 --- /dev/null +++ b/tests/baselines/reference/rangeTypeBasicOperators.types @@ -0,0 +1,83 @@ +=== tests/cases/compiler/rangeTypeBasicOperators.ts === +declare var a: (> 42); +>a : (> 42) + +declare var b: (<= 3); +>b : (<= 3) + +let a1 = a + b; +>a1 : number +>a + b : number +>a : (> 42) +>b : (<= 3) + +let a2 = a - b; +>a2 : number +>a - b : number +>a : (> 42) +>b : (<= 3) + +let a3 = a * b; +>a3 : number +>a * b : number +>a : (> 42) +>b : (<= 3) + +let a4 = a / b; +>a4 : number +>a / b : number +>a : (> 42) +>b : (<= 3) + +let a5 = a % b; +>a5 : number +>a % b : number +>a : (> 42) +>b : (<= 3) + +let a6 = a & b; +>a6 : number +>a & b : number +>a : (> 42) +>b : (<= 3) + +let a7 = a | b; +>a7 : number +>a | b : number +>a : (> 42) +>b : (<= 3) + +let a8 = a ^ b; +>a8 : number +>a ^ b : number +>a : (> 42) +>b : (<= 3) + +let a9 = a << b; +>a9 : number +>a << b : number +>a : (> 42) +>b : (<= 3) + +let a10 = a >> b; +>a10 : number +>a >> b : number +>a : (> 42) +>b : (<= 3) + +let a11 = a >>> b; +>a11 : number +>a >>> b : number +>a : (> 42) +>b : (<= 3) + +let a12 = ~a; +>a12 : number +>~a : number +>a : (> 42) + +let a13 = -a; +>a13 : number +>-a : number +>a : (> 42) + diff --git a/tests/cases/compiler/rangeTypeBasicOperators.ts b/tests/cases/compiler/rangeTypeBasicOperators.ts new file mode 100644 index 0000000000000..637e4c69d5163 --- /dev/null +++ b/tests/cases/compiler/rangeTypeBasicOperators.ts @@ -0,0 +1,16 @@ +declare var a: (> 42); +declare var b: (<= 3); + +let a1 = a + b; +let a2 = a - b; +let a3 = a * b; +let a4 = a / b; +let a5 = a % b; +let a6 = a & b; +let a7 = a | b; +let a8 = a ^ b; +let a9 = a << b; +let a10 = a >> b; +let a11 = a >>> b; +let a12 = ~a; +let a13 = -a; From c25254c1a8d11d8c911e3b9f761f85c9e0a7a60f Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Wed, 19 Dec 2018 18:53:44 -0500 Subject: [PATCH 3/7] Add range falsiness checks Assuming strict null checks are turned on, a range can only be falsy if it contains 0. --- src/compiler/checker.ts | 10 ++++- src/compiler/types.ts | 2 +- .../baselines/reference/rangeTypeFalsiness.js | 37 +++++++++++++++++++ .../reference/rangeTypeFalsiness.symbols | 29 +++++++++++++++ .../reference/rangeTypeFalsiness.types | 35 ++++++++++++++++++ tests/cases/compiler/rangeTypeFalsiness.ts | 20 ++++++++++ 6 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/rangeTypeFalsiness.js create mode 100644 tests/baselines/reference/rangeTypeFalsiness.symbols create mode 100644 tests/baselines/reference/rangeTypeFalsiness.types create mode 100644 tests/cases/compiler/rangeTypeFalsiness.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bc07cfd3e9c0d..568a9559d8db3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17226,13 +17226,15 @@ namespace ts { // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns - // no flags for all other types (including non-falsy literal types). + // the Range flag for ranges if they can possibly contain 0, and no flags for all other types (including + // non-falsy literal types). function getFalsyFlags(type: Type): TypeFlags { return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((type).types) : type.flags & TypeFlags.StringLiteral ? (type).value === "" ? TypeFlags.StringLiteral : 0 : type.flags & TypeFlags.NumberLiteral ? (type).value === 0 ? TypeFlags.NumberLiteral : 0 : type.flags & TypeFlags.BigIntLiteral ? isZeroBigInt(type) ? TypeFlags.BigIntLiteral : 0 : type.flags & TypeFlags.BooleanLiteral ? (type === falseType || type === regularFalseType) ? TypeFlags.BooleanLiteral : 0 : + type.flags & TypeFlags.Range ? isValueInRange(type, 0) ? TypeFlags.Range : 0 : type.flags & TypeFlags.PossiblyFalsy; } @@ -18889,6 +18891,12 @@ namespace ts { if (flags & (TypeFlags.Number | TypeFlags.Enum)) { return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts; } + if (flags & TypeFlags.Range) { + const maybeZero = isValueInRange(type, 0); + return strictNullChecks ? + maybeZero ? TypeFacts.NumberStrictFacts : TypeFacts.NonZeroNumberStrictFacts : + maybeZero ? TypeFacts.NumberFacts : TypeFacts.NonZeroNumberFacts; + } if (flags & TypeFlags.NumberLiteral) { const isZero = (type).value === 0; return strictNullChecks ? diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ef622ee512e51..9aa64e4575fb1 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4305,7 +4305,7 @@ namespace ts { StringOrNumberLiteralOrUnique = StringLiteral | NumberLiteral | UniqueESSymbol, /* @internal */ DefinitelyFalsy = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral | Void | Undefined | Null, - PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean, + PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean | Range, /* @internal */ Intrinsic = Any | Unknown | String | Number | BigInt | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, /* @internal */ diff --git a/tests/baselines/reference/rangeTypeFalsiness.js b/tests/baselines/reference/rangeTypeFalsiness.js new file mode 100644 index 0000000000000..760cee9262c03 --- /dev/null +++ b/tests/baselines/reference/rangeTypeFalsiness.js @@ -0,0 +1,37 @@ +//// [rangeTypeFalsiness.ts] +function a(arg: (> 0)) { + if(!arg) { + return false; + } + else { + return true; + } +} + +function b(arg: (>= 0)) { + if (!arg) { + return false; + } + else { + return true; + } +} + + +//// [rangeTypeFalsiness.js] +function a(arg) { + if (!arg) { + return false; + } + else { + return true; + } +} +function b(arg) { + if (!arg) { + return false; + } + else { + return true; + } +} diff --git a/tests/baselines/reference/rangeTypeFalsiness.symbols b/tests/baselines/reference/rangeTypeFalsiness.symbols new file mode 100644 index 0000000000000..c1c65eb11a13c --- /dev/null +++ b/tests/baselines/reference/rangeTypeFalsiness.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/rangeTypeFalsiness.ts === +function a(arg: (> 0)) { +>a : Symbol(a, Decl(rangeTypeFalsiness.ts, 0, 0)) +>arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 0, 11)) + + if(!arg) { +>arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 0, 11)) + + return false; + } + else { + return true; + } +} + +function b(arg: (>= 0)) { +>b : Symbol(b, Decl(rangeTypeFalsiness.ts, 7, 1)) +>arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 9, 11)) + + if (!arg) { +>arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 9, 11)) + + return false; + } + else { + return true; + } +} + diff --git a/tests/baselines/reference/rangeTypeFalsiness.types b/tests/baselines/reference/rangeTypeFalsiness.types new file mode 100644 index 0000000000000..a1a915bb135f9 --- /dev/null +++ b/tests/baselines/reference/rangeTypeFalsiness.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/rangeTypeFalsiness.ts === +function a(arg: (> 0)) { +>a : (arg: (> 0)) => boolean +>arg : (> 0) + + if(!arg) { +>!arg : false +>arg : (> 0) + + return false; +>false : false + } + else { + return true; +>true : true + } +} + +function b(arg: (>= 0)) { +>b : (arg: (>= 0)) => boolean +>arg : (>= 0) + + if (!arg) { +>!arg : boolean +>arg : (>= 0) + + return false; +>false : false + } + else { + return true; +>true : true + } +} + diff --git a/tests/cases/compiler/rangeTypeFalsiness.ts b/tests/cases/compiler/rangeTypeFalsiness.ts new file mode 100644 index 0000000000000..7efe50764f5cd --- /dev/null +++ b/tests/cases/compiler/rangeTypeFalsiness.ts @@ -0,0 +1,20 @@ +// @allowUnreachableCode: false +// @strictNullChecks: true + +function a(arg: (> 0)) { + if(!arg) { + return false; + } + else { + return true; + } +} + +function b(arg: (>= 0)) { + if (!arg) { + return false; + } + else { + return true; + } +} From 97eb1a3af36e78addc6d200b24504f32057d7817 Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Fri, 21 Dec 2018 06:54:04 -0500 Subject: [PATCH 4/7] Add type node output for full ranges Just in case they're produced from something else, they should be output into something that makes sense. For obvious reasons, a range with no min and no max is just the number type, while one with both a min and a max is output as an intersection of two half ranges. --- src/compiler/checker.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 568a9559d8db3..9699cbdb54f65 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4239,18 +4239,28 @@ namespace ts { return typeToTypeNodeHelper((type).typeVariable, context); } if (type.flags & TypeFlags.Range) { - let operator; - let basis; if ((type).min && !(type).max) { - operator = (type).minOpen ? createToken(SyntaxKind.GreaterThanToken) : createToken(SyntaxKind.GreaterThanEqualsToken); - basis = createLiteral((type).min!.value); + const operator = (type).minOpen ? createToken(SyntaxKind.GreaterThanToken) : createToken(SyntaxKind.GreaterThanEqualsToken); + const basis = createLiteral((type).min!.value); return createHalfRangeTypeNode(operator, basis); } else if (!(type).min && (type).max) { - operator = (type).maxOpen ? createToken(SyntaxKind.LessThanToken) : createToken(SyntaxKind.LessThanEqualsToken); - basis = createLiteral((type).max!.value); + const operator = (type).maxOpen ? createToken(SyntaxKind.LessThanToken) : createToken(SyntaxKind.LessThanEqualsToken); + const basis = createLiteral((type).max!.value); return createHalfRangeTypeNode(operator, basis); - } // TODO: "full" range handling (e.g. union) + } + else if ((type).min && (type).max) { + const min = createType(TypeFlags.Range); + min.min = (type).min; + min.minOpen = (type).minOpen; + const max = createType(TypeFlags.Range); + max.max = (type).max; + max.maxOpen = (type).maxOpen; + return createIntersectionTypeNode([typeToTypeNodeHelper(min, context), typeToTypeNodeHelper(max, context)]); + } + else if (!(type).min && !(type).max) { + return createKeywordTypeNode(SyntaxKind.NumberKeyword); + } } return Debug.fail("Should be unreachable."); From a8c5788e175ba844246cf2691a11a9e1d136017f Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Fri, 21 Dec 2018 02:29:20 -0500 Subject: [PATCH 5/7] Mark ranges as subtypes of containing ranges For example, (>= 1) is a subtype of (> 0). This doesn't really matter in most cases though, because unions don't often reduce subtypes, and that is the only time where the subtype relation is actually used. --- src/compiler/checker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9699cbdb54f65..7bb8bf6a35c92 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14761,7 +14761,7 @@ namespace ts { function isRangeTypeRelatedTo(source: Type, target: RangeType, relation: Map) { if (relation === comparableRelation) return true; - if (relation === assignableRelation) { + if (relation === assignableRelation || relation === subtypeRelation) { if (source.flags & TypeFlags.Range) { return isRangeContainedBy(source, target); } @@ -14772,7 +14772,6 @@ namespace ts { return false; } - // A range "contained" by another is essentially a subtype of it function isRangeContainedBy(source: RangeType, target: RangeType) { if (!source.min && target.min) return false; if (!source.max && target.max) return false; From 51aa323a27f112e49143ffb9820dbd54628c56a6 Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Fri, 21 Dec 2018 04:47:33 -0500 Subject: [PATCH 6/7] Make range type falsiness test more explicit --- .../baselines/reference/rangeTypeFalsiness.js | 32 ++++--------------- .../reference/rangeTypeFalsiness.symbols | 26 ++++----------- .../reference/rangeTypeFalsiness.types | 29 +++++------------ tests/cases/compiler/rangeTypeFalsiness.ts | 19 +++-------- 4 files changed, 25 insertions(+), 81 deletions(-) diff --git a/tests/baselines/reference/rangeTypeFalsiness.js b/tests/baselines/reference/rangeTypeFalsiness.js index 760cee9262c03..021dd64a9922d 100644 --- a/tests/baselines/reference/rangeTypeFalsiness.js +++ b/tests/baselines/reference/rangeTypeFalsiness.js @@ -1,37 +1,17 @@ //// [rangeTypeFalsiness.ts] -function a(arg: (> 0)) { - if(!arg) { - return false; - } - else { - return true; - } +function a(arg: (> 0)): true { + return !!arg; } -function b(arg: (>= 0)) { - if (!arg) { - return false; - } - else { - return true; - } +function b(arg: (>= 0)): boolean { + return !!arg; } //// [rangeTypeFalsiness.js] function a(arg) { - if (!arg) { - return false; - } - else { - return true; - } + return !!arg; } function b(arg) { - if (!arg) { - return false; - } - else { - return true; - } + return !!arg; } diff --git a/tests/baselines/reference/rangeTypeFalsiness.symbols b/tests/baselines/reference/rangeTypeFalsiness.symbols index c1c65eb11a13c..aa5b416fa9fa6 100644 --- a/tests/baselines/reference/rangeTypeFalsiness.symbols +++ b/tests/baselines/reference/rangeTypeFalsiness.symbols @@ -1,29 +1,17 @@ === tests/cases/compiler/rangeTypeFalsiness.ts === -function a(arg: (> 0)) { +function a(arg: (> 0)): true { >a : Symbol(a, Decl(rangeTypeFalsiness.ts, 0, 0)) >arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 0, 11)) - if(!arg) { + return !!arg; >arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 0, 11)) - - return false; - } - else { - return true; - } } -function b(arg: (>= 0)) { ->b : Symbol(b, Decl(rangeTypeFalsiness.ts, 7, 1)) ->arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 9, 11)) - - if (!arg) { ->arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 9, 11)) +function b(arg: (>= 0)): boolean { +>b : Symbol(b, Decl(rangeTypeFalsiness.ts, 2, 1)) +>arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 4, 11)) - return false; - } - else { - return true; - } + return !!arg; +>arg : Symbol(arg, Decl(rangeTypeFalsiness.ts, 4, 11)) } diff --git a/tests/baselines/reference/rangeTypeFalsiness.types b/tests/baselines/reference/rangeTypeFalsiness.types index a1a915bb135f9..b60c839ff16e6 100644 --- a/tests/baselines/reference/rangeTypeFalsiness.types +++ b/tests/baselines/reference/rangeTypeFalsiness.types @@ -1,35 +1,22 @@ === tests/cases/compiler/rangeTypeFalsiness.ts === -function a(arg: (> 0)) { ->a : (arg: (> 0)) => boolean +function a(arg: (> 0)): true { +>a : (arg: (> 0)) => true >arg : (> 0) +>true : true - if(!arg) { + return !!arg; +>!!arg : true >!arg : false >arg : (> 0) - - return false; ->false : false - } - else { - return true; ->true : true - } } -function b(arg: (>= 0)) { +function b(arg: (>= 0)): boolean { >b : (arg: (>= 0)) => boolean >arg : (>= 0) - if (!arg) { + return !!arg; +>!!arg : boolean >!arg : boolean >arg : (>= 0) - - return false; ->false : false - } - else { - return true; ->true : true - } } diff --git a/tests/cases/compiler/rangeTypeFalsiness.ts b/tests/cases/compiler/rangeTypeFalsiness.ts index 7efe50764f5cd..ee51877ada4a6 100644 --- a/tests/cases/compiler/rangeTypeFalsiness.ts +++ b/tests/cases/compiler/rangeTypeFalsiness.ts @@ -1,20 +1,9 @@ -// @allowUnreachableCode: false // @strictNullChecks: true -function a(arg: (> 0)) { - if(!arg) { - return false; - } - else { - return true; - } +function a(arg: (> 0)): true { + return !!arg; } -function b(arg: (>= 0)) { - if (!arg) { - return false; - } - else { - return true; - } +function b(arg: (>= 0)): boolean { + return !!arg; } From b231694f0191dd893c3d82c5c83e73b7988f04b6 Mon Sep 17 00:00:00 2001 From: ECrownofFire Date: Sat, 22 Dec 2018 16:41:35 -0500 Subject: [PATCH 7/7] Accept baseline change Forgot to when doing the falsiness thing, oops. --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- tests/baselines/reference/rangeTypeBasics.types | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9f47c99fd3d53..82d0c806a74df 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2361,7 +2361,7 @@ declare namespace ts { Literal = 2944, Unit = 109440, StringOrNumberLiteral = 384, - PossiblyFalsy = 117724, + PossiblyFalsy = 4312028, StringLike = 132, NumberLike = 4194600, BigIntLike = 2112, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index dd6015c81ae18..7cf5b7de3880f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2361,7 +2361,7 @@ declare namespace ts { Literal = 2944, Unit = 109440, StringOrNumberLiteral = 384, - PossiblyFalsy = 117724, + PossiblyFalsy = 4312028, StringLike = 132, NumberLike = 4194600, BigIntLike = 2112, diff --git a/tests/baselines/reference/rangeTypeBasics.types b/tests/baselines/reference/rangeTypeBasics.types index 41137172d20d0..23725fa63b0a0 100644 --- a/tests/baselines/reference/rangeTypeBasics.types +++ b/tests/baselines/reference/rangeTypeBasics.types @@ -115,7 +115,7 @@ type F3 = (<4>); > : any type F4 = (< +); ->F4 : () => any +>F4 : F4 >+ : number > : any @@ -141,5 +141,5 @@ type F7 = (>= ); > : any type F8 = (< ); ->F8 : () => any +>F8 : F8