diff --git a/packages/typescript/src/api/async/api.ts b/packages/typescript/src/api/async/api.ts index a9dd53fe3a3f1..89565a0e109e7 100644 --- a/packages/typescript/src/api/async/api.ts +++ b/packages/typescript/src/api/async/api.ts @@ -2610,6 +2610,11 @@ export class Checker { return type.getNonNullableType(); } + /** Get the negation of a type. Always returns a type. */ + async getNegatedType(type: Type): Promise { + return type.getNegatedType(); + } + /** * Get the type for a type node. Always returns a type; for type nodes whose * type cannot be determined the checker yields the error type (use @@ -3447,6 +3452,7 @@ class TypeObject implements Type { private constraint: number | false; private default: number | false; private nonNullableType: number | false; + private negatedType: number | false; private apparentType: number | false; private reducedType: number | false; private properties: readonly Symbol[] | false; @@ -3526,6 +3532,7 @@ class TypeObject implements Type { this.constraint = false; this.default = false; this.nonNullableType = false; + this.negatedType = false; this.apparentType = false; this.reducedType = false; this.properties = false; @@ -3581,6 +3588,12 @@ class TypeObject implements Type { return result; } + async getNegatedType(): Promise { + const result = await this.objectRegistry.fetchType(this, "getNegatedType", this.negatedType); + this.negatedType = result.id; + return result; + } + async getStringIndexType(): Promise { if (this.stringIndexType === false) { this.stringIndexType = await this.getStringIndexTypeWorker(); diff --git a/packages/typescript/src/api/async/types.ts b/packages/typescript/src/api/async/types.ts index e1c7e0c8753e9..e88e602999cf0 100644 --- a/packages/typescript/src/api/async/types.ts +++ b/packages/typescript/src/api/async/types.ts @@ -67,6 +67,9 @@ export interface Type { /** Get this type with `null` and `undefined` removed. */ getNonNullableType(): Promise; + /** Get the negation of this type. */ + getNegatedType(): Promise; + /** Get this type's string index value type, if present. */ getStringIndexType(): Promise; diff --git a/packages/typescript/src/api/node/encoder.generated.ts b/packages/typescript/src/api/node/encoder.generated.ts index 7b9c4de1425f6..bfb5f14c1b201 100644 --- a/packages/typescript/src/api/node/encoder.generated.ts +++ b/packages/typescript/src/api/node/encoder.generated.ts @@ -77,7 +77,7 @@ export function getNodeCommonData(node: Node): number { case SyntaxKind.ObjectLiteralExpression: return ((node as ObjectLiteralExpression).multiLine ? 1 : 0) << 24; case SyntaxKind.TypeOperator: - return ((node as TypeOperatorNode).operator === SyntaxKind.ReadonlyKeyword ? 1 : (node as TypeOperatorNode).operator === SyntaxKind.UniqueKeyword ? 2 : 0) << 24; + return ((node as TypeOperatorNode).operator === SyntaxKind.ReadonlyKeyword ? 1 : (node as TypeOperatorNode).operator === SyntaxKind.UniqueKeyword ? 2 : (node as TypeOperatorNode).operator === SyntaxKind.NotKeyword ? 3 : 0) << 24; case SyntaxKind.ImportAttributes: return ((node as ImportAttributes).multiLine ? 1 : 0) << 24 | ((node as ImportAttributes).token === SyntaxKind.AssertKeyword ? 1 : 0) << 25; case SyntaxKind.JsxText: diff --git a/packages/typescript/src/api/node/node.generated.ts b/packages/typescript/src/api/node/node.generated.ts index 0f69dbc63abd3..5f60f8719a0f6 100644 --- a/packages/typescript/src/api/node/node.generated.ts +++ b/packages/typescript/src/api/node/node.generated.ts @@ -580,6 +580,7 @@ export class RemoteNode extends RemoteNodeBase implements Node { const idx = (this.data >> 24) & 0x3; if (idx === 1) return SyntaxKind.ReadonlyKeyword; if (idx === 2) return SyntaxKind.UniqueKeyword; + if (idx === 3) return SyntaxKind.NotKeyword; return SyntaxKind.KeyOfKeyword; } } diff --git a/packages/typescript/src/api/proto.generated.ts b/packages/typescript/src/api/proto.generated.ts index 93774869c4407..2ff4d1710f2ff 100644 --- a/packages/typescript/src/api/proto.generated.ts +++ b/packages/typescript/src/api/proto.generated.ts @@ -151,6 +151,7 @@ export interface APIMethodInfo { getApparentPropertiesOfType: APIMethod; getApparentType: APIMethod; getReducedType: APIMethod; + getNegatedType: APIMethod; getPropertyOfType: APIMethod; getTypeOfPropertyOfType: APIMethod; getIndexInfoOfType: APIMethod; @@ -1222,6 +1223,7 @@ export interface BatchRequest { | "getModeForResolutionAtIndex" | "getModeForUsageLocation" | "getNameTypeOfMappedType" + | "getNegatedType" | "getNeverType" | "getNonMissingTypeOfSymbol" | "getNonNullableType" @@ -1404,6 +1406,7 @@ export interface BatchResponse { | "getModeForResolutionAtIndex" | "getModeForUsageLocation" | "getNameTypeOfMappedType" + | "getNegatedType" | "getNeverType" | "getNonMissingTypeOfSymbol" | "getNonNullableType" diff --git a/packages/typescript/src/api/sync/api.ts b/packages/typescript/src/api/sync/api.ts index 8950863c33460..cf820a69cbc46 100644 --- a/packages/typescript/src/api/sync/api.ts +++ b/packages/typescript/src/api/sync/api.ts @@ -4941,6 +4941,24 @@ export class Checker { ); } + /** Get the negation of a type. Always returns a type. */ + get getNegatedType(): { + (type: Type): Type; + gen(type: Type): Generator; + } { + const owner = this; + return cacheGeneratorMethod( + owner, + "getNegatedType", + function (type: Type): Type { + return type.getNegatedType(); + }, + function* (type: Type): Generator { + return yield* type.getNegatedType.gen(); + }, + ); + } + /** * Get the type for a type node. Always returns a type; for type nodes whose * type cannot be determined the checker yields the error type (use @@ -7012,6 +7030,7 @@ class TypeObject implements Type { private constraint: number | false; private default: number | false; private nonNullableType: number | false; + private negatedType: number | false; private apparentType: number | false; private reducedType: number | false; private properties: readonly Symbol[] | false; @@ -7091,6 +7110,7 @@ class TypeObject implements Type { this.constraint = false; this.default = false; this.nonNullableType = false; + this.negatedType = false; this.apparentType = false; this.reducedType = false; this.properties = false; @@ -7251,6 +7271,27 @@ class TypeObject implements Type { ); } + get getNegatedType(): { + (): Type; + gen(): Generator; + } { + const owner = this; + return cacheGeneratorMethod( + owner, + "getNegatedType", + function (): Type { + const result = owner.objectRegistry.fetchType(owner, "getNegatedType", owner.negatedType); + owner.negatedType = result.id; + return result; + }, + function* (): Generator { + const result = yield* owner.objectRegistry.fetchType.gen(owner, "getNegatedType", owner.negatedType); + owner.negatedType = result.id; + return result; + }, + ); + } + get getStringIndexType(): { (): Type | undefined; gen(): Generator; diff --git a/packages/typescript/src/api/sync/types.ts b/packages/typescript/src/api/sync/types.ts index 2f466b6b684ae..8222fe53280ba 100644 --- a/packages/typescript/src/api/sync/types.ts +++ b/packages/typescript/src/api/sync/types.ts @@ -107,6 +107,12 @@ export interface Type { gen(): Generator; }; + /** Get the negation of this type. */ + getNegatedType: { + (): Type; + gen(): Generator; + }; + /** Get this type's string index value type, if present. */ getStringIndexType: { (): Type | undefined; diff --git a/packages/typescript/src/ast/ast.generated.ts b/packages/typescript/src/ast/ast.generated.ts index 723093189f812..48c94f6226fd6 100644 --- a/packages/typescript/src/ast/ast.generated.ts +++ b/packages/typescript/src/ast/ast.generated.ts @@ -140,6 +140,7 @@ export type KeywordSyntaxKind = | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword + | SyntaxKind.NotKeyword | SyntaxKind.OutKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword @@ -312,6 +313,7 @@ export type TokenSyntaxKind = | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword + | SyntaxKind.NotKeyword | SyntaxKind.OutKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword @@ -964,7 +966,7 @@ export interface ConditionalTypeNode extends TypeNodeBase { } export interface TypeOperatorNode extends TypeNodeBase { readonly kind: SyntaxKind.TypeOperator; - readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.UniqueKeyword; + readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.NotKeyword; readonly type: TypeNode; } export interface InferTypeNode extends TypeNodeBase { diff --git a/packages/typescript/src/ast/factory.generated.ts b/packages/typescript/src/ast/factory.generated.ts index ac1ac5f377266..8a43622a42c63 100644 --- a/packages/typescript/src/ast/factory.generated.ts +++ b/packages/typescript/src/ast/factory.generated.ts @@ -4711,7 +4711,7 @@ export function createConditionalTypeNode(checkType: TypeNode, extendsType: Type }) as unknown as ConditionalTypeNode; } -export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode { +export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.NotKeyword, type: TypeNode): TypeOperatorNode { return new NodeObject(SyntaxKind.TypeOperator, { operator, type, diff --git a/packages/typescript/src/enums/objectFlags.enum.ts b/packages/typescript/src/enums/objectFlags.enum.ts index 15e497dc6ffb0..0509ff7723219 100644 --- a/packages/typescript/src/enums/objectFlags.enum.ts +++ b/packages/typescript/src/enums/objectFlags.enum.ts @@ -49,4 +49,5 @@ export enum ObjectFlags { IsNeverIntersectionComputed = 1 << 25, IsNeverIntersection = 1 << 26, IsConstrainedTypeVariable = 1 << 27, + FreshNegated = 1 << 25, } diff --git a/packages/typescript/src/enums/objectFlags.ts b/packages/typescript/src/enums/objectFlags.ts index af3bad5af2d58..c8e2d9c895f37 100644 --- a/packages/typescript/src/enums/objectFlags.ts +++ b/packages/typescript/src/enums/objectFlags.ts @@ -49,4 +49,5 @@ export var ObjectFlags: any; ObjectFlags[ObjectFlags["IsNeverIntersectionComputed"] = 33554432] = "IsNeverIntersectionComputed"; ObjectFlags[ObjectFlags["IsNeverIntersection"] = 67108864] = "IsNeverIntersection"; ObjectFlags[ObjectFlags["IsConstrainedTypeVariable"] = 134217728] = "IsConstrainedTypeVariable"; + ObjectFlags[ObjectFlags["FreshNegated"] = 33554432] = "FreshNegated"; })(ObjectFlags || (ObjectFlags = {})); diff --git a/packages/typescript/src/enums/syntaxKind.enum.ts b/packages/typescript/src/enums/syntaxKind.enum.ts index 1973373f684f3..0dcd83312abe6 100644 --- a/packages/typescript/src/enums/syntaxKind.enum.ts +++ b/packages/typescript/src/enums/syntaxKind.enum.ts @@ -148,212 +148,213 @@ export enum SyntaxKind { ModuleKeyword = 144, NamespaceKeyword = 145, NeverKeyword = 146, - OutKeyword = 147, - ReadonlyKeyword = 148, - RequireKeyword = 149, - NumberKeyword = 150, - ObjectKeyword = 151, - SatisfiesKeyword = 152, - SetKeyword = 153, - StringKeyword = 154, - SymbolKeyword = 155, - TypeKeyword = 156, - UndefinedKeyword = 157, - UniqueKeyword = 158, - UnknownKeyword = 159, - UsingKeyword = 160, - FromKeyword = 161, - GlobalKeyword = 162, - BigIntKeyword = 163, - OverrideKeyword = 164, - OfKeyword = 165, - DeferKeyword = 166, - SourceKeyword = 167, - QualifiedName = 168, - ComputedPropertyName = 169, - TypeParameter = 170, - Parameter = 171, - Decorator = 172, - PropertySignature = 173, - PropertyDeclaration = 174, - MethodSignature = 175, - MethodDeclaration = 176, - ClassStaticBlockDeclaration = 177, - Constructor = 178, - GetAccessor = 179, - SetAccessor = 180, - CallSignature = 181, - ConstructSignature = 182, - IndexSignature = 183, - TypePredicate = 184, - TypeReference = 185, - FunctionType = 186, - ConstructorType = 187, - TypeQuery = 188, - TypeLiteral = 189, - ArrayType = 190, - TupleType = 191, - OptionalType = 192, - RestType = 193, - UnionType = 194, - IntersectionType = 195, - ConditionalType = 196, - InferType = 197, - ParenthesizedType = 198, - ThisType = 199, - TypeOperator = 200, - IndexedAccessType = 201, - MappedType = 202, - LiteralType = 203, - NamedTupleMember = 204, - TemplateLiteralType = 205, - TemplateLiteralTypeSpan = 206, - ImportType = 207, - ObjectBindingPattern = 208, - ArrayBindingPattern = 209, - BindingElement = 210, - ArrayLiteralExpression = 211, - ObjectLiteralExpression = 212, - PropertyAccessExpression = 213, - ElementAccessExpression = 214, - CallExpression = 215, - NewExpression = 216, - TaggedTemplateExpression = 217, - TypeAssertionExpression = 218, - ParenthesizedExpression = 219, - FunctionExpression = 220, - ArrowFunction = 221, - DeleteExpression = 222, - TypeOfExpression = 223, - VoidExpression = 224, - AwaitExpression = 225, - PrefixUnaryExpression = 226, - PostfixUnaryExpression = 227, - BinaryExpression = 228, - ConditionalExpression = 229, - TemplateExpression = 230, - YieldExpression = 231, - SpreadElement = 232, - ClassExpression = 233, - OmittedExpression = 234, - ExpressionWithTypeArguments = 235, - AsExpression = 236, - NonNullExpression = 237, - MetaProperty = 238, - SyntheticExpression = 239, - SatisfiesExpression = 240, - TemplateSpan = 241, - SemicolonClassElement = 242, - Block = 243, - EmptyStatement = 244, - VariableStatement = 245, - ExpressionStatement = 246, - IfStatement = 247, - DoStatement = 248, - WhileStatement = 249, - ForStatement = 250, - ForInStatement = 251, - ForOfStatement = 252, - ContinueStatement = 253, - BreakStatement = 254, - ReturnStatement = 255, - WithStatement = 256, - SwitchStatement = 257, - LabeledStatement = 258, - ThrowStatement = 259, - TryStatement = 260, - DebuggerStatement = 261, - VariableDeclaration = 262, - VariableDeclarationList = 263, - FunctionDeclaration = 264, - ClassDeclaration = 265, - InterfaceDeclaration = 266, - TypeAliasDeclaration = 267, - EnumDeclaration = 268, - ModuleDeclaration = 269, - ModuleBlock = 270, - CaseBlock = 271, - NamespaceExportDeclaration = 272, - ImportEqualsDeclaration = 273, - ImportDeclaration = 274, - ImportClause = 275, - NamespaceImport = 276, - NamedImports = 277, - ImportSpecifier = 278, - ExportAssignment = 279, - ExportDeclaration = 280, - NamedExports = 281, - NamespaceExport = 282, - ExportSpecifier = 283, - MissingDeclaration = 284, - ExternalModuleReference = 285, - JsxElement = 286, - JsxSelfClosingElement = 287, - JsxOpeningElement = 288, - JsxClosingElement = 289, - JsxFragment = 290, - JsxOpeningFragment = 291, - JsxClosingFragment = 292, - JsxAttribute = 293, - JsxAttributes = 294, - JsxSpreadAttribute = 295, - JsxExpression = 296, - JsxNamespacedName = 297, - CaseClause = 298, - DefaultClause = 299, - HeritageClause = 300, - CatchClause = 301, - ImportAttributes = 302, - ImportAttribute = 303, - PropertyAssignment = 304, - ShorthandPropertyAssignment = 305, - SpreadAssignment = 306, - EnumMember = 307, - SourceFile = 308, - JSDocTypeExpression = 309, - JSDocNameReference = 310, - JSDocAllType = 311, - JSDocNullableType = 312, - JSDocNonNullableType = 313, - JSDocOptionalType = 314, - JSDocVariadicType = 315, - JSDoc = 316, - JSDocText = 317, - JSDocTypeLiteral = 318, - JSDocSignature = 319, - JSDocLink = 320, - JSDocLinkCode = 321, - JSDocLinkPlain = 322, - JSDocUnknownTag = 323, - JSDocAugmentsTag = 324, - JSDocImplementsTag = 325, - JSDocDeprecatedTag = 326, - JSDocPublicTag = 327, - JSDocPrivateTag = 328, - JSDocProtectedTag = 329, - JSDocReadonlyTag = 330, - JSDocOverrideTag = 331, - JSDocCallbackTag = 332, - JSDocOverloadTag = 333, - JSDocParameterTag = 334, - JSDocReturnTag = 335, - JSDocThisTag = 336, - JSDocTypeTag = 337, - JSDocTemplateTag = 338, - JSDocTypedefTag = 339, - JSDocSeeTag = 340, - JSDocPropertyTag = 341, - JSDocThrowsTag = 342, - JSDocSatisfiesTag = 343, - JSDocImportTag = 344, - SyntaxList = 345, - JSTypeAliasDeclaration = 346, - JSImportDeclaration = 347, - NotEmittedStatement = 348, - PartiallyEmittedExpression = 349, - SyntheticReferenceExpression = 350, - NotEmittedTypeElement = 351, - Count = 352, + NotKeyword = 147, + OutKeyword = 148, + ReadonlyKeyword = 149, + RequireKeyword = 150, + NumberKeyword = 151, + ObjectKeyword = 152, + SatisfiesKeyword = 153, + SetKeyword = 154, + StringKeyword = 155, + SymbolKeyword = 156, + TypeKeyword = 157, + UndefinedKeyword = 158, + UniqueKeyword = 159, + UnknownKeyword = 160, + UsingKeyword = 161, + FromKeyword = 162, + GlobalKeyword = 163, + BigIntKeyword = 164, + OverrideKeyword = 165, + OfKeyword = 166, + DeferKeyword = 167, + SourceKeyword = 168, + QualifiedName = 169, + ComputedPropertyName = 170, + TypeParameter = 171, + Parameter = 172, + Decorator = 173, + PropertySignature = 174, + PropertyDeclaration = 175, + MethodSignature = 176, + MethodDeclaration = 177, + ClassStaticBlockDeclaration = 178, + Constructor = 179, + GetAccessor = 180, + SetAccessor = 181, + CallSignature = 182, + ConstructSignature = 183, + IndexSignature = 184, + TypePredicate = 185, + TypeReference = 186, + FunctionType = 187, + ConstructorType = 188, + TypeQuery = 189, + TypeLiteral = 190, + ArrayType = 191, + TupleType = 192, + OptionalType = 193, + RestType = 194, + UnionType = 195, + IntersectionType = 196, + ConditionalType = 197, + InferType = 198, + ParenthesizedType = 199, + ThisType = 200, + TypeOperator = 201, + IndexedAccessType = 202, + MappedType = 203, + LiteralType = 204, + NamedTupleMember = 205, + TemplateLiteralType = 206, + TemplateLiteralTypeSpan = 207, + ImportType = 208, + ObjectBindingPattern = 209, + ArrayBindingPattern = 210, + BindingElement = 211, + ArrayLiteralExpression = 212, + ObjectLiteralExpression = 213, + PropertyAccessExpression = 214, + ElementAccessExpression = 215, + CallExpression = 216, + NewExpression = 217, + TaggedTemplateExpression = 218, + TypeAssertionExpression = 219, + ParenthesizedExpression = 220, + FunctionExpression = 221, + ArrowFunction = 222, + DeleteExpression = 223, + TypeOfExpression = 224, + VoidExpression = 225, + AwaitExpression = 226, + PrefixUnaryExpression = 227, + PostfixUnaryExpression = 228, + BinaryExpression = 229, + ConditionalExpression = 230, + TemplateExpression = 231, + YieldExpression = 232, + SpreadElement = 233, + ClassExpression = 234, + OmittedExpression = 235, + ExpressionWithTypeArguments = 236, + AsExpression = 237, + NonNullExpression = 238, + MetaProperty = 239, + SyntheticExpression = 240, + SatisfiesExpression = 241, + TemplateSpan = 242, + SemicolonClassElement = 243, + Block = 244, + EmptyStatement = 245, + VariableStatement = 246, + ExpressionStatement = 247, + IfStatement = 248, + DoStatement = 249, + WhileStatement = 250, + ForStatement = 251, + ForInStatement = 252, + ForOfStatement = 253, + ContinueStatement = 254, + BreakStatement = 255, + ReturnStatement = 256, + WithStatement = 257, + SwitchStatement = 258, + LabeledStatement = 259, + ThrowStatement = 260, + TryStatement = 261, + DebuggerStatement = 262, + VariableDeclaration = 263, + VariableDeclarationList = 264, + FunctionDeclaration = 265, + ClassDeclaration = 266, + InterfaceDeclaration = 267, + TypeAliasDeclaration = 268, + EnumDeclaration = 269, + ModuleDeclaration = 270, + ModuleBlock = 271, + CaseBlock = 272, + NamespaceExportDeclaration = 273, + ImportEqualsDeclaration = 274, + ImportDeclaration = 275, + ImportClause = 276, + NamespaceImport = 277, + NamedImports = 278, + ImportSpecifier = 279, + ExportAssignment = 280, + ExportDeclaration = 281, + NamedExports = 282, + NamespaceExport = 283, + ExportSpecifier = 284, + MissingDeclaration = 285, + ExternalModuleReference = 286, + JsxElement = 287, + JsxSelfClosingElement = 288, + JsxOpeningElement = 289, + JsxClosingElement = 290, + JsxFragment = 291, + JsxOpeningFragment = 292, + JsxClosingFragment = 293, + JsxAttribute = 294, + JsxAttributes = 295, + JsxSpreadAttribute = 296, + JsxExpression = 297, + JsxNamespacedName = 298, + CaseClause = 299, + DefaultClause = 300, + HeritageClause = 301, + CatchClause = 302, + ImportAttributes = 303, + ImportAttribute = 304, + PropertyAssignment = 305, + ShorthandPropertyAssignment = 306, + SpreadAssignment = 307, + EnumMember = 308, + SourceFile = 309, + JSDocTypeExpression = 310, + JSDocNameReference = 311, + JSDocAllType = 312, + JSDocNullableType = 313, + JSDocNonNullableType = 314, + JSDocOptionalType = 315, + JSDocVariadicType = 316, + JSDoc = 317, + JSDocText = 318, + JSDocTypeLiteral = 319, + JSDocSignature = 320, + JSDocLink = 321, + JSDocLinkCode = 322, + JSDocLinkPlain = 323, + JSDocUnknownTag = 324, + JSDocAugmentsTag = 325, + JSDocImplementsTag = 326, + JSDocDeprecatedTag = 327, + JSDocPublicTag = 328, + JSDocPrivateTag = 329, + JSDocProtectedTag = 330, + JSDocReadonlyTag = 331, + JSDocOverrideTag = 332, + JSDocCallbackTag = 333, + JSDocOverloadTag = 334, + JSDocParameterTag = 335, + JSDocReturnTag = 336, + JSDocThisTag = 337, + JSDocTypeTag = 338, + JSDocTemplateTag = 339, + JSDocTypedefTag = 340, + JSDocSeeTag = 341, + JSDocPropertyTag = 342, + JSDocThrowsTag = 343, + JSDocSatisfiesTag = 344, + JSDocImportTag = 345, + SyntaxList = 346, + JSTypeAliasDeclaration = 347, + JSImportDeclaration = 348, + NotEmittedStatement = 349, + PartiallyEmittedExpression = 350, + SyntheticReferenceExpression = 351, + NotEmittedTypeElement = 352, + Count = 353, FirstAssignment = EqualsToken, LastAssignment = CaretEqualsToken, FirstCompoundAssignment = PlusEqualsToken, diff --git a/packages/typescript/src/enums/syntaxKind.ts b/packages/typescript/src/enums/syntaxKind.ts index 596eeab49f274..735c02944ada3 100644 --- a/packages/typescript/src/enums/syntaxKind.ts +++ b/packages/typescript/src/enums/syntaxKind.ts @@ -148,212 +148,213 @@ export var SyntaxKind: any; SyntaxKind[SyntaxKind["ModuleKeyword"] = 144] = "ModuleKeyword"; SyntaxKind[SyntaxKind["NamespaceKeyword"] = 145] = "NamespaceKeyword"; SyntaxKind[SyntaxKind["NeverKeyword"] = 146] = "NeverKeyword"; - SyntaxKind[SyntaxKind["OutKeyword"] = 147] = "OutKeyword"; - SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 148] = "ReadonlyKeyword"; - SyntaxKind[SyntaxKind["RequireKeyword"] = 149] = "RequireKeyword"; - SyntaxKind[SyntaxKind["NumberKeyword"] = 150] = "NumberKeyword"; - SyntaxKind[SyntaxKind["ObjectKeyword"] = 151] = "ObjectKeyword"; - SyntaxKind[SyntaxKind["SatisfiesKeyword"] = 152] = "SatisfiesKeyword"; - SyntaxKind[SyntaxKind["SetKeyword"] = 153] = "SetKeyword"; - SyntaxKind[SyntaxKind["StringKeyword"] = 154] = "StringKeyword"; - SyntaxKind[SyntaxKind["SymbolKeyword"] = 155] = "SymbolKeyword"; - SyntaxKind[SyntaxKind["TypeKeyword"] = 156] = "TypeKeyword"; - SyntaxKind[SyntaxKind["UndefinedKeyword"] = 157] = "UndefinedKeyword"; - SyntaxKind[SyntaxKind["UniqueKeyword"] = 158] = "UniqueKeyword"; - SyntaxKind[SyntaxKind["UnknownKeyword"] = 159] = "UnknownKeyword"; - SyntaxKind[SyntaxKind["UsingKeyword"] = 160] = "UsingKeyword"; - SyntaxKind[SyntaxKind["FromKeyword"] = 161] = "FromKeyword"; - SyntaxKind[SyntaxKind["GlobalKeyword"] = 162] = "GlobalKeyword"; - SyntaxKind[SyntaxKind["BigIntKeyword"] = 163] = "BigIntKeyword"; - SyntaxKind[SyntaxKind["OverrideKeyword"] = 164] = "OverrideKeyword"; - SyntaxKind[SyntaxKind["OfKeyword"] = 165] = "OfKeyword"; - SyntaxKind[SyntaxKind["DeferKeyword"] = 166] = "DeferKeyword"; - SyntaxKind[SyntaxKind["SourceKeyword"] = 167] = "SourceKeyword"; - SyntaxKind[SyntaxKind["QualifiedName"] = 168] = "QualifiedName"; - SyntaxKind[SyntaxKind["ComputedPropertyName"] = 169] = "ComputedPropertyName"; - SyntaxKind[SyntaxKind["TypeParameter"] = 170] = "TypeParameter"; - SyntaxKind[SyntaxKind["Parameter"] = 171] = "Parameter"; - SyntaxKind[SyntaxKind["Decorator"] = 172] = "Decorator"; - SyntaxKind[SyntaxKind["PropertySignature"] = 173] = "PropertySignature"; - SyntaxKind[SyntaxKind["PropertyDeclaration"] = 174] = "PropertyDeclaration"; - SyntaxKind[SyntaxKind["MethodSignature"] = 175] = "MethodSignature"; - SyntaxKind[SyntaxKind["MethodDeclaration"] = 176] = "MethodDeclaration"; - SyntaxKind[SyntaxKind["ClassStaticBlockDeclaration"] = 177] = "ClassStaticBlockDeclaration"; - SyntaxKind[SyntaxKind["Constructor"] = 178] = "Constructor"; - SyntaxKind[SyntaxKind["GetAccessor"] = 179] = "GetAccessor"; - SyntaxKind[SyntaxKind["SetAccessor"] = 180] = "SetAccessor"; - SyntaxKind[SyntaxKind["CallSignature"] = 181] = "CallSignature"; - SyntaxKind[SyntaxKind["ConstructSignature"] = 182] = "ConstructSignature"; - SyntaxKind[SyntaxKind["IndexSignature"] = 183] = "IndexSignature"; - SyntaxKind[SyntaxKind["TypePredicate"] = 184] = "TypePredicate"; - SyntaxKind[SyntaxKind["TypeReference"] = 185] = "TypeReference"; - SyntaxKind[SyntaxKind["FunctionType"] = 186] = "FunctionType"; - SyntaxKind[SyntaxKind["ConstructorType"] = 187] = "ConstructorType"; - SyntaxKind[SyntaxKind["TypeQuery"] = 188] = "TypeQuery"; - SyntaxKind[SyntaxKind["TypeLiteral"] = 189] = "TypeLiteral"; - SyntaxKind[SyntaxKind["ArrayType"] = 190] = "ArrayType"; - SyntaxKind[SyntaxKind["TupleType"] = 191] = "TupleType"; - SyntaxKind[SyntaxKind["OptionalType"] = 192] = "OptionalType"; - SyntaxKind[SyntaxKind["RestType"] = 193] = "RestType"; - SyntaxKind[SyntaxKind["UnionType"] = 194] = "UnionType"; - SyntaxKind[SyntaxKind["IntersectionType"] = 195] = "IntersectionType"; - SyntaxKind[SyntaxKind["ConditionalType"] = 196] = "ConditionalType"; - SyntaxKind[SyntaxKind["InferType"] = 197] = "InferType"; - SyntaxKind[SyntaxKind["ParenthesizedType"] = 198] = "ParenthesizedType"; - SyntaxKind[SyntaxKind["ThisType"] = 199] = "ThisType"; - SyntaxKind[SyntaxKind["TypeOperator"] = 200] = "TypeOperator"; - SyntaxKind[SyntaxKind["IndexedAccessType"] = 201] = "IndexedAccessType"; - SyntaxKind[SyntaxKind["MappedType"] = 202] = "MappedType"; - SyntaxKind[SyntaxKind["LiteralType"] = 203] = "LiteralType"; - SyntaxKind[SyntaxKind["NamedTupleMember"] = 204] = "NamedTupleMember"; - SyntaxKind[SyntaxKind["TemplateLiteralType"] = 205] = "TemplateLiteralType"; - SyntaxKind[SyntaxKind["TemplateLiteralTypeSpan"] = 206] = "TemplateLiteralTypeSpan"; - SyntaxKind[SyntaxKind["ImportType"] = 207] = "ImportType"; - SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 208] = "ObjectBindingPattern"; - SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 209] = "ArrayBindingPattern"; - SyntaxKind[SyntaxKind["BindingElement"] = 210] = "BindingElement"; - SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 211] = "ArrayLiteralExpression"; - SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 212] = "ObjectLiteralExpression"; - SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 213] = "PropertyAccessExpression"; - SyntaxKind[SyntaxKind["ElementAccessExpression"] = 214] = "ElementAccessExpression"; - SyntaxKind[SyntaxKind["CallExpression"] = 215] = "CallExpression"; - SyntaxKind[SyntaxKind["NewExpression"] = 216] = "NewExpression"; - SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 217] = "TaggedTemplateExpression"; - SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 218] = "TypeAssertionExpression"; - SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 219] = "ParenthesizedExpression"; - SyntaxKind[SyntaxKind["FunctionExpression"] = 220] = "FunctionExpression"; - SyntaxKind[SyntaxKind["ArrowFunction"] = 221] = "ArrowFunction"; - SyntaxKind[SyntaxKind["DeleteExpression"] = 222] = "DeleteExpression"; - SyntaxKind[SyntaxKind["TypeOfExpression"] = 223] = "TypeOfExpression"; - SyntaxKind[SyntaxKind["VoidExpression"] = 224] = "VoidExpression"; - SyntaxKind[SyntaxKind["AwaitExpression"] = 225] = "AwaitExpression"; - SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 226] = "PrefixUnaryExpression"; - SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 227] = "PostfixUnaryExpression"; - SyntaxKind[SyntaxKind["BinaryExpression"] = 228] = "BinaryExpression"; - SyntaxKind[SyntaxKind["ConditionalExpression"] = 229] = "ConditionalExpression"; - SyntaxKind[SyntaxKind["TemplateExpression"] = 230] = "TemplateExpression"; - SyntaxKind[SyntaxKind["YieldExpression"] = 231] = "YieldExpression"; - SyntaxKind[SyntaxKind["SpreadElement"] = 232] = "SpreadElement"; - SyntaxKind[SyntaxKind["ClassExpression"] = 233] = "ClassExpression"; - SyntaxKind[SyntaxKind["OmittedExpression"] = 234] = "OmittedExpression"; - SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 235] = "ExpressionWithTypeArguments"; - SyntaxKind[SyntaxKind["AsExpression"] = 236] = "AsExpression"; - SyntaxKind[SyntaxKind["NonNullExpression"] = 237] = "NonNullExpression"; - SyntaxKind[SyntaxKind["MetaProperty"] = 238] = "MetaProperty"; - SyntaxKind[SyntaxKind["SyntheticExpression"] = 239] = "SyntheticExpression"; - SyntaxKind[SyntaxKind["SatisfiesExpression"] = 240] = "SatisfiesExpression"; - SyntaxKind[SyntaxKind["TemplateSpan"] = 241] = "TemplateSpan"; - SyntaxKind[SyntaxKind["SemicolonClassElement"] = 242] = "SemicolonClassElement"; - SyntaxKind[SyntaxKind["Block"] = 243] = "Block"; - SyntaxKind[SyntaxKind["EmptyStatement"] = 244] = "EmptyStatement"; - SyntaxKind[SyntaxKind["VariableStatement"] = 245] = "VariableStatement"; - SyntaxKind[SyntaxKind["ExpressionStatement"] = 246] = "ExpressionStatement"; - SyntaxKind[SyntaxKind["IfStatement"] = 247] = "IfStatement"; - SyntaxKind[SyntaxKind["DoStatement"] = 248] = "DoStatement"; - SyntaxKind[SyntaxKind["WhileStatement"] = 249] = "WhileStatement"; - SyntaxKind[SyntaxKind["ForStatement"] = 250] = "ForStatement"; - SyntaxKind[SyntaxKind["ForInStatement"] = 251] = "ForInStatement"; - SyntaxKind[SyntaxKind["ForOfStatement"] = 252] = "ForOfStatement"; - SyntaxKind[SyntaxKind["ContinueStatement"] = 253] = "ContinueStatement"; - SyntaxKind[SyntaxKind["BreakStatement"] = 254] = "BreakStatement"; - SyntaxKind[SyntaxKind["ReturnStatement"] = 255] = "ReturnStatement"; - SyntaxKind[SyntaxKind["WithStatement"] = 256] = "WithStatement"; - SyntaxKind[SyntaxKind["SwitchStatement"] = 257] = "SwitchStatement"; - SyntaxKind[SyntaxKind["LabeledStatement"] = 258] = "LabeledStatement"; - SyntaxKind[SyntaxKind["ThrowStatement"] = 259] = "ThrowStatement"; - SyntaxKind[SyntaxKind["TryStatement"] = 260] = "TryStatement"; - SyntaxKind[SyntaxKind["DebuggerStatement"] = 261] = "DebuggerStatement"; - SyntaxKind[SyntaxKind["VariableDeclaration"] = 262] = "VariableDeclaration"; - SyntaxKind[SyntaxKind["VariableDeclarationList"] = 263] = "VariableDeclarationList"; - SyntaxKind[SyntaxKind["FunctionDeclaration"] = 264] = "FunctionDeclaration"; - SyntaxKind[SyntaxKind["ClassDeclaration"] = 265] = "ClassDeclaration"; - SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 266] = "InterfaceDeclaration"; - SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 267] = "TypeAliasDeclaration"; - SyntaxKind[SyntaxKind["EnumDeclaration"] = 268] = "EnumDeclaration"; - SyntaxKind[SyntaxKind["ModuleDeclaration"] = 269] = "ModuleDeclaration"; - SyntaxKind[SyntaxKind["ModuleBlock"] = 270] = "ModuleBlock"; - SyntaxKind[SyntaxKind["CaseBlock"] = 271] = "CaseBlock"; - SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 272] = "NamespaceExportDeclaration"; - SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 273] = "ImportEqualsDeclaration"; - SyntaxKind[SyntaxKind["ImportDeclaration"] = 274] = "ImportDeclaration"; - SyntaxKind[SyntaxKind["ImportClause"] = 275] = "ImportClause"; - SyntaxKind[SyntaxKind["NamespaceImport"] = 276] = "NamespaceImport"; - SyntaxKind[SyntaxKind["NamedImports"] = 277] = "NamedImports"; - SyntaxKind[SyntaxKind["ImportSpecifier"] = 278] = "ImportSpecifier"; - SyntaxKind[SyntaxKind["ExportAssignment"] = 279] = "ExportAssignment"; - SyntaxKind[SyntaxKind["ExportDeclaration"] = 280] = "ExportDeclaration"; - SyntaxKind[SyntaxKind["NamedExports"] = 281] = "NamedExports"; - SyntaxKind[SyntaxKind["NamespaceExport"] = 282] = "NamespaceExport"; - SyntaxKind[SyntaxKind["ExportSpecifier"] = 283] = "ExportSpecifier"; - SyntaxKind[SyntaxKind["MissingDeclaration"] = 284] = "MissingDeclaration"; - SyntaxKind[SyntaxKind["ExternalModuleReference"] = 285] = "ExternalModuleReference"; - SyntaxKind[SyntaxKind["JsxElement"] = 286] = "JsxElement"; - SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 287] = "JsxSelfClosingElement"; - SyntaxKind[SyntaxKind["JsxOpeningElement"] = 288] = "JsxOpeningElement"; - SyntaxKind[SyntaxKind["JsxClosingElement"] = 289] = "JsxClosingElement"; - SyntaxKind[SyntaxKind["JsxFragment"] = 290] = "JsxFragment"; - SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 291] = "JsxOpeningFragment"; - SyntaxKind[SyntaxKind["JsxClosingFragment"] = 292] = "JsxClosingFragment"; - SyntaxKind[SyntaxKind["JsxAttribute"] = 293] = "JsxAttribute"; - SyntaxKind[SyntaxKind["JsxAttributes"] = 294] = "JsxAttributes"; - SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 295] = "JsxSpreadAttribute"; - SyntaxKind[SyntaxKind["JsxExpression"] = 296] = "JsxExpression"; - SyntaxKind[SyntaxKind["JsxNamespacedName"] = 297] = "JsxNamespacedName"; - SyntaxKind[SyntaxKind["CaseClause"] = 298] = "CaseClause"; - SyntaxKind[SyntaxKind["DefaultClause"] = 299] = "DefaultClause"; - SyntaxKind[SyntaxKind["HeritageClause"] = 300] = "HeritageClause"; - SyntaxKind[SyntaxKind["CatchClause"] = 301] = "CatchClause"; - SyntaxKind[SyntaxKind["ImportAttributes"] = 302] = "ImportAttributes"; - SyntaxKind[SyntaxKind["ImportAttribute"] = 303] = "ImportAttribute"; - SyntaxKind[SyntaxKind["PropertyAssignment"] = 304] = "PropertyAssignment"; - SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 305] = "ShorthandPropertyAssignment"; - SyntaxKind[SyntaxKind["SpreadAssignment"] = 306] = "SpreadAssignment"; - SyntaxKind[SyntaxKind["EnumMember"] = 307] = "EnumMember"; - SyntaxKind[SyntaxKind["SourceFile"] = 308] = "SourceFile"; - SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 309] = "JSDocTypeExpression"; - SyntaxKind[SyntaxKind["JSDocNameReference"] = 310] = "JSDocNameReference"; - SyntaxKind[SyntaxKind["JSDocAllType"] = 311] = "JSDocAllType"; - SyntaxKind[SyntaxKind["JSDocNullableType"] = 312] = "JSDocNullableType"; - SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 313] = "JSDocNonNullableType"; - SyntaxKind[SyntaxKind["JSDocOptionalType"] = 314] = "JSDocOptionalType"; - SyntaxKind[SyntaxKind["JSDocVariadicType"] = 315] = "JSDocVariadicType"; - SyntaxKind[SyntaxKind["JSDoc"] = 316] = "JSDoc"; - SyntaxKind[SyntaxKind["JSDocText"] = 317] = "JSDocText"; - SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 318] = "JSDocTypeLiteral"; - SyntaxKind[SyntaxKind["JSDocSignature"] = 319] = "JSDocSignature"; - SyntaxKind[SyntaxKind["JSDocLink"] = 320] = "JSDocLink"; - SyntaxKind[SyntaxKind["JSDocLinkCode"] = 321] = "JSDocLinkCode"; - SyntaxKind[SyntaxKind["JSDocLinkPlain"] = 322] = "JSDocLinkPlain"; - SyntaxKind[SyntaxKind["JSDocUnknownTag"] = 323] = "JSDocUnknownTag"; - SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 324] = "JSDocAugmentsTag"; - SyntaxKind[SyntaxKind["JSDocImplementsTag"] = 325] = "JSDocImplementsTag"; - SyntaxKind[SyntaxKind["JSDocDeprecatedTag"] = 326] = "JSDocDeprecatedTag"; - SyntaxKind[SyntaxKind["JSDocPublicTag"] = 327] = "JSDocPublicTag"; - SyntaxKind[SyntaxKind["JSDocPrivateTag"] = 328] = "JSDocPrivateTag"; - SyntaxKind[SyntaxKind["JSDocProtectedTag"] = 329] = "JSDocProtectedTag"; - SyntaxKind[SyntaxKind["JSDocReadonlyTag"] = 330] = "JSDocReadonlyTag"; - SyntaxKind[SyntaxKind["JSDocOverrideTag"] = 331] = "JSDocOverrideTag"; - SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 332] = "JSDocCallbackTag"; - SyntaxKind[SyntaxKind["JSDocOverloadTag"] = 333] = "JSDocOverloadTag"; - SyntaxKind[SyntaxKind["JSDocParameterTag"] = 334] = "JSDocParameterTag"; - SyntaxKind[SyntaxKind["JSDocReturnTag"] = 335] = "JSDocReturnTag"; - SyntaxKind[SyntaxKind["JSDocThisTag"] = 336] = "JSDocThisTag"; - SyntaxKind[SyntaxKind["JSDocTypeTag"] = 337] = "JSDocTypeTag"; - SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 338] = "JSDocTemplateTag"; - SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 339] = "JSDocTypedefTag"; - SyntaxKind[SyntaxKind["JSDocSeeTag"] = 340] = "JSDocSeeTag"; - SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 341] = "JSDocPropertyTag"; - SyntaxKind[SyntaxKind["JSDocThrowsTag"] = 342] = "JSDocThrowsTag"; - SyntaxKind[SyntaxKind["JSDocSatisfiesTag"] = 343] = "JSDocSatisfiesTag"; - SyntaxKind[SyntaxKind["JSDocImportTag"] = 344] = "JSDocImportTag"; - SyntaxKind[SyntaxKind["SyntaxList"] = 345] = "SyntaxList"; - SyntaxKind[SyntaxKind["JSTypeAliasDeclaration"] = 346] = "JSTypeAliasDeclaration"; - SyntaxKind[SyntaxKind["JSImportDeclaration"] = 347] = "JSImportDeclaration"; - SyntaxKind[SyntaxKind["NotEmittedStatement"] = 348] = "NotEmittedStatement"; - SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 349] = "PartiallyEmittedExpression"; - SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 350] = "SyntheticReferenceExpression"; - SyntaxKind[SyntaxKind["NotEmittedTypeElement"] = 351] = "NotEmittedTypeElement"; - SyntaxKind[SyntaxKind["Count"] = 352] = "Count"; + SyntaxKind[SyntaxKind["NotKeyword"] = 147] = "NotKeyword"; + SyntaxKind[SyntaxKind["OutKeyword"] = 148] = "OutKeyword"; + SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 149] = "ReadonlyKeyword"; + SyntaxKind[SyntaxKind["RequireKeyword"] = 150] = "RequireKeyword"; + SyntaxKind[SyntaxKind["NumberKeyword"] = 151] = "NumberKeyword"; + SyntaxKind[SyntaxKind["ObjectKeyword"] = 152] = "ObjectKeyword"; + SyntaxKind[SyntaxKind["SatisfiesKeyword"] = 153] = "SatisfiesKeyword"; + SyntaxKind[SyntaxKind["SetKeyword"] = 154] = "SetKeyword"; + SyntaxKind[SyntaxKind["StringKeyword"] = 155] = "StringKeyword"; + SyntaxKind[SyntaxKind["SymbolKeyword"] = 156] = "SymbolKeyword"; + SyntaxKind[SyntaxKind["TypeKeyword"] = 157] = "TypeKeyword"; + SyntaxKind[SyntaxKind["UndefinedKeyword"] = 158] = "UndefinedKeyword"; + SyntaxKind[SyntaxKind["UniqueKeyword"] = 159] = "UniqueKeyword"; + SyntaxKind[SyntaxKind["UnknownKeyword"] = 160] = "UnknownKeyword"; + SyntaxKind[SyntaxKind["UsingKeyword"] = 161] = "UsingKeyword"; + SyntaxKind[SyntaxKind["FromKeyword"] = 162] = "FromKeyword"; + SyntaxKind[SyntaxKind["GlobalKeyword"] = 163] = "GlobalKeyword"; + SyntaxKind[SyntaxKind["BigIntKeyword"] = 164] = "BigIntKeyword"; + SyntaxKind[SyntaxKind["OverrideKeyword"] = 165] = "OverrideKeyword"; + SyntaxKind[SyntaxKind["OfKeyword"] = 166] = "OfKeyword"; + SyntaxKind[SyntaxKind["DeferKeyword"] = 167] = "DeferKeyword"; + SyntaxKind[SyntaxKind["SourceKeyword"] = 168] = "SourceKeyword"; + SyntaxKind[SyntaxKind["QualifiedName"] = 169] = "QualifiedName"; + SyntaxKind[SyntaxKind["ComputedPropertyName"] = 170] = "ComputedPropertyName"; + SyntaxKind[SyntaxKind["TypeParameter"] = 171] = "TypeParameter"; + SyntaxKind[SyntaxKind["Parameter"] = 172] = "Parameter"; + SyntaxKind[SyntaxKind["Decorator"] = 173] = "Decorator"; + SyntaxKind[SyntaxKind["PropertySignature"] = 174] = "PropertySignature"; + SyntaxKind[SyntaxKind["PropertyDeclaration"] = 175] = "PropertyDeclaration"; + SyntaxKind[SyntaxKind["MethodSignature"] = 176] = "MethodSignature"; + SyntaxKind[SyntaxKind["MethodDeclaration"] = 177] = "MethodDeclaration"; + SyntaxKind[SyntaxKind["ClassStaticBlockDeclaration"] = 178] = "ClassStaticBlockDeclaration"; + SyntaxKind[SyntaxKind["Constructor"] = 179] = "Constructor"; + SyntaxKind[SyntaxKind["GetAccessor"] = 180] = "GetAccessor"; + SyntaxKind[SyntaxKind["SetAccessor"] = 181] = "SetAccessor"; + SyntaxKind[SyntaxKind["CallSignature"] = 182] = "CallSignature"; + SyntaxKind[SyntaxKind["ConstructSignature"] = 183] = "ConstructSignature"; + SyntaxKind[SyntaxKind["IndexSignature"] = 184] = "IndexSignature"; + SyntaxKind[SyntaxKind["TypePredicate"] = 185] = "TypePredicate"; + SyntaxKind[SyntaxKind["TypeReference"] = 186] = "TypeReference"; + SyntaxKind[SyntaxKind["FunctionType"] = 187] = "FunctionType"; + SyntaxKind[SyntaxKind["ConstructorType"] = 188] = "ConstructorType"; + SyntaxKind[SyntaxKind["TypeQuery"] = 189] = "TypeQuery"; + SyntaxKind[SyntaxKind["TypeLiteral"] = 190] = "TypeLiteral"; + SyntaxKind[SyntaxKind["ArrayType"] = 191] = "ArrayType"; + SyntaxKind[SyntaxKind["TupleType"] = 192] = "TupleType"; + SyntaxKind[SyntaxKind["OptionalType"] = 193] = "OptionalType"; + SyntaxKind[SyntaxKind["RestType"] = 194] = "RestType"; + SyntaxKind[SyntaxKind["UnionType"] = 195] = "UnionType"; + SyntaxKind[SyntaxKind["IntersectionType"] = 196] = "IntersectionType"; + SyntaxKind[SyntaxKind["ConditionalType"] = 197] = "ConditionalType"; + SyntaxKind[SyntaxKind["InferType"] = 198] = "InferType"; + SyntaxKind[SyntaxKind["ParenthesizedType"] = 199] = "ParenthesizedType"; + SyntaxKind[SyntaxKind["ThisType"] = 200] = "ThisType"; + SyntaxKind[SyntaxKind["TypeOperator"] = 201] = "TypeOperator"; + SyntaxKind[SyntaxKind["IndexedAccessType"] = 202] = "IndexedAccessType"; + SyntaxKind[SyntaxKind["MappedType"] = 203] = "MappedType"; + SyntaxKind[SyntaxKind["LiteralType"] = 204] = "LiteralType"; + SyntaxKind[SyntaxKind["NamedTupleMember"] = 205] = "NamedTupleMember"; + SyntaxKind[SyntaxKind["TemplateLiteralType"] = 206] = "TemplateLiteralType"; + SyntaxKind[SyntaxKind["TemplateLiteralTypeSpan"] = 207] = "TemplateLiteralTypeSpan"; + SyntaxKind[SyntaxKind["ImportType"] = 208] = "ImportType"; + SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 209] = "ObjectBindingPattern"; + SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 210] = "ArrayBindingPattern"; + SyntaxKind[SyntaxKind["BindingElement"] = 211] = "BindingElement"; + SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 212] = "ArrayLiteralExpression"; + SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 213] = "ObjectLiteralExpression"; + SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 214] = "PropertyAccessExpression"; + SyntaxKind[SyntaxKind["ElementAccessExpression"] = 215] = "ElementAccessExpression"; + SyntaxKind[SyntaxKind["CallExpression"] = 216] = "CallExpression"; + SyntaxKind[SyntaxKind["NewExpression"] = 217] = "NewExpression"; + SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 218] = "TaggedTemplateExpression"; + SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 219] = "TypeAssertionExpression"; + SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 220] = "ParenthesizedExpression"; + SyntaxKind[SyntaxKind["FunctionExpression"] = 221] = "FunctionExpression"; + SyntaxKind[SyntaxKind["ArrowFunction"] = 222] = "ArrowFunction"; + SyntaxKind[SyntaxKind["DeleteExpression"] = 223] = "DeleteExpression"; + SyntaxKind[SyntaxKind["TypeOfExpression"] = 224] = "TypeOfExpression"; + SyntaxKind[SyntaxKind["VoidExpression"] = 225] = "VoidExpression"; + SyntaxKind[SyntaxKind["AwaitExpression"] = 226] = "AwaitExpression"; + SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 227] = "PrefixUnaryExpression"; + SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 228] = "PostfixUnaryExpression"; + SyntaxKind[SyntaxKind["BinaryExpression"] = 229] = "BinaryExpression"; + SyntaxKind[SyntaxKind["ConditionalExpression"] = 230] = "ConditionalExpression"; + SyntaxKind[SyntaxKind["TemplateExpression"] = 231] = "TemplateExpression"; + SyntaxKind[SyntaxKind["YieldExpression"] = 232] = "YieldExpression"; + SyntaxKind[SyntaxKind["SpreadElement"] = 233] = "SpreadElement"; + SyntaxKind[SyntaxKind["ClassExpression"] = 234] = "ClassExpression"; + SyntaxKind[SyntaxKind["OmittedExpression"] = 235] = "OmittedExpression"; + SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 236] = "ExpressionWithTypeArguments"; + SyntaxKind[SyntaxKind["AsExpression"] = 237] = "AsExpression"; + SyntaxKind[SyntaxKind["NonNullExpression"] = 238] = "NonNullExpression"; + SyntaxKind[SyntaxKind["MetaProperty"] = 239] = "MetaProperty"; + SyntaxKind[SyntaxKind["SyntheticExpression"] = 240] = "SyntheticExpression"; + SyntaxKind[SyntaxKind["SatisfiesExpression"] = 241] = "SatisfiesExpression"; + SyntaxKind[SyntaxKind["TemplateSpan"] = 242] = "TemplateSpan"; + SyntaxKind[SyntaxKind["SemicolonClassElement"] = 243] = "SemicolonClassElement"; + SyntaxKind[SyntaxKind["Block"] = 244] = "Block"; + SyntaxKind[SyntaxKind["EmptyStatement"] = 245] = "EmptyStatement"; + SyntaxKind[SyntaxKind["VariableStatement"] = 246] = "VariableStatement"; + SyntaxKind[SyntaxKind["ExpressionStatement"] = 247] = "ExpressionStatement"; + SyntaxKind[SyntaxKind["IfStatement"] = 248] = "IfStatement"; + SyntaxKind[SyntaxKind["DoStatement"] = 249] = "DoStatement"; + SyntaxKind[SyntaxKind["WhileStatement"] = 250] = "WhileStatement"; + SyntaxKind[SyntaxKind["ForStatement"] = 251] = "ForStatement"; + SyntaxKind[SyntaxKind["ForInStatement"] = 252] = "ForInStatement"; + SyntaxKind[SyntaxKind["ForOfStatement"] = 253] = "ForOfStatement"; + SyntaxKind[SyntaxKind["ContinueStatement"] = 254] = "ContinueStatement"; + SyntaxKind[SyntaxKind["BreakStatement"] = 255] = "BreakStatement"; + SyntaxKind[SyntaxKind["ReturnStatement"] = 256] = "ReturnStatement"; + SyntaxKind[SyntaxKind["WithStatement"] = 257] = "WithStatement"; + SyntaxKind[SyntaxKind["SwitchStatement"] = 258] = "SwitchStatement"; + SyntaxKind[SyntaxKind["LabeledStatement"] = 259] = "LabeledStatement"; + SyntaxKind[SyntaxKind["ThrowStatement"] = 260] = "ThrowStatement"; + SyntaxKind[SyntaxKind["TryStatement"] = 261] = "TryStatement"; + SyntaxKind[SyntaxKind["DebuggerStatement"] = 262] = "DebuggerStatement"; + SyntaxKind[SyntaxKind["VariableDeclaration"] = 263] = "VariableDeclaration"; + SyntaxKind[SyntaxKind["VariableDeclarationList"] = 264] = "VariableDeclarationList"; + SyntaxKind[SyntaxKind["FunctionDeclaration"] = 265] = "FunctionDeclaration"; + SyntaxKind[SyntaxKind["ClassDeclaration"] = 266] = "ClassDeclaration"; + SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 267] = "InterfaceDeclaration"; + SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 268] = "TypeAliasDeclaration"; + SyntaxKind[SyntaxKind["EnumDeclaration"] = 269] = "EnumDeclaration"; + SyntaxKind[SyntaxKind["ModuleDeclaration"] = 270] = "ModuleDeclaration"; + SyntaxKind[SyntaxKind["ModuleBlock"] = 271] = "ModuleBlock"; + SyntaxKind[SyntaxKind["CaseBlock"] = 272] = "CaseBlock"; + SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 273] = "NamespaceExportDeclaration"; + SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 274] = "ImportEqualsDeclaration"; + SyntaxKind[SyntaxKind["ImportDeclaration"] = 275] = "ImportDeclaration"; + SyntaxKind[SyntaxKind["ImportClause"] = 276] = "ImportClause"; + SyntaxKind[SyntaxKind["NamespaceImport"] = 277] = "NamespaceImport"; + SyntaxKind[SyntaxKind["NamedImports"] = 278] = "NamedImports"; + SyntaxKind[SyntaxKind["ImportSpecifier"] = 279] = "ImportSpecifier"; + SyntaxKind[SyntaxKind["ExportAssignment"] = 280] = "ExportAssignment"; + SyntaxKind[SyntaxKind["ExportDeclaration"] = 281] = "ExportDeclaration"; + SyntaxKind[SyntaxKind["NamedExports"] = 282] = "NamedExports"; + SyntaxKind[SyntaxKind["NamespaceExport"] = 283] = "NamespaceExport"; + SyntaxKind[SyntaxKind["ExportSpecifier"] = 284] = "ExportSpecifier"; + SyntaxKind[SyntaxKind["MissingDeclaration"] = 285] = "MissingDeclaration"; + SyntaxKind[SyntaxKind["ExternalModuleReference"] = 286] = "ExternalModuleReference"; + SyntaxKind[SyntaxKind["JsxElement"] = 287] = "JsxElement"; + SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 288] = "JsxSelfClosingElement"; + SyntaxKind[SyntaxKind["JsxOpeningElement"] = 289] = "JsxOpeningElement"; + SyntaxKind[SyntaxKind["JsxClosingElement"] = 290] = "JsxClosingElement"; + SyntaxKind[SyntaxKind["JsxFragment"] = 291] = "JsxFragment"; + SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 292] = "JsxOpeningFragment"; + SyntaxKind[SyntaxKind["JsxClosingFragment"] = 293] = "JsxClosingFragment"; + SyntaxKind[SyntaxKind["JsxAttribute"] = 294] = "JsxAttribute"; + SyntaxKind[SyntaxKind["JsxAttributes"] = 295] = "JsxAttributes"; + SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 296] = "JsxSpreadAttribute"; + SyntaxKind[SyntaxKind["JsxExpression"] = 297] = "JsxExpression"; + SyntaxKind[SyntaxKind["JsxNamespacedName"] = 298] = "JsxNamespacedName"; + SyntaxKind[SyntaxKind["CaseClause"] = 299] = "CaseClause"; + SyntaxKind[SyntaxKind["DefaultClause"] = 300] = "DefaultClause"; + SyntaxKind[SyntaxKind["HeritageClause"] = 301] = "HeritageClause"; + SyntaxKind[SyntaxKind["CatchClause"] = 302] = "CatchClause"; + SyntaxKind[SyntaxKind["ImportAttributes"] = 303] = "ImportAttributes"; + SyntaxKind[SyntaxKind["ImportAttribute"] = 304] = "ImportAttribute"; + SyntaxKind[SyntaxKind["PropertyAssignment"] = 305] = "PropertyAssignment"; + SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 306] = "ShorthandPropertyAssignment"; + SyntaxKind[SyntaxKind["SpreadAssignment"] = 307] = "SpreadAssignment"; + SyntaxKind[SyntaxKind["EnumMember"] = 308] = "EnumMember"; + SyntaxKind[SyntaxKind["SourceFile"] = 309] = "SourceFile"; + SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 310] = "JSDocTypeExpression"; + SyntaxKind[SyntaxKind["JSDocNameReference"] = 311] = "JSDocNameReference"; + SyntaxKind[SyntaxKind["JSDocAllType"] = 312] = "JSDocAllType"; + SyntaxKind[SyntaxKind["JSDocNullableType"] = 313] = "JSDocNullableType"; + SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 314] = "JSDocNonNullableType"; + SyntaxKind[SyntaxKind["JSDocOptionalType"] = 315] = "JSDocOptionalType"; + SyntaxKind[SyntaxKind["JSDocVariadicType"] = 316] = "JSDocVariadicType"; + SyntaxKind[SyntaxKind["JSDoc"] = 317] = "JSDoc"; + SyntaxKind[SyntaxKind["JSDocText"] = 318] = "JSDocText"; + SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 319] = "JSDocTypeLiteral"; + SyntaxKind[SyntaxKind["JSDocSignature"] = 320] = "JSDocSignature"; + SyntaxKind[SyntaxKind["JSDocLink"] = 321] = "JSDocLink"; + SyntaxKind[SyntaxKind["JSDocLinkCode"] = 322] = "JSDocLinkCode"; + SyntaxKind[SyntaxKind["JSDocLinkPlain"] = 323] = "JSDocLinkPlain"; + SyntaxKind[SyntaxKind["JSDocUnknownTag"] = 324] = "JSDocUnknownTag"; + SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 325] = "JSDocAugmentsTag"; + SyntaxKind[SyntaxKind["JSDocImplementsTag"] = 326] = "JSDocImplementsTag"; + SyntaxKind[SyntaxKind["JSDocDeprecatedTag"] = 327] = "JSDocDeprecatedTag"; + SyntaxKind[SyntaxKind["JSDocPublicTag"] = 328] = "JSDocPublicTag"; + SyntaxKind[SyntaxKind["JSDocPrivateTag"] = 329] = "JSDocPrivateTag"; + SyntaxKind[SyntaxKind["JSDocProtectedTag"] = 330] = "JSDocProtectedTag"; + SyntaxKind[SyntaxKind["JSDocReadonlyTag"] = 331] = "JSDocReadonlyTag"; + SyntaxKind[SyntaxKind["JSDocOverrideTag"] = 332] = "JSDocOverrideTag"; + SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 333] = "JSDocCallbackTag"; + SyntaxKind[SyntaxKind["JSDocOverloadTag"] = 334] = "JSDocOverloadTag"; + SyntaxKind[SyntaxKind["JSDocParameterTag"] = 335] = "JSDocParameterTag"; + SyntaxKind[SyntaxKind["JSDocReturnTag"] = 336] = "JSDocReturnTag"; + SyntaxKind[SyntaxKind["JSDocThisTag"] = 337] = "JSDocThisTag"; + SyntaxKind[SyntaxKind["JSDocTypeTag"] = 338] = "JSDocTypeTag"; + SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 339] = "JSDocTemplateTag"; + SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 340] = "JSDocTypedefTag"; + SyntaxKind[SyntaxKind["JSDocSeeTag"] = 341] = "JSDocSeeTag"; + SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 342] = "JSDocPropertyTag"; + SyntaxKind[SyntaxKind["JSDocThrowsTag"] = 343] = "JSDocThrowsTag"; + SyntaxKind[SyntaxKind["JSDocSatisfiesTag"] = 344] = "JSDocSatisfiesTag"; + SyntaxKind[SyntaxKind["JSDocImportTag"] = 345] = "JSDocImportTag"; + SyntaxKind[SyntaxKind["SyntaxList"] = 346] = "SyntaxList"; + SyntaxKind[SyntaxKind["JSTypeAliasDeclaration"] = 347] = "JSTypeAliasDeclaration"; + SyntaxKind[SyntaxKind["JSImportDeclaration"] = 348] = "JSImportDeclaration"; + SyntaxKind[SyntaxKind["NotEmittedStatement"] = 349] = "NotEmittedStatement"; + SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 350] = "PartiallyEmittedExpression"; + SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 351] = "SyntheticReferenceExpression"; + SyntaxKind[SyntaxKind["NotEmittedTypeElement"] = 352] = "NotEmittedTypeElement"; + SyntaxKind[SyntaxKind["Count"] = 353] = "Count"; SyntaxKind[SyntaxKind["FirstAssignment"] = 63] = "FirstAssignment"; SyntaxKind[SyntaxKind["LastAssignment"] = 78] = "LastAssignment"; SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 64] = "FirstCompoundAssignment"; @@ -361,30 +362,30 @@ export var SyntaxKind: any; SyntaxKind[SyntaxKind["FirstReservedWord"] = 82] = "FirstReservedWord"; SyntaxKind[SyntaxKind["LastReservedWord"] = 117] = "LastReservedWord"; SyntaxKind[SyntaxKind["FirstKeyword"] = 82] = "FirstKeyword"; - SyntaxKind[SyntaxKind["LastKeyword"] = 167] = "LastKeyword"; + SyntaxKind[SyntaxKind["LastKeyword"] = 168] = "LastKeyword"; SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 118] = "FirstFutureReservedWord"; SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 126] = "LastFutureReservedWord"; - SyntaxKind[SyntaxKind["FirstTypeNode"] = 184] = "FirstTypeNode"; - SyntaxKind[SyntaxKind["LastTypeNode"] = 207] = "LastTypeNode"; + SyntaxKind[SyntaxKind["FirstTypeNode"] = 185] = "FirstTypeNode"; + SyntaxKind[SyntaxKind["LastTypeNode"] = 208] = "LastTypeNode"; SyntaxKind[SyntaxKind["FirstPunctuation"] = 18] = "FirstPunctuation"; SyntaxKind[SyntaxKind["LastPunctuation"] = 78] = "LastPunctuation"; SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken"; - SyntaxKind[SyntaxKind["LastToken"] = 167] = "LastToken"; + SyntaxKind[SyntaxKind["LastToken"] = 168] = "LastToken"; SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken"; SyntaxKind[SyntaxKind["LastLiteralToken"] = 14] = "LastLiteralToken"; SyntaxKind[SyntaxKind["FirstTemplateToken"] = 14] = "FirstTemplateToken"; SyntaxKind[SyntaxKind["LastTemplateToken"] = 17] = "LastTemplateToken"; SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 29] = "FirstBinaryOperator"; SyntaxKind[SyntaxKind["LastBinaryOperator"] = 78] = "LastBinaryOperator"; - SyntaxKind[SyntaxKind["FirstStatement"] = 245] = "FirstStatement"; - SyntaxKind[SyntaxKind["LastStatement"] = 261] = "LastStatement"; - SyntaxKind[SyntaxKind["FirstNode"] = 168] = "FirstNode"; - SyntaxKind[SyntaxKind["FirstJSDocNode"] = 309] = "FirstJSDocNode"; - SyntaxKind[SyntaxKind["LastJSDocNode"] = 344] = "LastJSDocNode"; - SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 323] = "FirstJSDocTagNode"; - SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 344] = "LastJSDocTagNode"; + SyntaxKind[SyntaxKind["FirstStatement"] = 246] = "FirstStatement"; + SyntaxKind[SyntaxKind["LastStatement"] = 262] = "LastStatement"; + SyntaxKind[SyntaxKind["FirstNode"] = 169] = "FirstNode"; + SyntaxKind[SyntaxKind["FirstJSDocNode"] = 310] = "FirstJSDocNode"; + SyntaxKind[SyntaxKind["LastJSDocNode"] = 345] = "LastJSDocNode"; + SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 324] = "FirstJSDocTagNode"; + SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 345] = "LastJSDocTagNode"; SyntaxKind[SyntaxKind["FirstContextualKeyword"] = 127] = "FirstContextualKeyword"; - SyntaxKind[SyntaxKind["LastContextualKeyword"] = 167] = "LastContextualKeyword"; + SyntaxKind[SyntaxKind["LastContextualKeyword"] = 168] = "LastContextualKeyword"; SyntaxKind[SyntaxKind["LastUnaryOperator"] = 54] = "LastUnaryOperator"; SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken"; SyntaxKind[SyntaxKind["LastTriviaToken"] = 6] = "LastTriviaToken"; diff --git a/packages/typescript/src/enums/typeFlags.enum.ts b/packages/typescript/src/enums/typeFlags.enum.ts index 282cbcfe49406..d771a027eff0d 100644 --- a/packages/typescript/src/enums/typeFlags.enum.ts +++ b/packages/typescript/src/enums/typeFlags.enum.ts @@ -27,13 +27,11 @@ export enum TypeFlags { TemplateLiteral = 1 << 22, StringMapping = 1 << 23, Substitution = 1 << 24, - IndexedAccess = 1 << 25, - Conditional = 1 << 26, - Union = 1 << 27, - Intersection = 1 << 28, - Reserved1 = 1 << 29, - Reserved2 = 1 << 30, - Reserved3 = 1 << 31, + Negated = 1 << 25, + IndexedAccess = 1 << 26, + Conditional = 1 << 27, + Union = 1 << 28, + Intersection = 1 << 29, AnyOrUnknown = Any | Unknown, Nullable = Undefined | Null, Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral, @@ -57,7 +55,7 @@ export enum TypeFlags { UnionOrIntersection = Union | Intersection, StructuredType = Object | Union | Intersection, TypeVariable = TypeParameter | IndexedAccess, - InstantiableNonPrimitive = TypeVariable | Conditional | Substitution, + InstantiableNonPrimitive = TypeVariable | Conditional | Substitution | Negated, InstantiablePrimitive = Index | TemplateLiteral | StringMapping, Instantiable = InstantiableNonPrimitive | InstantiablePrimitive, StructuredOrInstantiable = StructuredType | Instantiable, @@ -71,7 +69,5 @@ export enum TypeFlags { IncludesWildcard = IndexedAccess, IncludesEmptyObject = Conditional, IncludesInstantiable = Substitution, - IncludesConstrainedTypeVariable = Reserved1, - IncludesError = Reserved2, NotPrimitiveUnion = Any | Unknown | Void | Never | Object | Intersection | IncludesInstantiable, } diff --git a/packages/typescript/src/enums/typeFlags.ts b/packages/typescript/src/enums/typeFlags.ts index e1e8432972020..c0948bde4a12e 100644 --- a/packages/typescript/src/enums/typeFlags.ts +++ b/packages/typescript/src/enums/typeFlags.ts @@ -27,13 +27,11 @@ export var TypeFlags: any; TypeFlags[TypeFlags["TemplateLiteral"] = 4194304] = "TemplateLiteral"; TypeFlags[TypeFlags["StringMapping"] = 8388608] = "StringMapping"; TypeFlags[TypeFlags["Substitution"] = 16777216] = "Substitution"; - TypeFlags[TypeFlags["IndexedAccess"] = 33554432] = "IndexedAccess"; - TypeFlags[TypeFlags["Conditional"] = 67108864] = "Conditional"; - TypeFlags[TypeFlags["Union"] = 134217728] = "Union"; - TypeFlags[TypeFlags["Intersection"] = 268435456] = "Intersection"; - TypeFlags[TypeFlags["Reserved1"] = 536870912] = "Reserved1"; - TypeFlags[TypeFlags["Reserved2"] = 1073741824] = "Reserved2"; - TypeFlags[TypeFlags["Reserved3"] = -2147483648] = "Reserved3"; + TypeFlags[TypeFlags["Negated"] = 33554432] = "Negated"; + TypeFlags[TypeFlags["IndexedAccess"] = 67108864] = "IndexedAccess"; + TypeFlags[TypeFlags["Conditional"] = 134217728] = "Conditional"; + TypeFlags[TypeFlags["Union"] = 268435456] = "Union"; + TypeFlags[TypeFlags["Intersection"] = 536870912] = "Intersection"; TypeFlags[TypeFlags["AnyOrUnknown"] = 3] = "AnyOrUnknown"; TypeFlags[TypeFlags["Nullable"] = 12] = "Nullable"; TypeFlags[TypeFlags["Literal"] = 15360] = "Literal"; @@ -54,24 +52,22 @@ export var TypeFlags: any; TypeFlags[TypeFlags["Primitive"] = 12713980] = "Primitive"; TypeFlags[TypeFlags["DefinitelyNonNullable"] = 13893600] = "DefinitelyNonNullable"; TypeFlags[TypeFlags["DisjointDomains"] = 12812284] = "DisjointDomains"; - TypeFlags[TypeFlags["UnionOrIntersection"] = 402653184] = "UnionOrIntersection"; - TypeFlags[TypeFlags["StructuredType"] = 403701760] = "StructuredType"; - TypeFlags[TypeFlags["TypeVariable"] = 34078720] = "TypeVariable"; - TypeFlags[TypeFlags["InstantiableNonPrimitive"] = 117964800] = "InstantiableNonPrimitive"; + TypeFlags[TypeFlags["UnionOrIntersection"] = 805306368] = "UnionOrIntersection"; + TypeFlags[TypeFlags["StructuredType"] = 806354944] = "StructuredType"; + TypeFlags[TypeFlags["TypeVariable"] = 67633152] = "TypeVariable"; + TypeFlags[TypeFlags["InstantiableNonPrimitive"] = 252182528] = "InstantiableNonPrimitive"; TypeFlags[TypeFlags["InstantiablePrimitive"] = 14680064] = "InstantiablePrimitive"; - TypeFlags[TypeFlags["Instantiable"] = 132644864] = "Instantiable"; - TypeFlags[TypeFlags["StructuredOrInstantiable"] = 536346624] = "StructuredOrInstantiable"; - TypeFlags[TypeFlags["ObjectFlagsType"] = 403963917] = "ObjectFlagsType"; - TypeFlags[TypeFlags["Simplifiable"] = 102760448] = "Simplifiable"; + TypeFlags[TypeFlags["Instantiable"] = 266862592] = "Instantiable"; + TypeFlags[TypeFlags["StructuredOrInstantiable"] = 1073217536] = "StructuredOrInstantiable"; + TypeFlags[TypeFlags["ObjectFlagsType"] = 806617101] = "ObjectFlagsType"; + TypeFlags[TypeFlags["Simplifiable"] = 203423744] = "Simplifiable"; TypeFlags[TypeFlags["Singleton"] = 394239] = "Singleton"; - TypeFlags[TypeFlags["Narrowable"] = 536575971] = "Narrowable"; - TypeFlags[TypeFlags["IncludesMask"] = 416808959] = "IncludesMask"; + TypeFlags[TypeFlags["Narrowable"] = 1073446883] = "Narrowable"; + TypeFlags[TypeFlags["IncludesMask"] = 819462143] = "IncludesMask"; TypeFlags[TypeFlags["IncludesMissingType"] = 524288] = "IncludesMissingType"; TypeFlags[TypeFlags["IncludesNonWideningType"] = 2097152] = "IncludesNonWideningType"; - TypeFlags[TypeFlags["IncludesWildcard"] = 33554432] = "IncludesWildcard"; - TypeFlags[TypeFlags["IncludesEmptyObject"] = 67108864] = "IncludesEmptyObject"; + TypeFlags[TypeFlags["IncludesWildcard"] = 67108864] = "IncludesWildcard"; + TypeFlags[TypeFlags["IncludesEmptyObject"] = 134217728] = "IncludesEmptyObject"; TypeFlags[TypeFlags["IncludesInstantiable"] = 16777216] = "IncludesInstantiable"; - TypeFlags[TypeFlags["IncludesConstrainedTypeVariable"] = 536870912] = "IncludesConstrainedTypeVariable"; - TypeFlags[TypeFlags["IncludesError"] = 1073741824] = "IncludesError"; - TypeFlags[TypeFlags["NotPrimitiveUnion"] = 286523411] = "NotPrimitiveUnion"; + TypeFlags[TypeFlags["NotPrimitiveUnion"] = 554958867] = "NotPrimitiveUnion"; })(TypeFlags || (TypeFlags = {})); diff --git a/packages/typescript/test/async/api.test.ts b/packages/typescript/test/async/api.test.ts index 379f07b6b68f7..09db9c653aa6b 100644 --- a/packages/typescript/test/async/api.test.ts +++ b/packages/typescript/test/async/api.test.ts @@ -3737,6 +3737,11 @@ export class Cache { const nonNullable = await project.checker.getNonNullableType(type); assert.strictEqual(await type.getNonNullableType(), nonNullable); }); + await assertOneRequest(async () => { + const negatedType = await type.getNegatedType(); + assert.ok(negatedType.flags & TypeFlags.Negated); + assert.strictEqual(await project.checker.getNegatedType(type), negatedType); + }); await assertOneRequest(async () => { const apparentType = await type.getApparentType(); assert.strictEqual(await project.checker.getApparentType(type), apparentType); diff --git a/packages/typescript/test/sync/api-generators.test.ts b/packages/typescript/test/sync/api-generators.test.ts index 314052b63f789..b12cea1a36d48 100644 --- a/packages/typescript/test/sync/api-generators.test.ts +++ b/packages/typescript/test/sync/api-generators.test.ts @@ -1701,6 +1701,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => parityCase("Checker", "getBaseTypes", checker.getBaseTypes, assertTypeArraysEquivalent, derivedType), parityCase("Checker", "getApparentType", checker.getApparentType, assertTypesEquivalent, interfaceType), parityCase("Checker", "getReducedType", checker.getReducedType, assertTypesEquivalent, unionType), + parityCase("Checker", "getNegatedType", checker.getNegatedType, assertTypesEquivalent, interfaceType), parityCase("Checker", "getPropertiesOfType", checker.getPropertiesOfType, assertSymbolArraysEquivalent, interfaceType), parityCase("Checker", "getIndexInfosOfType", checker.getIndexInfosOfType, assertIndexInfosEquivalent, interfaceType), parityCase("Checker", "getIndexInfoOfType", checker.getIndexInfoOfType, assertDeepEquivalent, interfaceType, IndexKind.String), @@ -1749,6 +1750,7 @@ describe("API - generator batching", { concurrency: areTestsFiltered() }, () => parityCase("Type", "getCallSignatures", checker.getTypeAtLocation(combineDeclaration.name!).getCallSignatures, assertSignatureArraysEquivalent), parityCase("Type", "getConstructSignatures", derivedConstructorType.getConstructSignatures, assertSignatureArraysEquivalent), parityCase("Type", "getNonNullableType", interfaceType.getNonNullableType, assertTypesEquivalent), + parityCase("Type", "getNegatedType", interfaceType.getNegatedType, assertTypesEquivalent), parityCase("Type", "getStringIndexType", interfaceType.getStringIndexType, assertOptionalTypesEquivalent), parityCase("Type", "getNumberIndexType", interfaceType.getNumberIndexType, assertOptionalTypesEquivalent), parityCase("Type", "getApparentType", interfaceType.getApparentType, assertTypesEquivalent), diff --git a/packages/typescript/test/sync/api.test.ts b/packages/typescript/test/sync/api.test.ts index f048e8ede87e6..115a90508e33a 100644 --- a/packages/typescript/test/sync/api.test.ts +++ b/packages/typescript/test/sync/api.test.ts @@ -3562,6 +3562,11 @@ export class Cache { const nonNullable = project.checker.getNonNullableType(type); assert.strictEqual(type.getNonNullableType(), nonNullable); }); + assertOneRequest(() => { + const negatedType = type.getNegatedType(); + assert.ok(negatedType.flags & TypeFlags.Negated); + assert.strictEqual(project.checker.getNegatedType(type), negatedType); + }); assertOneRequest(() => { const apparentType = type.getApparentType(); assert.strictEqual(project.checker.getApparentType(type), apparentType); diff --git a/tools/scripts/tsc/ast.json b/tools/scripts/tsc/ast.json index a133915a10665..ac0cbb806c7bc 100644 --- a/tools/scripts/tsc/ast.json +++ b/tools/scripts/tsc/ast.json @@ -176,6 +176,7 @@ "ModuleKeyword", "NamespaceKeyword", "NeverKeyword", + "NotKeyword", "OutKeyword", "ReadonlyKeyword", "RequireKeyword", @@ -3555,7 +3556,8 @@ "type": [ "SyntaxKind.KeyOfKeyword", "SyntaxKind.ReadonlyKeyword", - "SyntaxKind.UniqueKeyword" + "SyntaxKind.UniqueKeyword", + "SyntaxKind.NotKeyword" ] }, { diff --git a/tools/scripts/tsc/generate-enums.ts b/tools/scripts/tsc/generate-enums.ts index 757f598fa88c6..c5e4717edea1b 100644 --- a/tools/scripts/tsc/generate-enums.ts +++ b/tools/scripts/tsc/generate-enums.ts @@ -34,7 +34,7 @@ export const enumDefs = [ { name: "SymbolFlags", goPrefix: "SymbolFlags", goFile: "tsc/internal/ast/symbolflags.go", outDir: "packages/typescript/src/enums" }, { name: "CheckFlags", goPrefix: "CheckFlags", goFile: "tsc/internal/ast/checkflags.go", outDir: "packages/typescript/src/enums" }, { name: "SymbolOwnerKind", goPrefix: "SymbolOwnerKind", goFile: "tsc/internal/api/proto.go", outDir: "packages/typescript/src/enums" }, - { name: "TypeFlags", goPrefix: "TypeFlags", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, + { name: "TypeFlags", goPrefix: "TypeFlags", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums", excludeMembers: ["Reserved1", "Reserved2", "Reserved3", "IncludesConstrainedTypeVariable", "IncludesError", "IncludesNegated"] }, { name: "ObjectFlags", goPrefix: "ObjectFlags", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, { name: "SignatureFlags", goPrefix: "SignatureFlags", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, { name: "SignatureKind", goPrefix: "SignatureKind", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, @@ -451,9 +451,9 @@ ${entries.join("\n")} } // A generic function call (unlike a constant conversion) forces Go to evaluate the conversion at -// runtime, truncating uint32-backed flags with a leading bitwise-not the same way JS's 32-bit +// runtime, truncating uint-backed flags with a leading bitwise-not the same way JS's 32-bit // bitwise operators would, instead of rejecting "constant overflows int32" at compile time. -func toInt32[T ~int8 | ~int16 | ~int32 | ~int | ~uint8 | ~uint16 | ~uint32](v T) int32 { +func toInt32[T ~int8 | ~int16 | ~int32 | ~int | ~uint8 | ~uint16 | ~uint32 | ~uint64](v T) int32 { \treturn int32(v) } diff --git a/tsc/internal/api/encoder/decoder_generated.go b/tsc/internal/api/encoder/decoder_generated.go index 612340abfb34c..9f34313b5366a 100644 --- a/tsc/internal/api/encoder/decoder_generated.go +++ b/tsc/internal/api/encoder/decoder_generated.go @@ -198,6 +198,7 @@ func (d *astDecoder) createChildrenNode(kind ast.Kind, data uint32, childIndices ast.KindKeyOfKeyword, ast.KindModuleKeyword, ast.KindNamespaceKeyword, + ast.KindNotKeyword, ast.KindOutKeyword, ast.KindReadonlyKeyword, ast.KindRequireKeyword, @@ -751,6 +752,8 @@ func (d *astDecoder) createChildrenNode(kind ast.Kind, data uint32, childIndices operator = ast.KindReadonlyKeyword case 2: operator = ast.KindUniqueKeyword + case 3: + operator = ast.KindNotKeyword } return d.factory.NewTypeOperatorNode(operator, d.singleChild(childIndices)), nil case ast.KindInferType: diff --git a/tsc/internal/api/encoder/encoder_generated.go b/tsc/internal/api/encoder/encoder_generated.go index 3f695dabfb03a..184499da2e01d 100644 --- a/tsc/internal/api/encoder/encoder_generated.go +++ b/tsc/internal/api/encoder/encoder_generated.go @@ -603,6 +603,8 @@ func getNodeCommonData(node *ast.Node) uint32 { operatorIdx = 1 case ast.KindUniqueKeyword: operatorIdx = 2 + case ast.KindNotKeyword: + operatorIdx = 3 } return operatorIdx << 24 case ast.KindImportAttributes: diff --git a/tsc/internal/api/enum_values_generated.go b/tsc/internal/api/enum_values_generated.go index f90d2892104c0..d7ca0cf3b0026 100644 --- a/tsc/internal/api/enum_values_generated.go +++ b/tsc/internal/api/enum_values_generated.go @@ -133,79 +133,75 @@ func main() { "Snapshot": toInt32(api.SymbolOwnerKindSnapshot), }, "TypeFlags": { - "None": toInt32(checker.TypeFlagsNone), - "Any": toInt32(checker.TypeFlagsAny), - "Unknown": toInt32(checker.TypeFlagsUnknown), - "Undefined": toInt32(checker.TypeFlagsUndefined), - "Null": toInt32(checker.TypeFlagsNull), - "Void": toInt32(checker.TypeFlagsVoid), - "String": toInt32(checker.TypeFlagsString), - "Number": toInt32(checker.TypeFlagsNumber), - "BigInt": toInt32(checker.TypeFlagsBigInt), - "Boolean": toInt32(checker.TypeFlagsBoolean), - "ESSymbol": toInt32(checker.TypeFlagsESSymbol), - "StringLiteral": toInt32(checker.TypeFlagsStringLiteral), - "NumberLiteral": toInt32(checker.TypeFlagsNumberLiteral), - "BigIntLiteral": toInt32(checker.TypeFlagsBigIntLiteral), - "BooleanLiteral": toInt32(checker.TypeFlagsBooleanLiteral), - "UniqueESSymbol": toInt32(checker.TypeFlagsUniqueESSymbol), - "EnumLiteral": toInt32(checker.TypeFlagsEnumLiteral), - "Enum": toInt32(checker.TypeFlagsEnum), - "NonPrimitive": toInt32(checker.TypeFlagsNonPrimitive), - "Never": toInt32(checker.TypeFlagsNever), - "TypeParameter": toInt32(checker.TypeFlagsTypeParameter), - "Object": toInt32(checker.TypeFlagsObject), - "Index": toInt32(checker.TypeFlagsIndex), - "TemplateLiteral": toInt32(checker.TypeFlagsTemplateLiteral), - "StringMapping": toInt32(checker.TypeFlagsStringMapping), - "Substitution": toInt32(checker.TypeFlagsSubstitution), - "IndexedAccess": toInt32(checker.TypeFlagsIndexedAccess), - "Conditional": toInt32(checker.TypeFlagsConditional), - "Union": toInt32(checker.TypeFlagsUnion), - "Intersection": toInt32(checker.TypeFlagsIntersection), - "Reserved1": toInt32(checker.TypeFlagsReserved1), - "Reserved2": toInt32(checker.TypeFlagsReserved2), - "Reserved3": toInt32(checker.TypeFlagsReserved3), - "AnyOrUnknown": toInt32(checker.TypeFlagsAnyOrUnknown), - "Nullable": toInt32(checker.TypeFlagsNullable), - "Literal": toInt32(checker.TypeFlagsLiteral), - "Unit": toInt32(checker.TypeFlagsUnit), - "Freshable": toInt32(checker.TypeFlagsFreshable), - "StringOrNumberLiteral": toInt32(checker.TypeFlagsStringOrNumberLiteral), - "StringOrNumberLiteralOrUnique": toInt32(checker.TypeFlagsStringOrNumberLiteralOrUnique), - "DefinitelyFalsy": toInt32(checker.TypeFlagsDefinitelyFalsy), - "PossiblyFalsy": toInt32(checker.TypeFlagsPossiblyFalsy), - "Intrinsic": toInt32(checker.TypeFlagsIntrinsic), - "StringLike": toInt32(checker.TypeFlagsStringLike), - "NumberLike": toInt32(checker.TypeFlagsNumberLike), - "BigIntLike": toInt32(checker.TypeFlagsBigIntLike), - "BooleanLike": toInt32(checker.TypeFlagsBooleanLike), - "EnumLike": toInt32(checker.TypeFlagsEnumLike), - "ESSymbolLike": toInt32(checker.TypeFlagsESSymbolLike), - "VoidLike": toInt32(checker.TypeFlagsVoidLike), - "Primitive": toInt32(checker.TypeFlagsPrimitive), - "DefinitelyNonNullable": toInt32(checker.TypeFlagsDefinitelyNonNullable), - "DisjointDomains": toInt32(checker.TypeFlagsDisjointDomains), - "UnionOrIntersection": toInt32(checker.TypeFlagsUnionOrIntersection), - "StructuredType": toInt32(checker.TypeFlagsStructuredType), - "TypeVariable": toInt32(checker.TypeFlagsTypeVariable), - "InstantiableNonPrimitive": toInt32(checker.TypeFlagsInstantiableNonPrimitive), - "InstantiablePrimitive": toInt32(checker.TypeFlagsInstantiablePrimitive), - "Instantiable": toInt32(checker.TypeFlagsInstantiable), - "StructuredOrInstantiable": toInt32(checker.TypeFlagsStructuredOrInstantiable), - "ObjectFlagsType": toInt32(checker.TypeFlagsObjectFlagsType), - "Simplifiable": toInt32(checker.TypeFlagsSimplifiable), - "Singleton": toInt32(checker.TypeFlagsSingleton), - "Narrowable": toInt32(checker.TypeFlagsNarrowable), - "IncludesMask": toInt32(checker.TypeFlagsIncludesMask), - "IncludesMissingType": toInt32(checker.TypeFlagsIncludesMissingType), - "IncludesNonWideningType": toInt32(checker.TypeFlagsIncludesNonWideningType), - "IncludesWildcard": toInt32(checker.TypeFlagsIncludesWildcard), - "IncludesEmptyObject": toInt32(checker.TypeFlagsIncludesEmptyObject), - "IncludesInstantiable": toInt32(checker.TypeFlagsIncludesInstantiable), - "IncludesConstrainedTypeVariable": toInt32(checker.TypeFlagsIncludesConstrainedTypeVariable), - "IncludesError": toInt32(checker.TypeFlagsIncludesError), - "NotPrimitiveUnion": toInt32(checker.TypeFlagsNotPrimitiveUnion), + "None": toInt32(checker.TypeFlagsNone), + "Any": toInt32(checker.TypeFlagsAny), + "Unknown": toInt32(checker.TypeFlagsUnknown), + "Undefined": toInt32(checker.TypeFlagsUndefined), + "Null": toInt32(checker.TypeFlagsNull), + "Void": toInt32(checker.TypeFlagsVoid), + "String": toInt32(checker.TypeFlagsString), + "Number": toInt32(checker.TypeFlagsNumber), + "BigInt": toInt32(checker.TypeFlagsBigInt), + "Boolean": toInt32(checker.TypeFlagsBoolean), + "ESSymbol": toInt32(checker.TypeFlagsESSymbol), + "StringLiteral": toInt32(checker.TypeFlagsStringLiteral), + "NumberLiteral": toInt32(checker.TypeFlagsNumberLiteral), + "BigIntLiteral": toInt32(checker.TypeFlagsBigIntLiteral), + "BooleanLiteral": toInt32(checker.TypeFlagsBooleanLiteral), + "UniqueESSymbol": toInt32(checker.TypeFlagsUniqueESSymbol), + "EnumLiteral": toInt32(checker.TypeFlagsEnumLiteral), + "Enum": toInt32(checker.TypeFlagsEnum), + "NonPrimitive": toInt32(checker.TypeFlagsNonPrimitive), + "Never": toInt32(checker.TypeFlagsNever), + "TypeParameter": toInt32(checker.TypeFlagsTypeParameter), + "Object": toInt32(checker.TypeFlagsObject), + "Index": toInt32(checker.TypeFlagsIndex), + "TemplateLiteral": toInt32(checker.TypeFlagsTemplateLiteral), + "StringMapping": toInt32(checker.TypeFlagsStringMapping), + "Substitution": toInt32(checker.TypeFlagsSubstitution), + "Negated": toInt32(checker.TypeFlagsNegated), + "IndexedAccess": toInt32(checker.TypeFlagsIndexedAccess), + "Conditional": toInt32(checker.TypeFlagsConditional), + "Union": toInt32(checker.TypeFlagsUnion), + "Intersection": toInt32(checker.TypeFlagsIntersection), + "AnyOrUnknown": toInt32(checker.TypeFlagsAnyOrUnknown), + "Nullable": toInt32(checker.TypeFlagsNullable), + "Literal": toInt32(checker.TypeFlagsLiteral), + "Unit": toInt32(checker.TypeFlagsUnit), + "Freshable": toInt32(checker.TypeFlagsFreshable), + "StringOrNumberLiteral": toInt32(checker.TypeFlagsStringOrNumberLiteral), + "StringOrNumberLiteralOrUnique": toInt32(checker.TypeFlagsStringOrNumberLiteralOrUnique), + "DefinitelyFalsy": toInt32(checker.TypeFlagsDefinitelyFalsy), + "PossiblyFalsy": toInt32(checker.TypeFlagsPossiblyFalsy), + "Intrinsic": toInt32(checker.TypeFlagsIntrinsic), + "StringLike": toInt32(checker.TypeFlagsStringLike), + "NumberLike": toInt32(checker.TypeFlagsNumberLike), + "BigIntLike": toInt32(checker.TypeFlagsBigIntLike), + "BooleanLike": toInt32(checker.TypeFlagsBooleanLike), + "EnumLike": toInt32(checker.TypeFlagsEnumLike), + "ESSymbolLike": toInt32(checker.TypeFlagsESSymbolLike), + "VoidLike": toInt32(checker.TypeFlagsVoidLike), + "Primitive": toInt32(checker.TypeFlagsPrimitive), + "DefinitelyNonNullable": toInt32(checker.TypeFlagsDefinitelyNonNullable), + "DisjointDomains": toInt32(checker.TypeFlagsDisjointDomains), + "UnionOrIntersection": toInt32(checker.TypeFlagsUnionOrIntersection), + "StructuredType": toInt32(checker.TypeFlagsStructuredType), + "TypeVariable": toInt32(checker.TypeFlagsTypeVariable), + "InstantiableNonPrimitive": toInt32(checker.TypeFlagsInstantiableNonPrimitive), + "InstantiablePrimitive": toInt32(checker.TypeFlagsInstantiablePrimitive), + "Instantiable": toInt32(checker.TypeFlagsInstantiable), + "StructuredOrInstantiable": toInt32(checker.TypeFlagsStructuredOrInstantiable), + "ObjectFlagsType": toInt32(checker.TypeFlagsObjectFlagsType), + "Simplifiable": toInt32(checker.TypeFlagsSimplifiable), + "Singleton": toInt32(checker.TypeFlagsSingleton), + "Narrowable": toInt32(checker.TypeFlagsNarrowable), + "IncludesMask": toInt32(checker.TypeFlagsIncludesMask), + "IncludesMissingType": toInt32(checker.TypeFlagsIncludesMissingType), + "IncludesNonWideningType": toInt32(checker.TypeFlagsIncludesNonWideningType), + "IncludesWildcard": toInt32(checker.TypeFlagsIncludesWildcard), + "IncludesEmptyObject": toInt32(checker.TypeFlagsIncludesEmptyObject), + "IncludesInstantiable": toInt32(checker.TypeFlagsIncludesInstantiable), + "NotPrimitiveUnion": toInt32(checker.TypeFlagsNotPrimitiveUnion), }, "ObjectFlags": { "None": toInt32(checker.ObjectFlagsNone), @@ -256,6 +252,7 @@ func main() { "IsNeverIntersectionComputed": toInt32(checker.ObjectFlagsIsNeverIntersectionComputed), "IsNeverIntersection": toInt32(checker.ObjectFlagsIsNeverIntersection), "IsConstrainedTypeVariable": toInt32(checker.ObjectFlagsIsConstrainedTypeVariable), + "FreshNegated": toInt32(checker.ObjectFlagsFreshNegated), }, "SignatureFlags": { "None": toInt32(checker.SignatureFlagsNone), @@ -478,6 +475,7 @@ func main() { "ModuleKeyword": toInt32(ast.KindModuleKeyword), "NamespaceKeyword": toInt32(ast.KindNamespaceKeyword), "NeverKeyword": toInt32(ast.KindNeverKeyword), + "NotKeyword": toInt32(ast.KindNotKeyword), "OutKeyword": toInt32(ast.KindOutKeyword), "ReadonlyKeyword": toInt32(ast.KindReadonlyKeyword), "RequireKeyword": toInt32(ast.KindRequireKeyword), @@ -1041,8 +1039,8 @@ func main() { } // A generic function call (unlike a constant conversion) forces Go to evaluate the conversion at -// runtime, truncating uint32-backed flags with a leading bitwise-not the same way JS's 32-bit +// runtime, truncating uint-backed flags with a leading bitwise-not the same way JS's 32-bit // bitwise operators would, instead of rejecting "constant overflows int32" at compile time. -func toInt32[T ~int8 | ~int16 | ~int32 | ~int | ~uint8 | ~uint16 | ~uint32](v T) int32 { +func toInt32[T ~int8 | ~int16 | ~int32 | ~int | ~uint8 | ~uint16 | ~uint32 | ~uint64](v T) int32 { return int32(v) } diff --git a/tsc/internal/api/proto.go b/tsc/internal/api/proto.go index c03e7ff85ed46..66bb14e9d4289 100644 --- a/tsc/internal/api/proto.go +++ b/tsc/internal/api/proto.go @@ -190,6 +190,7 @@ const ( MethodGetApparentPropertiesOfType Method = "getApparentPropertiesOfType" MethodGetApparentType Method = "getApparentType" MethodGetReducedType Method = "getReducedType" + MethodGetNegatedType Method = "getNegatedType" MethodGetPropertyOfType Method = "getPropertyOfType" MethodGetTypeOfPropertyOfType Method = "getTypeOfPropertyOfType" MethodGetIndexInfoOfType Method = "getIndexInfoOfType" @@ -713,6 +714,7 @@ var unmarshalers = map[Method]func([]byte) (any, error){ MethodGetApparentPropertiesOfType: unmarshallerFor[GetTypePropertyParams], MethodGetApparentType: unmarshallerFor[GetTypePropertyParams], MethodGetReducedType: unmarshallerFor[GetTypePropertyParams], + MethodGetNegatedType: unmarshallerFor[GetTypePropertyParams], MethodGetPropertyOfType: unmarshallerFor[GetPropertyOfTypeParams], MethodGetTypeOfPropertyOfType: unmarshallerFor[GetPropertyOfTypeParams], MethodGetIndexInfoOfType: unmarshallerFor[GetIndexInfoOfTypeParams], diff --git a/tsc/internal/api/session.go b/tsc/internal/api/session.go index c88ef9a1b3bee..31234996e00c5 100644 --- a/tsc/internal/api/session.go +++ b/tsc/internal/api/session.go @@ -1127,6 +1127,8 @@ func (s *Session) HandleRequest(ctx context.Context, method string, params json. return s.handleGetApparentType(ctx, parsed.(*GetTypePropertyParams)) case string(MethodGetReducedType): return s.handleGetReducedType(ctx, parsed.(*GetTypePropertyParams)) + case string(MethodGetNegatedType): + return s.handleGetNegatedType(ctx, parsed.(*GetTypePropertyParams)) case string(MethodGetPropertyOfType): return s.handleGetPropertyOfType(ctx, parsed.(*GetPropertyOfTypeParams)) case string(MethodGetTypeOfPropertyOfType): @@ -4468,6 +4470,22 @@ func (s *Session) handleGetReducedType(ctx context.Context, params *GetTypePrope return setup.sd.newTypeResponse(setup.projectID, setup.checker.GetReducedType(t), setup.checker), nil } +// handleGetNegatedType returns the negation of a type. +func (s *Session) handleGetNegatedType(ctx context.Context, params *GetTypePropertyParams) (*TypeResponse, error) { + setup, err := s.setupChecker(ctx, params.Snapshot, params.Project) + if err != nil { + return nil, err + } + defer setup.done() + + t, err := setup.resolveTypeHandle(params.Type) + if err != nil { + return nil, err + } + + return setup.sd.newTypeResponse(setup.projectID, setup.checker.GetNegatedType(t), setup.checker), nil +} + // handleGetIndexInfosOfType returns the index infos of a type. // @gen-proto-nullable func (s *Session) handleGetIndexInfosOfType(ctx context.Context, params *CheckerTypeParams) ([]*IndexInfoResponse, error) { diff --git a/tsc/internal/ast/ast_generated.go b/tsc/internal/ast/ast_generated.go index 58aef6d7bc11c..15a54f05a9bc0 100644 --- a/tsc/internal/ast/ast_generated.go +++ b/tsc/internal/ast/ast_generated.go @@ -654,7 +654,7 @@ func (node *Token) Clone(f NodeFactoryCoercible) *Node { func IsToken(node *Node) bool { switch node.Kind { - case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindNumericLiteral, KindBigIntLiteral, KindStringLiteral, KindJsxText, KindJsxTextAllWhiteSpaces, KindRegularExpressionLiteral, KindNoSubstitutionTemplateLiteral, KindTemplateHead, KindTemplateMiddle, KindTemplateTail, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindIdentifier, KindPrivateIdentifier, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFalseKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindImportKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindNullKeyword, KindReturnKeyword, KindSuperKeyword, KindSwitchKeyword, KindThisKeyword, KindThrowKeyword, KindTrueKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindVoidKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAnyKeyword, KindAsyncKeyword, KindAwaitKeyword, KindBooleanKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIntrinsicKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNeverKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindNumberKeyword, KindObjectKeyword, KindSatisfiesKeyword, KindSetKeyword, KindStringKeyword, KindSymbolKeyword, KindTypeKeyword, KindUndefinedKeyword, KindUniqueKeyword, KindUnknownKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindBigIntKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindNumericLiteral, KindBigIntLiteral, KindStringLiteral, KindJsxText, KindJsxTextAllWhiteSpaces, KindRegularExpressionLiteral, KindNoSubstitutionTemplateLiteral, KindTemplateHead, KindTemplateMiddle, KindTemplateTail, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindIdentifier, KindPrivateIdentifier, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFalseKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindImportKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindNullKeyword, KindReturnKeyword, KindSuperKeyword, KindSwitchKeyword, KindThisKeyword, KindThrowKeyword, KindTrueKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindVoidKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAnyKeyword, KindAsyncKeyword, KindAwaitKeyword, KindBooleanKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIntrinsicKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNeverKeyword, KindNotKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindNumberKeyword, KindObjectKeyword, KindSatisfiesKeyword, KindSetKeyword, KindStringKeyword, KindSymbolKeyword, KindTypeKeyword, KindUndefinedKeyword, KindUniqueKeyword, KindUnknownKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindBigIntKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: return true } return false @@ -9460,7 +9460,7 @@ func (n *Node) Clone(f NodeFactoryCoercible) *Node { switch n.Kind { case kindFlowSwitchClauseData, kindFlowReduceLabelData: return nil - case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNotKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: return (*Token)(unsafe.Pointer(n)).Clone(f) case KindNumericLiteral: return (*NumericLiteral)(unsafe.Pointer(n)).Clone(f) @@ -9857,7 +9857,7 @@ func (n *Node) SubtreeFacts() SubtreeFacts { switch n.Kind { case kindFlowSwitchClauseData, kindFlowReduceLabelData: return SubtreeFactsNone - case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNotKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: return n.computeSubtreeFacts() case KindNumericLiteral: return n.computeSubtreeFacts() @@ -10248,7 +10248,7 @@ func (n *Node) SubtreeFacts() SubtreeFacts { func (n *Node) computeSubtreeFacts() SubtreeFacts { switch n.Kind { - case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNotKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: return (*Token)(unsafe.Pointer(n)).computeSubtreeFacts() case KindNumericLiteral: return (*NumericLiteral)(unsafe.Pointer(n)).computeSubtreeFacts() @@ -10639,7 +10639,7 @@ func (n *Node) computeSubtreeFacts() SubtreeFacts { func (n *Node) propagateSubtreeFacts() SubtreeFacts { switch n.Kind { - case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNotKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: return (*Token)(unsafe.Pointer(n)).propagateSubtreeFacts() case KindNumericLiteral: return (*NumericLiteral)(unsafe.Pointer(n)).propagateSubtreeFacts() @@ -12170,7 +12170,7 @@ var ( func (n *Node) AsToken() *Token { switch n.Kind { - case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: + case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindReturnKeyword, KindSwitchKeyword, KindThrowKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAsyncKeyword, KindAwaitKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNotKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindSatisfiesKeyword, KindSetKeyword, KindTypeKeyword, KindUniqueKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword, KindSourceKeyword: default: panic("Invalid node cast to Token") } diff --git a/tsc/internal/ast/kind_generated.go b/tsc/internal/ast/kind_generated.go index 23f2c9ccf9de6..1ab572d0664f1 100644 --- a/tsc/internal/ast/kind_generated.go +++ b/tsc/internal/ast/kind_generated.go @@ -163,6 +163,7 @@ const ( KindModuleKeyword KindNamespaceKeyword KindNeverKeyword + KindNotKeyword KindOutKeyword KindReadonlyKeyword KindRequireKeyword @@ -430,11 +431,11 @@ type ( LiteralSyntaxKind = Kind // KindNumericLiteral | KindBigIntLiteral | KindStringLiteral | KindJsxText | KindJsxTextAllWhiteSpaces | KindRegularExpressionLiteral | KindNoSubstitutionTemplateLiteral PseudoLiteralSyntaxKind = Kind // KindTemplateHead | KindTemplateMiddle | KindTemplateTail PunctuationSyntaxKind = Kind // KindOpenBraceToken | KindCloseBraceToken | KindOpenParenToken | KindCloseParenToken | KindOpenBracketToken | KindCloseBracketToken | KindDotToken | KindDotDotDotToken | KindSemicolonToken | KindCommaToken | KindQuestionDotToken | KindLessThanToken | KindLessThanSlashToken | KindGreaterThanToken | KindLessThanEqualsToken | KindGreaterThanEqualsToken | KindEqualsEqualsToken | KindExclamationEqualsToken | KindEqualsEqualsEqualsToken | KindExclamationEqualsEqualsToken | KindEqualsGreaterThanToken | KindPlusToken | KindMinusToken | KindAsteriskToken | KindAsteriskAsteriskToken | KindSlashToken | KindPercentToken | KindPlusPlusToken | KindMinusMinusToken | KindLessThanLessThanToken | KindGreaterThanGreaterThanToken | KindGreaterThanGreaterThanGreaterThanToken | KindAmpersandToken | KindBarToken | KindCaretToken | KindExclamationToken | KindTildeToken | KindAmpersandAmpersandToken | KindBarBarToken | KindQuestionToken | KindColonToken | KindAtToken | KindQuestionQuestionToken | KindBacktickToken | KindHashToken | KindEqualsToken | KindPlusEqualsToken | KindMinusEqualsToken | KindAsteriskEqualsToken | KindAsteriskAsteriskEqualsToken | KindSlashEqualsToken | KindPercentEqualsToken | KindLessThanLessThanEqualsToken | KindGreaterThanGreaterThanEqualsToken | KindGreaterThanGreaterThanGreaterThanEqualsToken | KindAmpersandEqualsToken | KindBarEqualsToken | KindBarBarEqualsToken | KindAmpersandAmpersandEqualsToken | KindQuestionQuestionEqualsToken | KindCaretEqualsToken - KeywordSyntaxKind = Kind // KindBreakKeyword | KindCaseKeyword | KindCatchKeyword | KindClassKeyword | KindConstKeyword | KindContinueKeyword | KindDebuggerKeyword | KindDefaultKeyword | KindDeleteKeyword | KindDoKeyword | KindElseKeyword | KindEnumKeyword | KindExportKeyword | KindExtendsKeyword | KindFalseKeyword | KindFinallyKeyword | KindForKeyword | KindFunctionKeyword | KindIfKeyword | KindImportKeyword | KindInKeyword | KindInstanceOfKeyword | KindNewKeyword | KindNullKeyword | KindReturnKeyword | KindSuperKeyword | KindSwitchKeyword | KindThisKeyword | KindThrowKeyword | KindTrueKeyword | KindTryKeyword | KindTypeOfKeyword | KindVarKeyword | KindVoidKeyword | KindWhileKeyword | KindWithKeyword | KindImplementsKeyword | KindInterfaceKeyword | KindLetKeyword | KindPackageKeyword | KindPrivateKeyword | KindProtectedKeyword | KindPublicKeyword | KindStaticKeyword | KindYieldKeyword | KindAbstractKeyword | KindAccessorKeyword | KindAsKeyword | KindAssertsKeyword | KindAssertKeyword | KindAnyKeyword | KindAsyncKeyword | KindAwaitKeyword | KindBooleanKeyword | KindConstructorKeyword | KindDeclareKeyword | KindGetKeyword | KindImmediateKeyword | KindInferKeyword | KindIntrinsicKeyword | KindIsKeyword | KindKeyOfKeyword | KindModuleKeyword | KindNamespaceKeyword | KindNeverKeyword | KindOutKeyword | KindReadonlyKeyword | KindRequireKeyword | KindNumberKeyword | KindObjectKeyword | KindSatisfiesKeyword | KindSetKeyword | KindStringKeyword | KindSymbolKeyword | KindTypeKeyword | KindUndefinedKeyword | KindUniqueKeyword | KindUnknownKeyword | KindUsingKeyword | KindFromKeyword | KindGlobalKeyword | KindBigIntKeyword | KindOverrideKeyword | KindOfKeyword | KindDeferKeyword | KindSourceKeyword + KeywordSyntaxKind = Kind // KindBreakKeyword | KindCaseKeyword | KindCatchKeyword | KindClassKeyword | KindConstKeyword | KindContinueKeyword | KindDebuggerKeyword | KindDefaultKeyword | KindDeleteKeyword | KindDoKeyword | KindElseKeyword | KindEnumKeyword | KindExportKeyword | KindExtendsKeyword | KindFalseKeyword | KindFinallyKeyword | KindForKeyword | KindFunctionKeyword | KindIfKeyword | KindImportKeyword | KindInKeyword | KindInstanceOfKeyword | KindNewKeyword | KindNullKeyword | KindReturnKeyword | KindSuperKeyword | KindSwitchKeyword | KindThisKeyword | KindThrowKeyword | KindTrueKeyword | KindTryKeyword | KindTypeOfKeyword | KindVarKeyword | KindVoidKeyword | KindWhileKeyword | KindWithKeyword | KindImplementsKeyword | KindInterfaceKeyword | KindLetKeyword | KindPackageKeyword | KindPrivateKeyword | KindProtectedKeyword | KindPublicKeyword | KindStaticKeyword | KindYieldKeyword | KindAbstractKeyword | KindAccessorKeyword | KindAsKeyword | KindAssertsKeyword | KindAssertKeyword | KindAnyKeyword | KindAsyncKeyword | KindAwaitKeyword | KindBooleanKeyword | KindConstructorKeyword | KindDeclareKeyword | KindGetKeyword | KindImmediateKeyword | KindInferKeyword | KindIntrinsicKeyword | KindIsKeyword | KindKeyOfKeyword | KindModuleKeyword | KindNamespaceKeyword | KindNeverKeyword | KindNotKeyword | KindOutKeyword | KindReadonlyKeyword | KindRequireKeyword | KindNumberKeyword | KindObjectKeyword | KindSatisfiesKeyword | KindSetKeyword | KindStringKeyword | KindSymbolKeyword | KindTypeKeyword | KindUndefinedKeyword | KindUniqueKeyword | KindUnknownKeyword | KindUsingKeyword | KindFromKeyword | KindGlobalKeyword | KindBigIntKeyword | KindOverrideKeyword | KindOfKeyword | KindDeferKeyword | KindSourceKeyword ModifierSyntaxKind = Kind // KindAbstractKeyword | KindAccessorKeyword | KindAsyncKeyword | KindConstKeyword | KindDeclareKeyword | KindDefaultKeyword | KindExportKeyword | KindInKeyword | KindPrivateKeyword | KindProtectedKeyword | KindPublicKeyword | KindReadonlyKeyword | KindOutKeyword | KindOverrideKeyword | KindStaticKeyword KeywordTypeSyntaxKind = Kind // KindAnyKeyword | KindBigIntKeyword | KindBooleanKeyword | KindIntrinsicKeyword | KindNeverKeyword | KindNumberKeyword | KindObjectKeyword | KindStringKeyword | KindSymbolKeyword | KindUndefinedKeyword | KindUnknownKeyword | KindVoidKeyword KeywordExpressionSyntaxKind = Kind // KindNullKeyword | KindTrueKeyword | KindFalseKeyword | KindThisKeyword | KindSuperKeyword | KindImportKeyword - TokenSyntaxKind = Kind // KindUnknown | KindEndOfFile | KindSingleLineCommentTrivia | KindMultiLineCommentTrivia | KindNewLineTrivia | KindWhitespaceTrivia | KindConflictMarkerTrivia | KindNonTextFileMarkerTrivia | KindNumericLiteral | KindBigIntLiteral | KindStringLiteral | KindJsxText | KindJsxTextAllWhiteSpaces | KindRegularExpressionLiteral | KindNoSubstitutionTemplateLiteral | KindTemplateHead | KindTemplateMiddle | KindTemplateTail | KindOpenBraceToken | KindCloseBraceToken | KindOpenParenToken | KindCloseParenToken | KindOpenBracketToken | KindCloseBracketToken | KindDotToken | KindDotDotDotToken | KindSemicolonToken | KindCommaToken | KindQuestionDotToken | KindLessThanToken | KindLessThanSlashToken | KindGreaterThanToken | KindLessThanEqualsToken | KindGreaterThanEqualsToken | KindEqualsEqualsToken | KindExclamationEqualsToken | KindEqualsEqualsEqualsToken | KindExclamationEqualsEqualsToken | KindEqualsGreaterThanToken | KindPlusToken | KindMinusToken | KindAsteriskToken | KindAsteriskAsteriskToken | KindSlashToken | KindPercentToken | KindPlusPlusToken | KindMinusMinusToken | KindLessThanLessThanToken | KindGreaterThanGreaterThanToken | KindGreaterThanGreaterThanGreaterThanToken | KindAmpersandToken | KindBarToken | KindCaretToken | KindExclamationToken | KindTildeToken | KindAmpersandAmpersandToken | KindBarBarToken | KindQuestionToken | KindColonToken | KindAtToken | KindQuestionQuestionToken | KindBacktickToken | KindHashToken | KindEqualsToken | KindPlusEqualsToken | KindMinusEqualsToken | KindAsteriskEqualsToken | KindAsteriskAsteriskEqualsToken | KindSlashEqualsToken | KindPercentEqualsToken | KindLessThanLessThanEqualsToken | KindGreaterThanGreaterThanEqualsToken | KindGreaterThanGreaterThanGreaterThanEqualsToken | KindAmpersandEqualsToken | KindBarEqualsToken | KindBarBarEqualsToken | KindAmpersandAmpersandEqualsToken | KindQuestionQuestionEqualsToken | KindCaretEqualsToken | KindIdentifier | KindPrivateIdentifier | KindJSDocCommentTextToken | KindBreakKeyword | KindCaseKeyword | KindCatchKeyword | KindClassKeyword | KindConstKeyword | KindContinueKeyword | KindDebuggerKeyword | KindDefaultKeyword | KindDeleteKeyword | KindDoKeyword | KindElseKeyword | KindEnumKeyword | KindExportKeyword | KindExtendsKeyword | KindFalseKeyword | KindFinallyKeyword | KindForKeyword | KindFunctionKeyword | KindIfKeyword | KindImportKeyword | KindInKeyword | KindInstanceOfKeyword | KindNewKeyword | KindNullKeyword | KindReturnKeyword | KindSuperKeyword | KindSwitchKeyword | KindThisKeyword | KindThrowKeyword | KindTrueKeyword | KindTryKeyword | KindTypeOfKeyword | KindVarKeyword | KindVoidKeyword | KindWhileKeyword | KindWithKeyword | KindImplementsKeyword | KindInterfaceKeyword | KindLetKeyword | KindPackageKeyword | KindPrivateKeyword | KindProtectedKeyword | KindPublicKeyword | KindStaticKeyword | KindYieldKeyword | KindAbstractKeyword | KindAccessorKeyword | KindAsKeyword | KindAssertsKeyword | KindAssertKeyword | KindAnyKeyword | KindAsyncKeyword | KindAwaitKeyword | KindBooleanKeyword | KindConstructorKeyword | KindDeclareKeyword | KindGetKeyword | KindImmediateKeyword | KindInferKeyword | KindIntrinsicKeyword | KindIsKeyword | KindKeyOfKeyword | KindModuleKeyword | KindNamespaceKeyword | KindNeverKeyword | KindOutKeyword | KindReadonlyKeyword | KindRequireKeyword | KindNumberKeyword | KindObjectKeyword | KindSatisfiesKeyword | KindSetKeyword | KindStringKeyword | KindSymbolKeyword | KindTypeKeyword | KindUndefinedKeyword | KindUniqueKeyword | KindUnknownKeyword | KindUsingKeyword | KindFromKeyword | KindGlobalKeyword | KindBigIntKeyword | KindOverrideKeyword | KindOfKeyword | KindDeferKeyword | KindSourceKeyword + TokenSyntaxKind = Kind // KindUnknown | KindEndOfFile | KindSingleLineCommentTrivia | KindMultiLineCommentTrivia | KindNewLineTrivia | KindWhitespaceTrivia | KindConflictMarkerTrivia | KindNonTextFileMarkerTrivia | KindNumericLiteral | KindBigIntLiteral | KindStringLiteral | KindJsxText | KindJsxTextAllWhiteSpaces | KindRegularExpressionLiteral | KindNoSubstitutionTemplateLiteral | KindTemplateHead | KindTemplateMiddle | KindTemplateTail | KindOpenBraceToken | KindCloseBraceToken | KindOpenParenToken | KindCloseParenToken | KindOpenBracketToken | KindCloseBracketToken | KindDotToken | KindDotDotDotToken | KindSemicolonToken | KindCommaToken | KindQuestionDotToken | KindLessThanToken | KindLessThanSlashToken | KindGreaterThanToken | KindLessThanEqualsToken | KindGreaterThanEqualsToken | KindEqualsEqualsToken | KindExclamationEqualsToken | KindEqualsEqualsEqualsToken | KindExclamationEqualsEqualsToken | KindEqualsGreaterThanToken | KindPlusToken | KindMinusToken | KindAsteriskToken | KindAsteriskAsteriskToken | KindSlashToken | KindPercentToken | KindPlusPlusToken | KindMinusMinusToken | KindLessThanLessThanToken | KindGreaterThanGreaterThanToken | KindGreaterThanGreaterThanGreaterThanToken | KindAmpersandToken | KindBarToken | KindCaretToken | KindExclamationToken | KindTildeToken | KindAmpersandAmpersandToken | KindBarBarToken | KindQuestionToken | KindColonToken | KindAtToken | KindQuestionQuestionToken | KindBacktickToken | KindHashToken | KindEqualsToken | KindPlusEqualsToken | KindMinusEqualsToken | KindAsteriskEqualsToken | KindAsteriskAsteriskEqualsToken | KindSlashEqualsToken | KindPercentEqualsToken | KindLessThanLessThanEqualsToken | KindGreaterThanGreaterThanEqualsToken | KindGreaterThanGreaterThanGreaterThanEqualsToken | KindAmpersandEqualsToken | KindBarEqualsToken | KindBarBarEqualsToken | KindAmpersandAmpersandEqualsToken | KindQuestionQuestionEqualsToken | KindCaretEqualsToken | KindIdentifier | KindPrivateIdentifier | KindJSDocCommentTextToken | KindBreakKeyword | KindCaseKeyword | KindCatchKeyword | KindClassKeyword | KindConstKeyword | KindContinueKeyword | KindDebuggerKeyword | KindDefaultKeyword | KindDeleteKeyword | KindDoKeyword | KindElseKeyword | KindEnumKeyword | KindExportKeyword | KindExtendsKeyword | KindFalseKeyword | KindFinallyKeyword | KindForKeyword | KindFunctionKeyword | KindIfKeyword | KindImportKeyword | KindInKeyword | KindInstanceOfKeyword | KindNewKeyword | KindNullKeyword | KindReturnKeyword | KindSuperKeyword | KindSwitchKeyword | KindThisKeyword | KindThrowKeyword | KindTrueKeyword | KindTryKeyword | KindTypeOfKeyword | KindVarKeyword | KindVoidKeyword | KindWhileKeyword | KindWithKeyword | KindImplementsKeyword | KindInterfaceKeyword | KindLetKeyword | KindPackageKeyword | KindPrivateKeyword | KindProtectedKeyword | KindPublicKeyword | KindStaticKeyword | KindYieldKeyword | KindAbstractKeyword | KindAccessorKeyword | KindAsKeyword | KindAssertsKeyword | KindAssertKeyword | KindAnyKeyword | KindAsyncKeyword | KindAwaitKeyword | KindBooleanKeyword | KindConstructorKeyword | KindDeclareKeyword | KindGetKeyword | KindImmediateKeyword | KindInferKeyword | KindIntrinsicKeyword | KindIsKeyword | KindKeyOfKeyword | KindModuleKeyword | KindNamespaceKeyword | KindNeverKeyword | KindNotKeyword | KindOutKeyword | KindReadonlyKeyword | KindRequireKeyword | KindNumberKeyword | KindObjectKeyword | KindSatisfiesKeyword | KindSetKeyword | KindStringKeyword | KindSymbolKeyword | KindTypeKeyword | KindUndefinedKeyword | KindUniqueKeyword | KindUnknownKeyword | KindUsingKeyword | KindFromKeyword | KindGlobalKeyword | KindBigIntKeyword | KindOverrideKeyword | KindOfKeyword | KindDeferKeyword | KindSourceKeyword JsxTokenSyntaxKind = Kind // KindLessThanSlashToken | KindEndOfFile | KindConflictMarkerTrivia | KindJsxText | KindJsxTextAllWhiteSpaces | KindOpenBraceToken | KindLessThanToken JSDocNodeSyntaxKind = Kind // KindJSDocTypeExpression | KindJSDocNameReference | KindJSDocAllType | KindJSDocNullableType | KindJSDocNonNullableType | KindJSDocOptionalType | KindJSDocVariadicType | KindJSDoc | KindJSDocText | KindJSDocTypeLiteral | KindJSDocSignature | KindJSDocLink | KindJSDocLinkCode | KindJSDocLinkPlain | KindJSDocUnknownTag | KindJSDocAugmentsTag | KindJSDocImplementsTag | KindJSDocDeprecatedTag | KindJSDocPublicTag | KindJSDocPrivateTag | KindJSDocProtectedTag | KindJSDocReadonlyTag | KindJSDocOverrideTag | KindJSDocCallbackTag | KindJSDocOverloadTag | KindJSDocParameterTag | KindJSDocReturnTag | KindJSDocThisTag | KindJSDocTypeTag | KindJSDocTemplateTag | KindJSDocTypedefTag | KindJSDocSeeTag | KindJSDocPropertyTag | KindJSDocThrowsTag | KindJSDocSatisfiesTag | KindJSDocImportTag ImportPhaseModifierSyntaxKind = Kind // KindTypeKeyword | KindDeferKeyword | KindSourceKeyword diff --git a/tsc/internal/ast/kind_stringer_generated.go b/tsc/internal/ast/kind_stringer_generated.go index 5ef080dd0350e..618f647dc6f31 100644 --- a/tsc/internal/ast/kind_stringer_generated.go +++ b/tsc/internal/ast/kind_stringer_generated.go @@ -8,8 +8,8 @@ func _() { // An "invalid array index" compiler error signifies that the constant values have changed. // Re-run the stringer command to generate them again. var x [1]struct{} - _ = x[kindFlowSwitchClauseData-353] - _ = x[kindFlowReduceLabelData-354] + _ = x[kindFlowSwitchClauseData-354] + _ = x[kindFlowReduceLabelData-355] _ = x[KindUnknown-0] _ = x[KindEndOfFile-1] _ = x[KindSingleLineCommentTrivia-2] @@ -157,217 +157,218 @@ func _() { _ = x[KindModuleKeyword-144] _ = x[KindNamespaceKeyword-145] _ = x[KindNeverKeyword-146] - _ = x[KindOutKeyword-147] - _ = x[KindReadonlyKeyword-148] - _ = x[KindRequireKeyword-149] - _ = x[KindNumberKeyword-150] - _ = x[KindObjectKeyword-151] - _ = x[KindSatisfiesKeyword-152] - _ = x[KindSetKeyword-153] - _ = x[KindStringKeyword-154] - _ = x[KindSymbolKeyword-155] - _ = x[KindTypeKeyword-156] - _ = x[KindUndefinedKeyword-157] - _ = x[KindUniqueKeyword-158] - _ = x[KindUnknownKeyword-159] - _ = x[KindUsingKeyword-160] - _ = x[KindFromKeyword-161] - _ = x[KindGlobalKeyword-162] - _ = x[KindBigIntKeyword-163] - _ = x[KindOverrideKeyword-164] - _ = x[KindOfKeyword-165] - _ = x[KindDeferKeyword-166] - _ = x[KindSourceKeyword-167] - _ = x[KindQualifiedName-168] - _ = x[KindComputedPropertyName-169] - _ = x[KindTypeParameter-170] - _ = x[KindParameter-171] - _ = x[KindDecorator-172] - _ = x[KindPropertySignature-173] - _ = x[KindPropertyDeclaration-174] - _ = x[KindMethodSignature-175] - _ = x[KindMethodDeclaration-176] - _ = x[KindClassStaticBlockDeclaration-177] - _ = x[KindConstructor-178] - _ = x[KindGetAccessor-179] - _ = x[KindSetAccessor-180] - _ = x[KindCallSignature-181] - _ = x[KindConstructSignature-182] - _ = x[KindIndexSignature-183] - _ = x[KindTypePredicate-184] - _ = x[KindTypeReference-185] - _ = x[KindFunctionType-186] - _ = x[KindConstructorType-187] - _ = x[KindTypeQuery-188] - _ = x[KindTypeLiteral-189] - _ = x[KindArrayType-190] - _ = x[KindTupleType-191] - _ = x[KindOptionalType-192] - _ = x[KindRestType-193] - _ = x[KindUnionType-194] - _ = x[KindIntersectionType-195] - _ = x[KindConditionalType-196] - _ = x[KindInferType-197] - _ = x[KindParenthesizedType-198] - _ = x[KindThisType-199] - _ = x[KindTypeOperator-200] - _ = x[KindIndexedAccessType-201] - _ = x[KindMappedType-202] - _ = x[KindLiteralType-203] - _ = x[KindNamedTupleMember-204] - _ = x[KindTemplateLiteralType-205] - _ = x[KindTemplateLiteralTypeSpan-206] - _ = x[KindImportType-207] - _ = x[KindObjectBindingPattern-208] - _ = x[KindArrayBindingPattern-209] - _ = x[KindBindingElement-210] - _ = x[KindArrayLiteralExpression-211] - _ = x[KindObjectLiteralExpression-212] - _ = x[KindPropertyAccessExpression-213] - _ = x[KindElementAccessExpression-214] - _ = x[KindCallExpression-215] - _ = x[KindNewExpression-216] - _ = x[KindTaggedTemplateExpression-217] - _ = x[KindTypeAssertionExpression-218] - _ = x[KindParenthesizedExpression-219] - _ = x[KindFunctionExpression-220] - _ = x[KindArrowFunction-221] - _ = x[KindDeleteExpression-222] - _ = x[KindTypeOfExpression-223] - _ = x[KindVoidExpression-224] - _ = x[KindAwaitExpression-225] - _ = x[KindPrefixUnaryExpression-226] - _ = x[KindPostfixUnaryExpression-227] - _ = x[KindBinaryExpression-228] - _ = x[KindConditionalExpression-229] - _ = x[KindTemplateExpression-230] - _ = x[KindYieldExpression-231] - _ = x[KindSpreadElement-232] - _ = x[KindClassExpression-233] - _ = x[KindOmittedExpression-234] - _ = x[KindExpressionWithTypeArguments-235] - _ = x[KindAsExpression-236] - _ = x[KindNonNullExpression-237] - _ = x[KindMetaProperty-238] - _ = x[KindSyntheticExpression-239] - _ = x[KindSatisfiesExpression-240] - _ = x[KindTemplateSpan-241] - _ = x[KindSemicolonClassElement-242] - _ = x[KindBlock-243] - _ = x[KindEmptyStatement-244] - _ = x[KindVariableStatement-245] - _ = x[KindExpressionStatement-246] - _ = x[KindIfStatement-247] - _ = x[KindDoStatement-248] - _ = x[KindWhileStatement-249] - _ = x[KindForStatement-250] - _ = x[KindForInStatement-251] - _ = x[KindForOfStatement-252] - _ = x[KindContinueStatement-253] - _ = x[KindBreakStatement-254] - _ = x[KindReturnStatement-255] - _ = x[KindWithStatement-256] - _ = x[KindSwitchStatement-257] - _ = x[KindLabeledStatement-258] - _ = x[KindThrowStatement-259] - _ = x[KindTryStatement-260] - _ = x[KindDebuggerStatement-261] - _ = x[KindVariableDeclaration-262] - _ = x[KindVariableDeclarationList-263] - _ = x[KindFunctionDeclaration-264] - _ = x[KindClassDeclaration-265] - _ = x[KindInterfaceDeclaration-266] - _ = x[KindTypeAliasDeclaration-267] - _ = x[KindEnumDeclaration-268] - _ = x[KindModuleDeclaration-269] - _ = x[KindModuleBlock-270] - _ = x[KindCaseBlock-271] - _ = x[KindNamespaceExportDeclaration-272] - _ = x[KindImportEqualsDeclaration-273] - _ = x[KindImportDeclaration-274] - _ = x[KindImportClause-275] - _ = x[KindNamespaceImport-276] - _ = x[KindNamedImports-277] - _ = x[KindImportSpecifier-278] - _ = x[KindExportAssignment-279] - _ = x[KindExportDeclaration-280] - _ = x[KindNamedExports-281] - _ = x[KindNamespaceExport-282] - _ = x[KindExportSpecifier-283] - _ = x[KindMissingDeclaration-284] - _ = x[KindExternalModuleReference-285] - _ = x[KindJsxElement-286] - _ = x[KindJsxSelfClosingElement-287] - _ = x[KindJsxOpeningElement-288] - _ = x[KindJsxClosingElement-289] - _ = x[KindJsxFragment-290] - _ = x[KindJsxOpeningFragment-291] - _ = x[KindJsxClosingFragment-292] - _ = x[KindJsxAttribute-293] - _ = x[KindJsxAttributes-294] - _ = x[KindJsxSpreadAttribute-295] - _ = x[KindJsxExpression-296] - _ = x[KindJsxNamespacedName-297] - _ = x[KindCaseClause-298] - _ = x[KindDefaultClause-299] - _ = x[KindHeritageClause-300] - _ = x[KindCatchClause-301] - _ = x[KindImportAttributes-302] - _ = x[KindImportAttribute-303] - _ = x[KindPropertyAssignment-304] - _ = x[KindShorthandPropertyAssignment-305] - _ = x[KindSpreadAssignment-306] - _ = x[KindEnumMember-307] - _ = x[KindSourceFile-308] - _ = x[KindJSDocTypeExpression-309] - _ = x[KindJSDocNameReference-310] - _ = x[KindJSDocAllType-311] - _ = x[KindJSDocNullableType-312] - _ = x[KindJSDocNonNullableType-313] - _ = x[KindJSDocOptionalType-314] - _ = x[KindJSDocVariadicType-315] - _ = x[KindJSDoc-316] - _ = x[KindJSDocText-317] - _ = x[KindJSDocTypeLiteral-318] - _ = x[KindJSDocSignature-319] - _ = x[KindJSDocLink-320] - _ = x[KindJSDocLinkCode-321] - _ = x[KindJSDocLinkPlain-322] - _ = x[KindJSDocUnknownTag-323] - _ = x[KindJSDocAugmentsTag-324] - _ = x[KindJSDocImplementsTag-325] - _ = x[KindJSDocDeprecatedTag-326] - _ = x[KindJSDocPublicTag-327] - _ = x[KindJSDocPrivateTag-328] - _ = x[KindJSDocProtectedTag-329] - _ = x[KindJSDocReadonlyTag-330] - _ = x[KindJSDocOverrideTag-331] - _ = x[KindJSDocCallbackTag-332] - _ = x[KindJSDocOverloadTag-333] - _ = x[KindJSDocParameterTag-334] - _ = x[KindJSDocReturnTag-335] - _ = x[KindJSDocThisTag-336] - _ = x[KindJSDocTypeTag-337] - _ = x[KindJSDocTemplateTag-338] - _ = x[KindJSDocTypedefTag-339] - _ = x[KindJSDocSeeTag-340] - _ = x[KindJSDocPropertyTag-341] - _ = x[KindJSDocThrowsTag-342] - _ = x[KindJSDocSatisfiesTag-343] - _ = x[KindJSDocImportTag-344] - _ = x[KindSyntaxList-345] - _ = x[KindJSTypeAliasDeclaration-346] - _ = x[KindJSImportDeclaration-347] - _ = x[KindNotEmittedStatement-348] - _ = x[KindPartiallyEmittedExpression-349] - _ = x[KindSyntheticReferenceExpression-350] - _ = x[KindNotEmittedTypeElement-351] - _ = x[KindCount-352] + _ = x[KindNotKeyword-147] + _ = x[KindOutKeyword-148] + _ = x[KindReadonlyKeyword-149] + _ = x[KindRequireKeyword-150] + _ = x[KindNumberKeyword-151] + _ = x[KindObjectKeyword-152] + _ = x[KindSatisfiesKeyword-153] + _ = x[KindSetKeyword-154] + _ = x[KindStringKeyword-155] + _ = x[KindSymbolKeyword-156] + _ = x[KindTypeKeyword-157] + _ = x[KindUndefinedKeyword-158] + _ = x[KindUniqueKeyword-159] + _ = x[KindUnknownKeyword-160] + _ = x[KindUsingKeyword-161] + _ = x[KindFromKeyword-162] + _ = x[KindGlobalKeyword-163] + _ = x[KindBigIntKeyword-164] + _ = x[KindOverrideKeyword-165] + _ = x[KindOfKeyword-166] + _ = x[KindDeferKeyword-167] + _ = x[KindSourceKeyword-168] + _ = x[KindQualifiedName-169] + _ = x[KindComputedPropertyName-170] + _ = x[KindTypeParameter-171] + _ = x[KindParameter-172] + _ = x[KindDecorator-173] + _ = x[KindPropertySignature-174] + _ = x[KindPropertyDeclaration-175] + _ = x[KindMethodSignature-176] + _ = x[KindMethodDeclaration-177] + _ = x[KindClassStaticBlockDeclaration-178] + _ = x[KindConstructor-179] + _ = x[KindGetAccessor-180] + _ = x[KindSetAccessor-181] + _ = x[KindCallSignature-182] + _ = x[KindConstructSignature-183] + _ = x[KindIndexSignature-184] + _ = x[KindTypePredicate-185] + _ = x[KindTypeReference-186] + _ = x[KindFunctionType-187] + _ = x[KindConstructorType-188] + _ = x[KindTypeQuery-189] + _ = x[KindTypeLiteral-190] + _ = x[KindArrayType-191] + _ = x[KindTupleType-192] + _ = x[KindOptionalType-193] + _ = x[KindRestType-194] + _ = x[KindUnionType-195] + _ = x[KindIntersectionType-196] + _ = x[KindConditionalType-197] + _ = x[KindInferType-198] + _ = x[KindParenthesizedType-199] + _ = x[KindThisType-200] + _ = x[KindTypeOperator-201] + _ = x[KindIndexedAccessType-202] + _ = x[KindMappedType-203] + _ = x[KindLiteralType-204] + _ = x[KindNamedTupleMember-205] + _ = x[KindTemplateLiteralType-206] + _ = x[KindTemplateLiteralTypeSpan-207] + _ = x[KindImportType-208] + _ = x[KindObjectBindingPattern-209] + _ = x[KindArrayBindingPattern-210] + _ = x[KindBindingElement-211] + _ = x[KindArrayLiteralExpression-212] + _ = x[KindObjectLiteralExpression-213] + _ = x[KindPropertyAccessExpression-214] + _ = x[KindElementAccessExpression-215] + _ = x[KindCallExpression-216] + _ = x[KindNewExpression-217] + _ = x[KindTaggedTemplateExpression-218] + _ = x[KindTypeAssertionExpression-219] + _ = x[KindParenthesizedExpression-220] + _ = x[KindFunctionExpression-221] + _ = x[KindArrowFunction-222] + _ = x[KindDeleteExpression-223] + _ = x[KindTypeOfExpression-224] + _ = x[KindVoidExpression-225] + _ = x[KindAwaitExpression-226] + _ = x[KindPrefixUnaryExpression-227] + _ = x[KindPostfixUnaryExpression-228] + _ = x[KindBinaryExpression-229] + _ = x[KindConditionalExpression-230] + _ = x[KindTemplateExpression-231] + _ = x[KindYieldExpression-232] + _ = x[KindSpreadElement-233] + _ = x[KindClassExpression-234] + _ = x[KindOmittedExpression-235] + _ = x[KindExpressionWithTypeArguments-236] + _ = x[KindAsExpression-237] + _ = x[KindNonNullExpression-238] + _ = x[KindMetaProperty-239] + _ = x[KindSyntheticExpression-240] + _ = x[KindSatisfiesExpression-241] + _ = x[KindTemplateSpan-242] + _ = x[KindSemicolonClassElement-243] + _ = x[KindBlock-244] + _ = x[KindEmptyStatement-245] + _ = x[KindVariableStatement-246] + _ = x[KindExpressionStatement-247] + _ = x[KindIfStatement-248] + _ = x[KindDoStatement-249] + _ = x[KindWhileStatement-250] + _ = x[KindForStatement-251] + _ = x[KindForInStatement-252] + _ = x[KindForOfStatement-253] + _ = x[KindContinueStatement-254] + _ = x[KindBreakStatement-255] + _ = x[KindReturnStatement-256] + _ = x[KindWithStatement-257] + _ = x[KindSwitchStatement-258] + _ = x[KindLabeledStatement-259] + _ = x[KindThrowStatement-260] + _ = x[KindTryStatement-261] + _ = x[KindDebuggerStatement-262] + _ = x[KindVariableDeclaration-263] + _ = x[KindVariableDeclarationList-264] + _ = x[KindFunctionDeclaration-265] + _ = x[KindClassDeclaration-266] + _ = x[KindInterfaceDeclaration-267] + _ = x[KindTypeAliasDeclaration-268] + _ = x[KindEnumDeclaration-269] + _ = x[KindModuleDeclaration-270] + _ = x[KindModuleBlock-271] + _ = x[KindCaseBlock-272] + _ = x[KindNamespaceExportDeclaration-273] + _ = x[KindImportEqualsDeclaration-274] + _ = x[KindImportDeclaration-275] + _ = x[KindImportClause-276] + _ = x[KindNamespaceImport-277] + _ = x[KindNamedImports-278] + _ = x[KindImportSpecifier-279] + _ = x[KindExportAssignment-280] + _ = x[KindExportDeclaration-281] + _ = x[KindNamedExports-282] + _ = x[KindNamespaceExport-283] + _ = x[KindExportSpecifier-284] + _ = x[KindMissingDeclaration-285] + _ = x[KindExternalModuleReference-286] + _ = x[KindJsxElement-287] + _ = x[KindJsxSelfClosingElement-288] + _ = x[KindJsxOpeningElement-289] + _ = x[KindJsxClosingElement-290] + _ = x[KindJsxFragment-291] + _ = x[KindJsxOpeningFragment-292] + _ = x[KindJsxClosingFragment-293] + _ = x[KindJsxAttribute-294] + _ = x[KindJsxAttributes-295] + _ = x[KindJsxSpreadAttribute-296] + _ = x[KindJsxExpression-297] + _ = x[KindJsxNamespacedName-298] + _ = x[KindCaseClause-299] + _ = x[KindDefaultClause-300] + _ = x[KindHeritageClause-301] + _ = x[KindCatchClause-302] + _ = x[KindImportAttributes-303] + _ = x[KindImportAttribute-304] + _ = x[KindPropertyAssignment-305] + _ = x[KindShorthandPropertyAssignment-306] + _ = x[KindSpreadAssignment-307] + _ = x[KindEnumMember-308] + _ = x[KindSourceFile-309] + _ = x[KindJSDocTypeExpression-310] + _ = x[KindJSDocNameReference-311] + _ = x[KindJSDocAllType-312] + _ = x[KindJSDocNullableType-313] + _ = x[KindJSDocNonNullableType-314] + _ = x[KindJSDocOptionalType-315] + _ = x[KindJSDocVariadicType-316] + _ = x[KindJSDoc-317] + _ = x[KindJSDocText-318] + _ = x[KindJSDocTypeLiteral-319] + _ = x[KindJSDocSignature-320] + _ = x[KindJSDocLink-321] + _ = x[KindJSDocLinkCode-322] + _ = x[KindJSDocLinkPlain-323] + _ = x[KindJSDocUnknownTag-324] + _ = x[KindJSDocAugmentsTag-325] + _ = x[KindJSDocImplementsTag-326] + _ = x[KindJSDocDeprecatedTag-327] + _ = x[KindJSDocPublicTag-328] + _ = x[KindJSDocPrivateTag-329] + _ = x[KindJSDocProtectedTag-330] + _ = x[KindJSDocReadonlyTag-331] + _ = x[KindJSDocOverrideTag-332] + _ = x[KindJSDocCallbackTag-333] + _ = x[KindJSDocOverloadTag-334] + _ = x[KindJSDocParameterTag-335] + _ = x[KindJSDocReturnTag-336] + _ = x[KindJSDocThisTag-337] + _ = x[KindJSDocTypeTag-338] + _ = x[KindJSDocTemplateTag-339] + _ = x[KindJSDocTypedefTag-340] + _ = x[KindJSDocSeeTag-341] + _ = x[KindJSDocPropertyTag-342] + _ = x[KindJSDocThrowsTag-343] + _ = x[KindJSDocSatisfiesTag-344] + _ = x[KindJSDocImportTag-345] + _ = x[KindSyntaxList-346] + _ = x[KindJSTypeAliasDeclaration-347] + _ = x[KindJSImportDeclaration-348] + _ = x[KindNotEmittedStatement-349] + _ = x[KindPartiallyEmittedExpression-350] + _ = x[KindSyntheticReferenceExpression-351] + _ = x[KindNotEmittedTypeElement-352] + _ = x[KindCount-353] } -const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindSourceKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocUnknownTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocThrowsTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCountkindFlowSwitchClauseDatakindFlowReduceLabelData" +const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindNotKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindSourceKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocUnknownTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocThrowsTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCountkindFlowSwitchClauseDatakindFlowReduceLabelData" -var _Kind_index = [...]uint16{0, 11, 24, 51, 77, 94, 114, 138, 165, 183, 200, 217, 228, 253, 281, 314, 330, 348, 364, 382, 401, 419, 438, 458, 479, 491, 509, 527, 541, 561, 578, 600, 620, 643, 669, 690, 716, 743, 775, 801, 814, 828, 845, 870, 884, 900, 917, 936, 961, 992, 1034, 1052, 1064, 1078, 1098, 1112, 1139, 1154, 1171, 1185, 1196, 1221, 1238, 1251, 1266, 1285, 1305, 1328, 1359, 1379, 1401, 1432, 1469, 1517, 1541, 1559, 1580, 1613, 1644, 1664, 1678, 1699, 1724, 1740, 1755, 1771, 1787, 1803, 1822, 1841, 1859, 1876, 1889, 1904, 1919, 1936, 1954, 1970, 1988, 2002, 2021, 2034, 2051, 2064, 2085, 2099, 2114, 2131, 2147, 2164, 2179, 2195, 2210, 2224, 2241, 2255, 2270, 2286, 2301, 2322, 2342, 2356, 2374, 2392, 2412, 2429, 2446, 2462, 2481, 2500, 2513, 2531, 2548, 2562, 2578, 2594, 2612, 2634, 2652, 2666, 2686, 2702, 2722, 2735, 2751, 2768, 2788, 2804, 2818, 2837, 2855, 2872, 2889, 2909, 2923, 2940, 2957, 2972, 2992, 3009, 3027, 3043, 3058, 3075, 3092, 3111, 3124, 3140, 3157, 3174, 3198, 3215, 3228, 3241, 3262, 3285, 3304, 3325, 3356, 3371, 3386, 3401, 3418, 3440, 3458, 3475, 3492, 3508, 3527, 3540, 3555, 3568, 3581, 3597, 3609, 3622, 3642, 3661, 3674, 3695, 3707, 3723, 3744, 3758, 3773, 3793, 3816, 3843, 3857, 3881, 3904, 3922, 3948, 3975, 4003, 4030, 4048, 4065, 4093, 4120, 4147, 4169, 4186, 4206, 4226, 4244, 4263, 4288, 4314, 4334, 4359, 4381, 4400, 4417, 4436, 4457, 4488, 4504, 4525, 4541, 4564, 4587, 4603, 4628, 4637, 4655, 4676, 4699, 4714, 4729, 4747, 4763, 4781, 4799, 4820, 4838, 4857, 4874, 4893, 4913, 4931, 4947, 4968, 4991, 5018, 5041, 5061, 5085, 5109, 5128, 5149, 5164, 5177, 5207, 5234, 5255, 5271, 5290, 5306, 5325, 5345, 5366, 5382, 5401, 5420, 5442, 5469, 5483, 5508, 5529, 5550, 5565, 5587, 5609, 5625, 5642, 5664, 5681, 5702, 5716, 5733, 5751, 5766, 5786, 5805, 5827, 5858, 5878, 5892, 5906, 5929, 5951, 5967, 5988, 6012, 6033, 6054, 6063, 6076, 6096, 6114, 6127, 6144, 6162, 6181, 6201, 6223, 6245, 6263, 6282, 6303, 6323, 6343, 6363, 6383, 6404, 6422, 6438, 6454, 6474, 6493, 6508, 6528, 6546, 6567, 6585, 6599, 6625, 6648, 6671, 6701, 6733, 6758, 6767, 6791, 6814} +var _Kind_index = [...]uint16{0, 11, 24, 51, 77, 94, 114, 138, 165, 183, 200, 217, 228, 253, 281, 314, 330, 348, 364, 382, 401, 419, 438, 458, 479, 491, 509, 527, 541, 561, 578, 600, 620, 643, 669, 690, 716, 743, 775, 801, 814, 828, 845, 870, 884, 900, 917, 936, 961, 992, 1034, 1052, 1064, 1078, 1098, 1112, 1139, 1154, 1171, 1185, 1196, 1221, 1238, 1251, 1266, 1285, 1305, 1328, 1359, 1379, 1401, 1432, 1469, 1517, 1541, 1559, 1580, 1613, 1644, 1664, 1678, 1699, 1724, 1740, 1755, 1771, 1787, 1803, 1822, 1841, 1859, 1876, 1889, 1904, 1919, 1936, 1954, 1970, 1988, 2002, 2021, 2034, 2051, 2064, 2085, 2099, 2114, 2131, 2147, 2164, 2179, 2195, 2210, 2224, 2241, 2255, 2270, 2286, 2301, 2322, 2342, 2356, 2374, 2392, 2412, 2429, 2446, 2462, 2481, 2500, 2513, 2531, 2548, 2562, 2578, 2594, 2612, 2634, 2652, 2666, 2686, 2702, 2722, 2735, 2751, 2768, 2788, 2804, 2818, 2832, 2851, 2869, 2886, 2903, 2923, 2937, 2954, 2971, 2986, 3006, 3023, 3041, 3057, 3072, 3089, 3106, 3125, 3138, 3154, 3171, 3188, 3212, 3229, 3242, 3255, 3276, 3299, 3318, 3339, 3370, 3385, 3400, 3415, 3432, 3454, 3472, 3489, 3506, 3522, 3541, 3554, 3569, 3582, 3595, 3611, 3623, 3636, 3656, 3675, 3688, 3709, 3721, 3737, 3758, 3772, 3787, 3807, 3830, 3857, 3871, 3895, 3918, 3936, 3962, 3989, 4017, 4044, 4062, 4079, 4107, 4134, 4161, 4183, 4200, 4220, 4240, 4258, 4277, 4302, 4328, 4348, 4373, 4395, 4414, 4431, 4450, 4471, 4502, 4518, 4539, 4555, 4578, 4601, 4617, 4642, 4651, 4669, 4690, 4713, 4728, 4743, 4761, 4777, 4795, 4813, 4834, 4852, 4871, 4888, 4907, 4927, 4945, 4961, 4982, 5005, 5032, 5055, 5075, 5099, 5123, 5142, 5163, 5178, 5191, 5221, 5248, 5269, 5285, 5304, 5320, 5339, 5359, 5380, 5396, 5415, 5434, 5456, 5483, 5497, 5522, 5543, 5564, 5579, 5601, 5623, 5639, 5656, 5678, 5695, 5716, 5730, 5747, 5765, 5780, 5800, 5819, 5841, 5872, 5892, 5906, 5920, 5943, 5965, 5981, 6002, 6026, 6047, 6068, 6077, 6090, 6110, 6128, 6141, 6158, 6176, 6195, 6215, 6237, 6259, 6277, 6296, 6317, 6337, 6357, 6377, 6397, 6418, 6436, 6452, 6468, 6488, 6507, 6522, 6542, 6560, 6581, 6599, 6613, 6639, 6662, 6685, 6715, 6747, 6772, 6781, 6805, 6828} func (i Kind) String() string { idx := int(i) - 0 diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 10ddb3c0c88b4..bd6eb44dbcd54 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -65,6 +65,7 @@ const ( TypeSystemPropertyNameWriteType TypeSystemPropertyNameInitializerIsUndefined TypeSystemPropertyNameAliasTarget + TypeSystemPropertyNameResolvedReducedType ) type TypeResolution struct { @@ -151,6 +152,11 @@ type CachedTypeKey struct { typeId TypeId } +type DistributiveInstantiationKey struct { + typeId TypeId + typeParameterId TypeId +} + // NarrowedTypeKey type NarrowedTypeKey struct { @@ -429,41 +435,50 @@ const ( TypeFactsFalsy TypeFacts = 1 << 23 TypeFactsIsUndefined TypeFacts = 1 << 24 TypeFactsIsNull TypeFacts = 1 << 25 + // The following facts record whether a type could be a particular *falsy* value. Unlike the Falsy + // fact (which is a single "could be falsy at all" bit), these are per-value so that a negated type + // such as `not ""` can surgically exclude a single falsy possibility. They are AND-combined in + // getIntersectionTypeFacts (a value is in an intersection only if it is in every constituent), which + // lets an intersection of negations exclude every falsy value. + TypeFactsCouldBeEmptyString TypeFacts = 1 << 26 + TypeFactsCouldBeZeroNumber TypeFacts = 1 << 27 + TypeFactsCouldBeZeroBigInt TypeFacts = 1 << 28 + TypeFactsCouldBeFalse TypeFacts = 1 << 29 TypeFactsIsUndefinedOrNull TypeFacts = TypeFactsIsUndefined | TypeFactsIsNull - TypeFactsAll TypeFacts = (1 << 27) - 1 + TypeFactsAll TypeFacts = (1 << 30) - 1 // The following members encode facts about particular kinds of types for use in the getTypeFacts function. // The presence of a particular fact means that the given test is true for some (and possibly all) values // of that kind of type. TypeFactsBaseStringStrictFacts TypeFacts = TypeFactsTypeofEQString | TypeFactsTypeofNENumber | TypeFactsTypeofNEBigInt | TypeFactsTypeofNEBoolean | TypeFactsTypeofNESymbol | TypeFactsTypeofNEObject | TypeFactsTypeofNEFunction | TypeFactsTypeofNEHostObject | TypeFactsNEUndefined | TypeFactsNENull | TypeFactsNEUndefinedOrNull TypeFactsBaseStringFacts TypeFacts = TypeFactsBaseStringStrictFacts | TypeFactsEQUndefined | TypeFactsEQNull | TypeFactsEQUndefinedOrNull | TypeFactsFalsy - TypeFactsStringStrictFacts TypeFacts = TypeFactsBaseStringStrictFacts | TypeFactsTruthy | TypeFactsFalsy - TypeFactsStringFacts TypeFacts = TypeFactsBaseStringFacts | TypeFactsTruthy - TypeFactsEmptyStringStrictFacts TypeFacts = TypeFactsBaseStringStrictFacts | TypeFactsFalsy - TypeFactsEmptyStringFacts TypeFacts = TypeFactsBaseStringFacts + TypeFactsStringStrictFacts TypeFacts = TypeFactsBaseStringStrictFacts | TypeFactsTruthy | TypeFactsFalsy | TypeFactsCouldBeEmptyString + TypeFactsStringFacts TypeFacts = TypeFactsBaseStringFacts | TypeFactsTruthy | TypeFactsCouldBeEmptyString + TypeFactsEmptyStringStrictFacts TypeFacts = TypeFactsBaseStringStrictFacts | TypeFactsFalsy | TypeFactsCouldBeEmptyString + TypeFactsEmptyStringFacts TypeFacts = TypeFactsBaseStringFacts | TypeFactsCouldBeEmptyString TypeFactsNonEmptyStringStrictFacts TypeFacts = TypeFactsBaseStringStrictFacts | TypeFactsTruthy TypeFactsNonEmptyStringFacts TypeFacts = TypeFactsBaseStringFacts | TypeFactsTruthy TypeFactsBaseNumberStrictFacts TypeFacts = TypeFactsTypeofEQNumber | TypeFactsTypeofNEString | TypeFactsTypeofNEBigInt | TypeFactsTypeofNEBoolean | TypeFactsTypeofNESymbol | TypeFactsTypeofNEObject | TypeFactsTypeofNEFunction | TypeFactsTypeofNEHostObject | TypeFactsNEUndefined | TypeFactsNENull | TypeFactsNEUndefinedOrNull TypeFactsBaseNumberFacts TypeFacts = TypeFactsBaseNumberStrictFacts | TypeFactsEQUndefined | TypeFactsEQNull | TypeFactsEQUndefinedOrNull | TypeFactsFalsy - TypeFactsNumberStrictFacts TypeFacts = TypeFactsBaseNumberStrictFacts | TypeFactsTruthy | TypeFactsFalsy - TypeFactsNumberFacts TypeFacts = TypeFactsBaseNumberFacts | TypeFactsTruthy - TypeFactsZeroNumberStrictFacts TypeFacts = TypeFactsBaseNumberStrictFacts | TypeFactsFalsy - TypeFactsZeroNumberFacts TypeFacts = TypeFactsBaseNumberFacts + TypeFactsNumberStrictFacts TypeFacts = TypeFactsBaseNumberStrictFacts | TypeFactsTruthy | TypeFactsFalsy | TypeFactsCouldBeZeroNumber + TypeFactsNumberFacts TypeFacts = TypeFactsBaseNumberFacts | TypeFactsTruthy | TypeFactsCouldBeZeroNumber + TypeFactsZeroNumberStrictFacts TypeFacts = TypeFactsBaseNumberStrictFacts | TypeFactsFalsy | TypeFactsCouldBeZeroNumber + TypeFactsZeroNumberFacts TypeFacts = TypeFactsBaseNumberFacts | TypeFactsCouldBeZeroNumber TypeFactsNonZeroNumberStrictFacts TypeFacts = TypeFactsBaseNumberStrictFacts | TypeFactsTruthy TypeFactsNonZeroNumberFacts TypeFacts = TypeFactsBaseNumberFacts | TypeFactsTruthy TypeFactsBaseBigIntStrictFacts TypeFacts = TypeFactsTypeofEQBigInt | TypeFactsTypeofNEString | TypeFactsTypeofNENumber | TypeFactsTypeofNEBoolean | TypeFactsTypeofNESymbol | TypeFactsTypeofNEObject | TypeFactsTypeofNEFunction | TypeFactsTypeofNEHostObject | TypeFactsNEUndefined | TypeFactsNENull | TypeFactsNEUndefinedOrNull TypeFactsBaseBigIntFacts TypeFacts = TypeFactsBaseBigIntStrictFacts | TypeFactsEQUndefined | TypeFactsEQNull | TypeFactsEQUndefinedOrNull | TypeFactsFalsy - TypeFactsBigIntStrictFacts TypeFacts = TypeFactsBaseBigIntStrictFacts | TypeFactsTruthy | TypeFactsFalsy - TypeFactsBigIntFacts TypeFacts = TypeFactsBaseBigIntFacts | TypeFactsTruthy - TypeFactsZeroBigIntStrictFacts TypeFacts = TypeFactsBaseBigIntStrictFacts | TypeFactsFalsy - TypeFactsZeroBigIntFacts TypeFacts = TypeFactsBaseBigIntFacts + TypeFactsBigIntStrictFacts TypeFacts = TypeFactsBaseBigIntStrictFacts | TypeFactsTruthy | TypeFactsFalsy | TypeFactsCouldBeZeroBigInt + TypeFactsBigIntFacts TypeFacts = TypeFactsBaseBigIntFacts | TypeFactsTruthy | TypeFactsCouldBeZeroBigInt + TypeFactsZeroBigIntStrictFacts TypeFacts = TypeFactsBaseBigIntStrictFacts | TypeFactsFalsy | TypeFactsCouldBeZeroBigInt + TypeFactsZeroBigIntFacts TypeFacts = TypeFactsBaseBigIntFacts | TypeFactsCouldBeZeroBigInt TypeFactsNonZeroBigIntStrictFacts TypeFacts = TypeFactsBaseBigIntStrictFacts | TypeFactsTruthy TypeFactsNonZeroBigIntFacts TypeFacts = TypeFactsBaseBigIntFacts | TypeFactsTruthy TypeFactsBaseBooleanStrictFacts TypeFacts = TypeFactsTypeofEQBoolean | TypeFactsTypeofNEString | TypeFactsTypeofNENumber | TypeFactsTypeofNEBigInt | TypeFactsTypeofNESymbol | TypeFactsTypeofNEObject | TypeFactsTypeofNEFunction | TypeFactsTypeofNEHostObject | TypeFactsNEUndefined | TypeFactsNENull | TypeFactsNEUndefinedOrNull TypeFactsBaseBooleanFacts TypeFacts = TypeFactsBaseBooleanStrictFacts | TypeFactsEQUndefined | TypeFactsEQNull | TypeFactsEQUndefinedOrNull | TypeFactsFalsy - TypeFactsBooleanStrictFacts TypeFacts = TypeFactsBaseBooleanStrictFacts | TypeFactsTruthy | TypeFactsFalsy - TypeFactsBooleanFacts TypeFacts = TypeFactsBaseBooleanFacts | TypeFactsTruthy - TypeFactsFalseStrictFacts TypeFacts = TypeFactsBaseBooleanStrictFacts | TypeFactsFalsy - TypeFactsFalseFacts TypeFacts = TypeFactsBaseBooleanFacts + TypeFactsBooleanStrictFacts TypeFacts = TypeFactsBaseBooleanStrictFacts | TypeFactsTruthy | TypeFactsFalsy | TypeFactsCouldBeFalse + TypeFactsBooleanFacts TypeFacts = TypeFactsBaseBooleanFacts | TypeFactsTruthy | TypeFactsCouldBeFalse + TypeFactsFalseStrictFacts TypeFacts = TypeFactsBaseBooleanStrictFacts | TypeFactsFalsy | TypeFactsCouldBeFalse + TypeFactsFalseFacts TypeFacts = TypeFactsBaseBooleanFacts | TypeFactsCouldBeFalse TypeFactsTrueStrictFacts TypeFacts = TypeFactsBaseBooleanStrictFacts | TypeFactsTruthy TypeFactsTrueFacts TypeFacts = TypeFactsBaseBooleanFacts | TypeFactsTruthy TypeFactsSymbolStrictFacts TypeFacts = TypeFactsTypeofEQSymbol | TypeFactsTypeofNEString | TypeFactsTypeofNENumber | TypeFactsTypeofNEBigInt | TypeFactsTypeofNEBoolean | TypeFactsTypeofNEObject | TypeFactsTypeofNEFunction | TypeFactsTypeofNEHostObject | TypeFactsNEUndefined | TypeFactsNENull | TypeFactsNEUndefinedOrNull | TypeFactsTruthy @@ -479,6 +494,9 @@ const ( TypeFactsEmptyObjectFacts TypeFacts = TypeFactsAll & ^TypeFactsIsUndefinedOrNull TypeFactsUnknownFacts TypeFacts = TypeFactsAll & ^TypeFactsIsUndefinedOrNull TypeFactsAllTypeofNE TypeFacts = TypeFactsTypeofNEString | TypeFactsTypeofNENumber | TypeFactsTypeofNEBigInt | TypeFactsTypeofNEBoolean | TypeFactsTypeofNESymbol | TypeFactsTypeofNEObject | TypeFactsTypeofNEFunction | TypeFactsNEUndefined + // The set of facts that indicate a type could be some falsy value. A type whose intersection facts + // retain none of these can never be falsy, so its Falsy fact is spurious and gets cleared. + TypeFactsAllCouldBeFalsy TypeFacts = TypeFactsCouldBeEmptyString | TypeFactsCouldBeZeroNumber | TypeFactsCouldBeZeroBigInt | TypeFactsCouldBeFalse | TypeFactsEQUndefined | TypeFactsEQNull | TypeFactsEQUndefinedOrNull // Masks TypeFactsOrFactsMask TypeFacts = TypeFactsTypeofEQFunction | TypeFactsTypeofNEObject TypeFactsAndFactsMask TypeFacts = TypeFactsAll & ^TypeFactsOrFactsMask @@ -638,6 +656,7 @@ type Checker struct { thisExpandoLocations map[*ast.Symbol]*ast.Node subtypeReductionCache map[CacheHashKey][]*Type cachedTypes map[CachedTypeKey]*Type + distributiveInstantiationCache map[DistributiveInstantiationKey]bool cachedSignatures map[CachedSignatureKey]*Signature undefinedProperties map[*ast.Symbol]*ast.Symbol narrowedTypes map[NarrowedTypeKey]*Type @@ -645,6 +664,7 @@ type Checker struct { discriminatedContextualTypes map[DiscriminatedContextualTypeKey]*Type instantiationExpressionTypes map[InstantiationExpressionKey]*Type substitutionTypes map[SubstitutionTypeKey]*Type + negatedTypes map[TypeId]*Type reverseMappedCache map[ReverseMappedTypeKey]*Type reverseHomomorphicMappedCache map[ReverseMappedTypeKey]*Type iterationTypesCache map[IterationTypesKey]IterationTypes @@ -976,6 +996,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) { c.thisExpandoLocations = make(map[*ast.Symbol]*ast.Node) c.subtypeReductionCache = make(map[CacheHashKey][]*Type) c.cachedTypes = make(map[CachedTypeKey]*Type) + c.distributiveInstantiationCache = make(map[DistributiveInstantiationKey]bool) c.cachedSignatures = make(map[CachedSignatureKey]*Signature) c.undefinedProperties = make(map[*ast.Symbol]*ast.Symbol) c.narrowedTypes = make(map[NarrowedTypeKey]*Type) @@ -983,6 +1004,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) { c.discriminatedContextualTypes = make(map[DiscriminatedContextualTypeKey]*Type) c.instantiationExpressionTypes = make(map[InstantiationExpressionKey]*Type) c.substitutionTypes = make(map[SubstitutionTypeKey]*Type) + c.negatedTypes = make(map[TypeId]*Type) c.reverseMappedCache = make(map[ReverseMappedTypeKey]*Type) c.reverseHomomorphicMappedCache = make(map[ReverseMappedTypeKey]*Type) c.iterationTypesCache = make(map[IterationTypesKey]IterationTypes) @@ -12574,7 +12596,12 @@ func (c *Checker) checkBinaryLikeExpression(left *ast.Node, operatorToken *ast.N if operator == ast.KindEqualsToken && (left.Kind == ast.KindObjectLiteralExpression || left.Kind == ast.KindArrayLiteralExpression) { return c.checkDestructuringAssignment(left, c.checkExpressionEx(right, checkMode), checkMode, right.Kind == ast.KindThisKeyword) } - leftType := c.checkExpressionEx(left, checkMode) + var leftType *Type + if ast.IsCompoundAssignment(operator) && !ast.IsLogicalOrCoalescingAssignmentOperator(operator) { + leftType = c.checkExpressionForMutableLocation(left, checkMode) + } else { + leftType = c.checkExpressionEx(left, checkMode) + } rightType := c.checkExpressionEx(right, checkMode) if ast.IsLogicalOrCoalescingBinaryOperator(operator) { parent := left.Parent.Parent @@ -17537,7 +17564,13 @@ func (c *Checker) getInferredTypeParameterConstraint(t *Type, omitTypeReferences } switch { case ast.IsTypeReferenceNode(parent) && !omitTypeReferences: - typeParameters := c.getTypeParametersForTypeReferenceOrImport(parent) + var typeParameters []*Type + symbol := c.getSymbolFromTypeReference(parent) + if symbol.Flags()&ast.SymbolFlagsTypeAlias != 0 && symbol.CheckFlags()&ast.CheckFlagsUnresolved == 0 { + typeParameters = c.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) + } else { + typeParameters = c.getTypeParametersForTypeReferenceOrImport(parent) + } if typeParameters != nil { index := slices.Index(parent.TypeArguments(), child) if index >= 0 && index < len(typeParameters) { @@ -18687,7 +18720,9 @@ func (c *Checker) widenTypeForVariableLikeDeclaration(t *Type, declaration *ast. if t.flags&TypeFlagsUniqueESSymbol != 0 && (ast.IsBindingElement(declaration) || declaration.Type() == nil) && t.symbol != c.getSymbolOfDeclaration(declaration) { t = c.esSymbolType } - return c.getWidenedType(t) + // Drop any fresh negated types introduced by control flow narrowing so a CFA-introduced + // 'not X' does not leak into an inferred variable, parameter, or property declaration. + return c.removeOrRegularizeNegatedTypes(c.getWidenedType(t), true /*removeNegatedTypes*/) } // Rest parameters default to type any[], other parameters default to type any if ast.IsParameterDeclaration(declaration) && declaration.AsParameterDeclaration().DotDotDotToken != nil { @@ -18793,6 +18828,7 @@ func (c *Checker) getWidenedType(t *Type) *Type { } func (c *Checker) getWidenedTypeWithContext(t *Type, context *WideningContext) *Type { + t = c.removeFreshNegatedTypes(t) if t.objectFlags&ObjectFlagsRequiresWidening != 0 { if context == nil { if cached := c.cachedTypes[CachedTypeKey{kind: CachedTypeKindWidened, typeId: t.id}]; cached != nil { @@ -19251,6 +19287,8 @@ func (c *Checker) typeResolutionHasProperty(r *TypeResolution) bool { return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).getWriteType() != nil case TypeSystemPropertyNameAliasTarget: return c.aliasSymbolLinks.Get(r.target.(*ast.Symbol)).aliasTarget != nil + case TypeSystemPropertyNameResolvedReducedType: + return r.target.(*Type).AsUnionType().resolvedReducedType != nil } panic("Unhandled case in typeResolutionHasProperty") } @@ -20636,7 +20674,7 @@ func (c *Checker) getReturnTypeFromBody(fn *ast.Node, checkMode CheckMode) *Type if nextType != nil { c.reportErrorsFromWidening(fn, nextType, WideningKindGeneratorNext) } - if returnType != nil && isUnitType(returnType) || yieldType != nil && isUnitType(yieldType) || nextType != nil && isUnitType(nextType) { + if needsContextualWidening(returnType) || needsContextualWidening(yieldType) || needsContextualWidening(nextType) { contextualSignature := c.getContextualSignatureForFunctionLikeDeclaration(fn) var contextualType *Type switch { @@ -20840,8 +20878,12 @@ func (c *Checker) unwrapReturnType(returnType *Type, functionFlags ast.FunctionF return returnType } +func needsContextualWidening(t *Type) bool { + return t != nil && (isUnitType(t) || containsFreshNegatedType(t)) +} + func (c *Checker) getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(t *Type, contextualSignatureReturnType *Type, isAsync bool) *Type { - if t != nil && isUnitType(t) { + if needsContextualWidening(t) { var contextualType *Type switch { case contextualSignatureReturnType == nil: @@ -20857,7 +20899,7 @@ func (c *Checker) getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(t *Ty } func (c *Checker) getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(t *Type, contextualSignatureReturnType *Type, kind IterationTypeKind, isAsyncGenerator bool) *Type { - if t != nil && isUnitType(t) { + if needsContextualWidening(t) { var contextualType *Type if contextualSignatureReturnType != nil { contextualType = c.getIterationTypeOfGeneratorFunctionReturnType(kind, contextualSignatureReturnType, isAsyncGenerator) @@ -21027,7 +21069,7 @@ func (c *Checker) checkIfExpressionRefinesParameter(fn *ast.Node, expr *ast.Node antecedent = &ast.FlowNode{Flags: ast.FlowFlagsStart} } trueCondition := &ast.FlowNode{Flags: ast.FlowFlagsTrueCondition, Node: expr, Antecedent: antecedent} - trueType := c.getFlowTypeOfReferenceEx(param.Name(), initType, initType, fn, trueCondition) + trueType := c.removeFreshNegatedTypes(c.getFlowTypeOfReferenceEx(param.Name(), initType, initType, fn, trueCondition)) if trueType == initType { return nil } @@ -21497,7 +21539,11 @@ func (c *Checker) resolveUnionTypeMembers(t *Type) { if t == c.globalFunctionType { return []*Signature{c.unknownSignature} } - return c.getSignaturesOfType(t, SignatureKindCall) + signatures := c.getSignaturesOfType(t, SignatureKindCall) + if len(signatures) == 0 && t.flags&TypeFlagsIntersection != 0 && slices.Contains(t.Types(), c.globalFunctionType) && len(c.getSignaturesOfType(t, SignatureKindConstruct)) == 0 { + return []*Signature{c.unknownSignature} + } + return signatures })) if len(callSignatures) == 0 { callSignatures = c.getArrayMemberCallSignatures(t) @@ -22273,7 +22319,7 @@ func (c *Checker) getApparentTypeOfIntersectionType(t *Type, thisArgument *Type) } /** - * Return the reduced form of the given type. For a union type, it is a union of the normalized constituent types. + * Return the reduced form of the given type. For a union type, normalize its constituents and combine negated complements. * For an intersection of types containing one or more mututally exclusive discriminant properties, it is 'never'. * For all other types, it is simply the type itself. Discriminant properties are considered mutually exclusive when * no constituent property has type 'never', but the intersection of the constituent property types is 'never'. @@ -22281,13 +22327,25 @@ func (c *Checker) getApparentTypeOfIntersectionType(t *Type, thisArgument *Type) func (c *Checker) getReducedType(t *Type) *Type { switch { case t.flags&TypeFlagsUnion != 0: - if t.objectFlags&ObjectFlagsContainsIntersections != 0 { + if t.objectFlags&ObjectFlagsContainsIntersections != 0 || containsNegatedType(t) { if reducedType := t.AsUnionType().resolvedReducedType; reducedType != nil { return reducedType } + if !c.pushTypeResolution(t, TypeSystemPropertyNameResolvedReducedType) { + t.AsUnionType().resolvedReducedType = t + return t + } reducedType := c.getReducedUnionType(t) - t.AsUnionType().resolvedReducedType = reducedType - return reducedType + if !c.popTypeResolution() { + reducedType = t + } + if t.AsUnionType().resolvedReducedType == nil { + if reducedType.flags&TypeFlagsUnion != 0 && reducedType.AsUnionType().resolvedReducedType == nil { + reducedType.AsUnionType().resolvedReducedType = reducedType + } + t.AsUnionType().resolvedReducedType = reducedType + } + return t.AsUnionType().resolvedReducedType } case t.flags&TypeFlagsIntersection != 0: if t.objectFlags&ObjectFlagsIsNeverIntersectionComputed == 0 { @@ -22340,14 +22398,17 @@ func (c *Checker) somePropertyReducesToNever(t *Type) bool { func (c *Checker) getReducedUnionType(unionType *Type) *Type { reducedTypes := core.SameMap(unionType.Types(), c.getReducedType) + if !core.Same(reducedTypes, unionType.Types()) { + reducedTypes, _ = c.addTypesToUnion(reducedTypes, nil) + } + if core.Some(reducedTypes, isNegatedType) && c.checkForSaturatedNegatedType(reducedTypes) { + return c.unknownType + } + reducedTypes = c.removeComplementaryNegatedTypes(reducedTypes) if core.Same(reducedTypes, unionType.Types()) { return unionType } - reduced := c.getUnionType(reducedTypes) - if reduced.flags&TypeFlagsUnion != 0 { - reduced.AsUnionType().resolvedReducedType = reduced - } - return reduced + return c.getUnionType(reducedTypes) } func (c *Checker) isNeverReducedProperty(prop *ast.Symbol) bool { @@ -22715,7 +22776,8 @@ func (c *Checker) couldContainTypeVariablesWorker(t *Type) bool { if objectFlags&ObjectFlagsCouldContainTypeVariablesComputed != 0 { return objectFlags&ObjectFlagsCouldContainTypeVariables != 0 } - result := t.flags&TypeFlagsInstantiable != 0 || + result := t.flags&(TypeFlagsInstantiable & ^TypeFlagsNegated) != 0 || + t.flags&TypeFlagsNegated != 0 && c.couldContainTypeVariables(t.AsNegatedType().baseType) || t.flags&TypeFlagsObject != 0 && !c.isNonGenericTopLevelType(t) && (objectFlags&ObjectFlagsReference != 0 && (t.AsTypeReference().node != nil || core.Some(c.getTypeArguments(t), c.couldContainTypeVariables)) || objectFlags&ObjectFlagsAnonymous != 0 && t.symbol != nil && t.symbol.Flags()&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod|ast.SymbolFlagsClass|ast.SymbolFlagsTypeLiteral|ast.SymbolFlagsObjectLiteral) != 0 && t.symbol.Declarations() != nil || objectFlags&(ObjectFlagsMapped|ObjectFlagsReverseMapped|ObjectFlagsObjectRestType|ObjectFlagsInstantiationExpressionType) != 0) || @@ -22799,6 +22861,8 @@ func (c *Checker) instantiateTypeWorker(t *Type, m *TypeMapper, alias *TypeAlias return c.getStringMappingType(t.symbol, c.instantiateType(t.AsStringMappingType().target, m)) case flags&TypeFlagsConditional != 0: return c.getConditionalTypeInstantiation(t, c.combineTypeMappers(t.AsConditionalType().mapper, m), false /*forConstraint*/, alias) + case flags&TypeFlagsNegated != 0: + return c.getNegatedType(c.instantiateType(t.AsNegatedType().baseType, m)) case flags&TypeFlagsSubstitution != 0: newBaseType := c.instantiateType(t.AsSubstitutionType().baseType, m) if c.isNoInferType(t) { @@ -23498,6 +23562,8 @@ func (c *Checker) getTypeFromTypeOperatorNode(node *ast.Node) *Type { } case ast.KindReadonlyKeyword: links.resolvedType = c.getTypeFromTypeNode(argType) + case ast.KindNotKeyword: + links.resolvedType = c.getNegatedType(c.getTypeFromTypeNode(argType)) default: panic("Unhandled case in getTypeFromTypeOperatorNode") } @@ -25464,6 +25530,12 @@ func (c *Checker) getGenericObjectFlags(t *Type) ObjectFlags { } return t.objectFlags & ObjectFlagsIsGenericType } + if t.flags&TypeFlagsNegated != 0 { + // A negated type 'not T' is generic only if its base type is generic. This unwrapping + // mirrors maybeTypeOfKindUnwrapNegations, ensuring e.g. 'not "a"' is not treated as a + // generic (instantiable) type even though Negated is part of InstantiableNonPrimitive. + return c.getGenericObjectFlags(t.AsNegatedType().baseType) + } if t.flags&TypeFlagsInstantiableNonPrimitive != 0 || c.isGenericMappedType(t) || c.isGenericTupleType(t) { combinedFlags |= ObjectFlagsIsGenericObjectType } @@ -26104,7 +26176,11 @@ func (c *Checker) getWidenedLiteralLikeTypeForContextualType(t *Type, contextual if !c.isLiteralOfContextualType(t, contextualType) { t = c.getWidenedUniqueESSymbolType(c.getWidenedLiteralType(t)) } - return c.getRegularTypeOfLiteralType(t) + // Fresh negated types introduced by control flow narrowing are widened away (dropped) when a + // narrowed value escapes into a location that does not itself want a negation, so that 'not X' + // does not leak into an inferred declaration. When the contextual type does mention a negation + // (e.g. a 'not string' parameter or property), the fresh negation is preserved. + return c.getRegularTypeOfLiteralType(c.removeOrRegularizeNegatedTypes(t, containsFreshNegatedType(t) && !containsNegatedType(contextualType))) } func (c *Checker) isLiteralOfContextualType(candidateType *Type, contextualType *Type) bool { @@ -26114,6 +26190,9 @@ func (c *Checker) isLiteralOfContextualType(candidateType *Type, contextualType return c.isLiteralOfContextualType(candidateType, t) }) } + if contextualType.flags&TypeFlagsNegated != 0 { + return c.isLiteralOfContextualType(candidateType, contextualType.AsNegatedType().baseType) + } if contextualType.flags&TypeFlagsInstantiableNonPrimitive != 0 { // If the contextual type is a type variable constrained to a primitive type, consider // this a literal context for literals of that primitive type. For example, given a @@ -26274,7 +26353,7 @@ func (c *Checker) getUnionTypeWorker(types []*Type, unionReduction UnionReductio } if includes&(TypeFlagsEnum|TypeFlagsLiteral|TypeFlagsUniqueESSymbol|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 || includes&TypeFlagsVoid != 0 && includes&TypeFlagsUndefined != 0 { - typeSet = c.removeRedundantLiteralTypes(typeSet, includes, unionReduction&UnionReductionSubtype != 0) + typeSet = c.removeRedundantLiteralTypes(typeSet, includes, unionReduction == UnionReductionSubtype) } if includes&TypeFlagsStringLiteral != 0 && includes&(TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 { typeSet = c.removeStringLiteralsMatchedByTemplateLiterals(typeSet) @@ -26371,6 +26450,9 @@ func (c *Checker) addTypesToUnion(sourceTypes []*Type, types []*Type) ([]*Type, if flags&TypeFlagsInstantiable != 0 { includes |= TypeFlagsIncludesInstantiable } + if flags&TypeFlagsNegated != 0 { + includes |= TypeFlagsIncludesNegated + } if flags&TypeFlagsIntersection != 0 && t.objectFlags&ObjectFlagsIsConstrainedTypeVariable != 0 { includes |= TypeFlagsIncludesConstrainedTypeVariable } @@ -26410,7 +26492,7 @@ func (c *Checker) addTypesToUnion(sourceTypes []*Type, types []*Type) ([]*Type, slices.SortStableFunc(types, CompareTypes) unique := 1 for _, t := range types[1:] { - if t != types[unique-1] { + if t != types[unique-1] && !(isFreshNegatedType(t) && containsType(types, t.AsNegatedType().regularType)) { types[unique] = t unique++ } @@ -26722,6 +26804,14 @@ func (c *Checker) getIntersectionTypeEx(types []*Type, flags IntersectionFlags, if includes&TypeFlagsIncludesMissingType != 0 { typeSet[slices.Index(typeSet, c.undefinedType)] = c.missingType } + if includes&TypeFlagsUnion == 0 && core.Some(typeSet, isNegatedType) { + if c.checkForUnsatisfiedNegatedType(typeSet, flags) { + return c.neverType + } + if flags&IntersectionFlagsNoConstraintReduction == 0 { + typeSet = c.removeNegatedSubtypes(typeSet) + } + } if len(typeSet) == 0 { return c.unknownType } @@ -26835,6 +26925,10 @@ func isIntersectionType(t *Type) bool { return t.flags&TypeFlagsIntersection != 0 } +func isNegatedType(t *Type) bool { + return t.flags&TypeFlagsNegated != 0 +} + func isPrimitiveUnion(t *Type) bool { return t.objectFlags&ObjectFlagsPrimitiveUnion != 0 } @@ -26861,6 +26955,15 @@ func (c *Checker) addTypeToIntersection(typeSet *orderedSet[*Type], includes Typ if flags&TypeFlagsIntersection != 0 { return c.addTypesToIntersection(typeSet, includes, t.Types()) } + if flags&TypeFlagsNegated != 0 { + if isFreshNegatedType(t) { + if typeSet.contains(t.AsNegatedType().regularType) { + return includes + } + } else if typeSet.replace(t.AsNegatedType().freshType, t) { + return includes + } + } if c.IsEmptyAnonymousObjectType(t) { if includes&TypeFlagsIncludesEmptyObject == 0 { includes |= TypeFlagsIncludesEmptyObject @@ -27111,6 +27214,9 @@ func (c *Checker) isPatternLiteralPlaceholderType(t *Type) bool { } return seenPlaceholder } + if t.flags&TypeFlagsNegated != 0 { + return true // Negated types are always placeholders, since they represent arbitrary domains that may include sets of strings + } return t.flags&(TypeFlagsAny|TypeFlagsString|TypeFlagsNumber|TypeFlagsBigInt) != 0 || c.isPatternLiteralType(t) } @@ -27437,7 +27543,7 @@ func (c *Checker) getSubstitutionIntersection(t *Type) *Type { } func (c *Checker) shouldDeferIndexType(t *Type, indexFlags IndexFlags) bool { - return t.flags&TypeFlagsInstantiableNonPrimitive != 0 || + return t.flags&TypeFlagsInstantiableNonPrimitive != 0 && (t.flags&TypeFlagsNegated == 0 || c.isGenericType(t)) || c.isGenericTupleType(t) || c.isGenericMappedType(t) && c.getNameTypeFromMappedType(t) != nil || t.flags&TypeFlagsUnion != 0 && indexFlags&IndexFlagsNoReducibleCheck == 0 && c.isGenericReducibleType(t) || @@ -28172,6 +28278,8 @@ func (c *Checker) computeBaseConstraint(t *Type, stack []RecursionId) *Type { constraint := c.getConstraintFromConditionalType(t) c.conditionalConstraintDepth-- return c.getNextBaseConstraint(constraint, stack) + case t.flags&TypeFlagsNegated != 0: + return c.unknownType case t.flags&TypeFlagsSubstitution != 0: return c.getNextBaseConstraint(c.getSubstitutionIntersection(t), stack) case c.isGenericTupleType(t): @@ -31254,7 +31362,7 @@ func (c *Checker) getIndexedMappedTypeSubstitutedTypeOfContextualType(t *Type, n propertyNameType = c.getStringLiteralType(name) } constraint := c.getConstraintTypeFromMappedType(t) - // special case for conditional types pretending to be negated types + // Excluded names cannot contribute contextual property types, even when the key constraint is generic. if t.AsMappedType().nameType != nil && c.isExcludedMappedPropertyName(t.AsMappedType().nameType, propertyNameType) || c.isExcludedMappedPropertyName(constraint, propertyNameType) { return nil } @@ -31266,6 +31374,9 @@ func (c *Checker) getIndexedMappedTypeSubstitutedTypeOfContextualType(t *Type, n } func (c *Checker) isExcludedMappedPropertyName(t *Type, propertyNameType *Type) bool { + if t.flags&TypeFlagsNegated != 0 { + return c.isTypeAssignableTo(propertyNameType, t.AsNegatedType().baseType) + } if t.flags&TypeFlagsConditional != 0 { return c.getReducedType(c.getTrueTypeFromConditionalType(t)).flags&TypeFlagsNever != 0 && c.getActualTypeVariable(c.getFalseTypeFromConditionalType(t)) == c.getActualTypeVariable(t.AsConditionalType().checkType) && @@ -31623,7 +31734,64 @@ func (c *Checker) hasTypeFacts(t *Type, mask TypeFacts) bool { return c.getTypeFacts(t, mask) != 0 } +func (c *Checker) getNegatedTypeFactsWorker(t *Type) TypeFacts { + // The facts of `not T` are the facts of "every value other than the values in T". Removing values + // from the universe can only remove facts that are unique to those values; all other facts remain + // possible. We therefore start from the broad `unknown` fact set and subtract only the facts implied + // solely by `t`. Note we do *not* reduce `t` to its base constraint, as a generic is *more specific* + // than the base type, meaning the set of values in the negated set is *larger* (and unknowable). + flags := t.flags + switch { + case flags&TypeFlagsNull != 0: + return TypeFactsUnknownFacts & ^(TypeFactsEQNull | TypeFactsEQUndefinedOrNull) + case flags&TypeFlagsUndefined != 0: + return TypeFactsUnknownFacts & ^(TypeFactsEQUndefined | TypeFactsEQUndefinedOrNull) + case flags&TypeFlagsString != 0: + return TypeFactsUnknownFacts & ^(TypeFactsTypeofEQString | TypeFactsCouldBeEmptyString) + case flags&TypeFlagsNumber != 0: + return TypeFactsUnknownFacts & ^(TypeFactsTypeofEQNumber | TypeFactsCouldBeZeroNumber) + case flags&TypeFlagsBigInt != 0: + return TypeFactsUnknownFacts & ^(TypeFactsTypeofEQBigInt | TypeFactsCouldBeZeroBigInt) + case flags&TypeFlagsBoolean != 0: + return TypeFactsUnknownFacts & ^(TypeFactsTypeofEQBoolean | TypeFactsCouldBeFalse) + case flags&TypeFlagsESSymbolLike != 0: + return TypeFactsUnknownFacts & ^TypeFactsTypeofEQSymbol + case flags&TypeFlagsStringLiteral != 0: + // `not ""` can still be any (non-empty) string, so it keeps all string facts and merely loses the + // ability to be the falsy empty string. Enum members are more specific than their literal value, so + // their negation does not imply the associated fact. + if flags&TypeFlagsEnumLiteral == 0 && getStringLiteralValue(t) == "" { + return TypeFactsUnknownFacts & ^TypeFactsCouldBeEmptyString + } + case flags&TypeFlagsNumberLiteral != 0: + if flags&TypeFlagsEnumLiteral == 0 && getNumberLiteralValue(t) == 0 { + return TypeFactsUnknownFacts & ^TypeFactsCouldBeZeroNumber + } + case flags&TypeFlagsBigIntLiteral != 0: + if isZeroBigInt(t) { + return TypeFactsUnknownFacts & ^TypeFactsCouldBeZeroBigInt + } + case flags&TypeFlagsBooleanLiteral != 0: + if t == c.falseType || t == c.regularFalseType { + return TypeFactsUnknownFacts & ^TypeFactsCouldBeFalse + } + } + // For every other type (non-empty string literals, non-zero numeric/bigint literals, `true`, objects, + // symbols, enum members, etc.) removing it from the universe removes no fact, since other values share + // all of its facts. Unions and intersections are hoisted out of the negation during construction. + return TypeFactsUnknownFacts +} + func (c *Checker) getTypeFactsWorker(t *Type, callerOnlyNeeds TypeFacts) TypeFacts { + if t.flags&TypeFlagsNegated != 0 { + return c.getNegatedTypeFactsWorker(t.AsNegatedType().baseType) + } + if t.flags&TypeFlagsIntersection != 0 && core.Some(t.Types(), isNegatedType) { + // An intersection that mentions a negated type must not be reduced to its base constraint below, + // since that discards the negated constituents (whose base constraint is `unknown`). Compute the + // facts from the constituents directly so the negations can refine the result. + return c.getIntersectionTypeFacts(t, callerOnlyNeeds) + } if t.flags&(TypeFlagsIntersection|TypeFlagsInstantiable) != 0 { t = c.getBaseConstraintOfType(t) if t == nil { @@ -31774,7 +31942,16 @@ func (c *Checker) getIntersectionTypeFacts(t *Type, callerOnlyNeeds TypeFacts) T andedFacts &= f } } - return oredFacts&TypeFactsOrFactsMask | andedFacts&TypeFactsAndFactsMask + result := oredFacts&TypeFactsOrFactsMask | andedFacts&TypeFactsAndFactsMask + // The per-falsy-value "could be" facts are AND-combined above (a value is in the intersection only if + // it is in every constituent). If none survive then no value in the intersection is falsy, so a Falsy + // fact that lingered only because each constituent was independently falsy-capable is spurious and gets + // removed. This is what lets `not "" & not 0 & not 0n & not null & not undefined & not false` be seen + // as purely truthy, and `string & not ""` reduce to the non-empty string facts. + if result&TypeFactsFalsy != 0 && result&TypeFactsAllCouldBeFalsy == 0 { + result &^= TypeFactsFalsy + } + return result } func isZeroBigInt(t *Type) bool { @@ -31804,6 +31981,22 @@ func (c *Checker) getAdjustedTypeWithFacts(t *Type, facts TypeFacts) *Type { reduced := c.recombineUnknownType(c.getTypeWithFacts(core.IfElse(c.strictNullChecks && t.flags&TypeFlagsUnknown != 0, c.unknownUnionType, t), facts)) if c.strictNullChecks { switch facts { + case TypeFactsEQUndefined, TypeFactsEQNull, TypeFactsEQUndefinedOrNull: + return c.mapType(reduced, func(t *Type) *Type { + if containsNegatedType(t) { + var nullableType *Type + switch facts { + case TypeFactsEQUndefined: + nullableType = c.undefinedType + case TypeFactsEQNull: + nullableType = c.nullType + default: + nullableType = c.getUnionType([]*Type{c.undefinedType, c.nullType}) + } + return c.getIntersectionType([]*Type{t, nullableType}) + } + return t + }) case TypeFactsNEUndefined: return c.removeNullableByIntersection(reduced, TypeFactsEQUndefined, TypeFactsEQNull, TypeFactsIsNull, c.nullType) case TypeFactsNENull: diff --git a/tsc/internal/checker/exports.go b/tsc/internal/checker/exports.go index 1a7afc78e9acb..ffedd16a9e9fe 100644 --- a/tsc/internal/checker/exports.go +++ b/tsc/internal/checker/exports.go @@ -325,6 +325,10 @@ func (c *Checker) GetReducedType(t *Type) *Type { return c.getReducedType(t) } +func (c *Checker) GetNegatedType(t *Type) *Type { + return c.getNegatedType(t) +} + // GetFullyQualifiedName returns the fully qualified name of a symbol, walking up // its parent chain (e.g. `"/path/to/module".Namespace.Name`). func (c *Checker) GetFullyQualifiedName(symbol *ast.Symbol) string { diff --git a/tsc/internal/checker/flow.go b/tsc/internal/checker/flow.go index d2831231772fe..4f2045ddd8f72 100644 --- a/tsc/internal/checker/flow.go +++ b/tsc/internal/checker/flow.go @@ -25,6 +25,13 @@ func (ft *FlowType) isNil() bool { return ft.t == nil } +func (c *Checker) getReducedFlowType(t *Type) *Type { + if t.flags&TypeFlagsUnion != 0 { + return c.getReducedType(t) + } + return t +} + func (c *Checker) newFlowType(t *Type, incomplete bool) FlowType { if incomplete && t.flags&TypeFlagsNever != 0 { t = c.silentNeverType @@ -88,10 +95,12 @@ func (c *Checker) getFlowTypeOfReferenceEx(reference *ast.Node, declaredType *Ty return declaredType } } + reducedDeclaredType := c.getReducedFlowType(declaredType) + reducedInitialType := c.getReducedFlowType(core.Coalesce(initialType, declaredType)) f := c.getFlowState() f.reference = reference - f.declaredType = declaredType - f.initialType = core.Coalesce(initialType, declaredType) + f.declaredType = reducedDeclaredType + f.initialType = reducedInitialType f.flowContainer = flowContainer f.sharedFlowStart = len(c.sharedFlows) c.flowInvocationCount++ @@ -196,6 +205,7 @@ func (c *Checker) getTypeAtFlowNode(f *FlowState, flow *ast.FlowNode) FlowType { // simply return the non-auto declared type to reduce follow-on errors. t = FlowType{t: c.convertAutoToAny(f.declaredType)} } + t = c.newFlowType(c.getReducedFlowType(t.t), t.incomplete) if sharedFlow != nil { // Record visited node and the associated type in the cache. c.sharedFlows = append(c.sharedFlows, SharedFlow{flow: sharedFlow, flowType: t}) @@ -217,6 +227,15 @@ func getBranchLabelAntecedents(flow *ast.FlowNode, reduceLabels []*ast.FlowReduc return flow.Antecedents } +// Compound assignments, updates, and compound-like assignments can change the value, so +// their flow types must generalize literal types and discard fresh negations describing +// the old value (e.g. 'number & not 0' before a decrement). This approximates the type +// after the operation without checking its expression here; regular negated constraints +// are preserved. +func (c *Checker) getTypeForCompoundAssignment(typeToGeneralize *Type) *Type { + return c.getBaseTypeOfLiteralType(c.removeFreshNegatedTypes(typeToGeneralize)) +} + func (c *Checker) getTypeAtFlowAssignment(f *FlowState, flow *ast.FlowNode) FlowType { node := flow.Node // Assignments only narrow the computed type if the declared type is a union type. Thus, we @@ -227,7 +246,7 @@ func (c *Checker) getTypeAtFlowAssignment(f *FlowState, flow *ast.FlowNode) Flow } if getAssignmentTargetKind(node) == AssignmentKindCompound { flowType := c.getTypeAtFlowNode(f, flow.Antecedent) - return c.newFlowType(c.getBaseTypeOfLiteralType(flowType.t), flowType.incomplete) + return c.newFlowType(c.getTypeForCompoundAssignment(flowType.t), flowType.incomplete) } if f.declaredType == c.autoType || f.declaredType == c.autoArrayType { if c.isEmptyArrayAssignment(node) { @@ -241,7 +260,7 @@ func (c *Checker) getTypeAtFlowAssignment(f *FlowState, flow *ast.FlowNode) Flow } t := f.declaredType if isInCompoundLikeAssignment(node) { - t = c.getBaseTypeOfLiteralType(t) + t = c.getTypeForCompoundAssignment(t) } if t.flags&TypeFlagsUnion != 0 { return FlowType{t: c.getAssignmentReducedType(t, c.getInitialOrAssignedType(f, flow))} @@ -375,6 +394,7 @@ func (c *Checker) getTypeAtFlowCondition(f *FlowState, flow *ast.FlowNode) FlowT // Narrow the given type based on the given expression having the assumed boolean value. The returned type // will be a subtype or the same type as the argument. func (c *Checker) narrowType(f *FlowState, t *Type, expr *ast.Node, assumeTrue bool) *Type { + t = c.getReducedFlowType(t) // for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a` if ast.IsExpressionOfOptionalChainRoot(expr) || ast.IsBinaryExpression(expr.Parent) && (expr.Parent.AsBinaryExpression().OperatorToken.Kind == ast.KindQuestionQuestionToken || expr.Parent.AsBinaryExpression().OperatorToken.Kind == ast.KindQuestionQuestionEqualsToken) && expr.Parent.AsBinaryExpression().Left == expr { return c.narrowTypeByOptionality(f, t, expr, assumeTrue) @@ -481,10 +501,10 @@ func (c *Checker) narrowTypeByBinaryExpression(f *FlowState, t *Type, expr *ast. return c.narrowTypeByTypeof(f, t, right.AsTypeOfExpression(), operator, left, assumeTrue) } if c.isMatchingReference(f.reference, left) { - return c.narrowTypeByEquality(t, operator, right, assumeTrue) + return c.narrowTypeByEquality(t, operator, right, assumeTrue, !ast.IsAccessExpression(f.reference)) } if c.isMatchingReference(f.reference, right) { - return c.narrowTypeByEquality(t, operator, left, assumeTrue) + return c.narrowTypeByEquality(t, operator, left, assumeTrue, !ast.IsAccessExpression(f.reference)) } if c.strictNullChecks { if c.optionalChainContainsReference(left, f.reference) { @@ -553,7 +573,30 @@ func (c *Checker) narrowTypeByBinaryExpression(f *FlowState, t *Type, expr *ast. return t } -func (c *Checker) narrowTypeByEquality(t *Type, operator ast.Kind, value *ast.Node, assumeTrue bool) *Type { +// Returns true if the type includes the "top" of the type hierarchy, or close enough to it - `unknown`, `{}`, and negated types and intersections thereof +// Used to determine if we should narrow to a literal type in `===` comparisons +func (c *Checker) typeIsTopInclusive(t *Type) bool { + if t.flags&TypeFlagsUnion != 0 { + return core.Some(t.Types(), c.typeIsTopInclusive) + } + if t.flags&TypeFlagsUnknown != 0 || c.IsEmptyAnonymousObjectType(t) { + return true + } + if t.flags&TypeFlagsNegated != 0 { + return true + } + if t.flags&TypeFlagsIntersection != 0 { + for _, t2 := range t.AsIntersectionType().Types() { + if !c.typeIsTopInclusive(t2) { + return false + } + } + return true + } + return false +} + +func (c *Checker) narrowTypeByEquality(t *Type, operator ast.Kind, value *ast.Node, assumeTrue bool, introduceNegation bool) *Type { if t.flags&TypeFlagsAny != 0 { return t } @@ -578,7 +621,7 @@ func (c *Checker) narrowTypeByEquality(t *Type, operator ast.Kind, value *ast.No return c.getAdjustedTypeWithFacts(t, facts) } if assumeTrue { - if !doubleEquals && (t.flags&TypeFlagsUnknown != 0 || someType(t, c.IsEmptyAnonymousObjectType)) { + if !doubleEquals && c.typeIsTopInclusive(t) { if valueType.flags&(TypeFlagsPrimitive|TypeFlagsNonPrimitive) != 0 || c.IsEmptyAnonymousObjectType(valueType) { return valueType } @@ -604,9 +647,19 @@ func (c *Checker) narrowTypeByEquality(t *Type, operator ast.Kind, value *ast.No return filteredType } } - return c.filterType(t, func(t *Type) bool { + filtered := c.filterType(t, func(t *Type) bool { return !(c.isUnitLikeType(t) && c.areTypesComparable(t, valueType)) }) + // In the false branch of a strict literal comparison, introduce a fresh negation so that a base + // type that overlaps the compared value records the exclusion. For example, the else branch of + // 'n === 0' where 'n: number' produces 'number & not 0'. The negation reduces away for + // constituents already disjoint from the value (e.g. 'string & not 0' -> 'string'). We restrict + // this to strict '==='/'!==' because loose '=='/'!=' coerces operands, so excluding a single + // literal would not soundly capture the comparison's semantics. + if introduceNegation && !doubleEquals { + return c.introduceNegationIntoNarrowedType(filtered, valueType) + } + return filtered } return t } @@ -651,7 +704,32 @@ func (c *Checker) narrowTypeByLiteralExpression(t *Type, literal *ast.LiteralExp if !ok { facts = TypeFactsTypeofNEHostObject } - return c.getAdjustedTypeWithFacts(t, facts) + result := c.getAdjustedTypeWithFacts(t, facts) + if impliedType := c.getImpliedTypeForTypeofNegation(literal.Text()); impliedType != nil { + result = c.introduceNegationIntoNarrowedType(result, impliedType) + } + return result +} + +// getImpliedTypeForTypeofNegation returns the primitive type that a value is known *not* to be in the +// false branch of a 'typeof x === "..."' check, or nil for typeof names whose negation isn't a simple +// primitive. It is used to introduce negated types (e.g. 'not string') during control flow narrowing. +func (c *Checker) getImpliedTypeForTypeofNegation(typeName string) *Type { + switch typeName { + case "string": + return c.stringType + case "number": + return c.numberType + case "bigint": + return c.bigintType + case "boolean": + return c.booleanType + case "symbol": + return c.esSymbolType + case "undefined": + return c.undefinedType + } + return nil } func (c *Checker) narrowTypeByTypeName(t *Type, typeName string) *Type { @@ -684,6 +762,17 @@ func (c *Checker) narrowTypeByTypeName(t *Type, typeName string) *Type { func (c *Checker) narrowTypeByTypeFacts(t *Type, impliedType *Type, facts TypeFacts) *Type { return c.mapType(t, func(t *Type) *Type { + if t.flags&TypeFlagsIntersection != 0 && containsFreshNegatedType(t) { + return c.getIntersectionType(append(core.Map(t.Types(), func(t *Type) *Type { + if isFreshNegatedType(t) { + if c.typesAreInDisjointDomainsIncludingObjects(impliedType, t.AsNegatedType().baseType) { + return c.unknownType + } + return t + } + return c.narrowTypeByTypeFacts(t, impliedType, facts) + }), impliedType)) + } switch { case c.isTypeRelatedTo(t, impliedType, c.strictSubtypeRelation): if c.hasTypeFacts(t, facts) { @@ -718,7 +807,12 @@ func (c *Checker) narrowTypeByDiscriminantProperty(t *Type, access *ast.Node, op } } return c.narrowTypeByDiscriminant(t, access, func(t *Type) *Type { - return c.narrowTypeByEquality(t, operator, value, assumeTrue) + // When narrowing a discriminant property, the narrowed property type is only used for a + // comparability test against each constituent's discriminant. Introducing a negated type here + // would produce a structurally different (though semantically equivalent) negation that + // 'areTypesComparable' may fail to relate to a constituent's existing negated discriminant, so + // we suppress negation introduction on this path. + return c.narrowTypeByEquality(t, operator, value, assumeTrue, false /*introduceNegation*/) }) } @@ -856,12 +950,29 @@ func (c *Checker) getNarrowedType(t *Type, candidate *Type, assumeTrue bool, che return narrowedType } +// introduceNegationIntoNarrowedType intersects each constituent of a control-flow-narrowed type with +// 'not candidate' in the false branch of a narrowing check. The resulting negated intersections are +// reduced away by getIntersectionType when redundant (e.g. 'number & not string' -> 'number'), so this +// only meaningfully affects narrowings whose base type overlaps the removed candidate (such as '{}', +// 'unknown', 'object', or a type parameter). For example, narrowing '{}' in the false branch of +// 'typeof x === "string"' produces '{} & not string'. +func (c *Checker) introduceNegationIntoNarrowedType(t *Type, candidate *Type) *Type { + if t.flags&TypeFlagsNever != 0 || candidate.flags&TypeFlagsNever != 0 { + return t + } + return c.getIntersectionType([]*Type{t, c.getFreshNegatedType(candidate)}) +} + func (c *Checker) getNarrowedTypeWorker(t *Type, candidate *Type, assumeTrue bool, checkDerived bool) *Type { if !assumeTrue { if t == candidate { return c.neverType } if checkDerived { + // 'instanceof' (and other prototype-based) narrowing is nominal, so we deliberately do not + // introduce a structural 'not candidate' here. Many class types lack nominal tags and are + // structural subtypes of one another (e.g. 'Derived2' structurally extends 'Derived1'), so a + // structural negation would unsoundly reduce a nominally-kept constituent to never. return c.filterType(t, func(t *Type) bool { return !c.isTypeDerivedFrom(t, candidate) }) @@ -1170,9 +1281,20 @@ func (c *Checker) narrowTypeBySwitchOnTypeOf(t *Type, data *ast.FlowSwitchClause if hasDefaultClause { // In the default clause we filter constituents down to those that are not-equal to all handled cases. notEqualFacts := c.getNotEqualFactsFromTypeofSwitch(clauseStart, clauseEnd, witnesses) - return c.filterType(t, func(t *Type) bool { + filtered := c.filterType(t, func(t *Type) bool { return c.getTypeFacts(t, notEqualFacts) == notEqualFacts }) + // Mirror the false branch of `if (typeof x === "...")`: introduce a fresh `not ` + // for each handled case whose negation is a simple primitive, so that a base type overlapping + // those primitives (such as `{}` or a type parameter) records the exclusion. + for i, witness := range witnesses { + if (i < clauseStart || i >= clauseEnd) && witness != "" { + if impliedType := c.getImpliedTypeForTypeofNegation(witness); impliedType != nil { + filtered = c.introduceNegationIntoNarrowedType(filtered, impliedType) + } + } + } + return filtered } // In the non-default cause we create a union of the type narrowed by each of the listed cases. clauseWitnesses := witnesses[clauseStart:clauseEnd] @@ -1311,11 +1433,11 @@ func (c *Checker) getTypeAtFlowBranchLabel(f *FlowState, flow *ast.FlowNode, ant // At flow control branch or loop junctions, if the type along every antecedent code path // is an evolving array type, we construct a combined evolving array type. Otherwise we // finalize all evolving array types. -func (c *Checker) getUnionOrEvolvingArrayType(f *FlowState, types []*Type, subtypeReduction UnionReduction) *Type { +func (c *Checker) getUnionOrEvolvingArrayType(f *FlowState, types []*Type, unionReduction UnionReduction) *Type { if isEvolvingArrayTypeList(types) { return c.getEvolvingArrayType(c.getUnionType(core.Map(types, c.getElementTypeOfEvolvingArrayType))) } - result := c.recombineUnknownType(c.getUnionTypeEx(core.SameMap(types, c.finalizeEvolvingArrayType), subtypeReduction, nil, nil)) + result := c.recombineUnknownType(c.getReducedType(c.getUnionTypeEx(core.SameMap(types, c.finalizeEvolvingArrayType), unionReduction, nil, nil))) if result != f.declaredType && result.flags&f.declaredType.flags&TypeFlagsUnion != 0 && slices.Equal(result.AsUnionType().types, f.declaredType.AsUnionType().types) { return f.declaredType } @@ -1909,6 +2031,18 @@ func (c *Checker) replacePrimitivesWithLiterals(typeWithPrimitives *Type, typeWi c.maybeTypeOfKind(typeWithLiterals, TypeFlagsStringLiteral|TypeFlagsTemplateLiteral|TypeFlagsStringMapping|TypeFlagsNumberLiteral|TypeFlagsBigIntLiteral) { return c.mapType(typeWithPrimitives, func(t *Type) *Type { switch { + case t.flags&TypeFlagsIntersection != 0 && containsFreshNegatedType(t): + result := c.getIntersectionType(core.Map(t.Types(), func(t *Type) *Type { + return c.replacePrimitivesWithLiterals(t, typeWithLiterals) + })) + return c.mapType(result, func(reduced *Type) *Type { + if someType(typeWithLiterals, func(literal *Type) bool { + return isFreshLiteralType(literal) && c.getRegularTypeOfLiteralType(literal) == reduced + }) { + return c.getFreshTypeOfLiteralType(reduced) + } + return reduced + }) case t.flags&TypeFlagsString != 0: return c.extractTypesOfKind(typeWithLiterals, TypeFlagsString|TypeFlagsStringLiteral|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) case c.isPatternLiteralType(t) && !c.maybeTypeOfKind(typeWithLiterals, TypeFlagsString|TypeFlagsTemplateLiteral|TypeFlagsStringMapping): @@ -2397,6 +2531,7 @@ func (c *Checker) getTypeWithDefault(t *Type, defaultExpression *ast.Node) *Type // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean, // we remove type string. func (c *Checker) getAssignmentReducedType(declaredType *Type, assignedType *Type) *Type { + assignedType = c.getReducedType(assignedType) if declaredType == assignedType { return declaredType } diff --git a/tsc/internal/checker/inference.go b/tsc/internal/checker/inference.go index 02c7d009b9ec5..4fd6800853f87 100644 --- a/tsc/internal/checker/inference.go +++ b/tsc/internal/checker/inference.go @@ -141,6 +141,10 @@ func (c *Checker) inferFromTypes(n *InferenceState, source *Type, target *Type) } source = c.getIntersectionType(sources) target = c.getIntersectionType(targets) + if getInferenceInfoForType(n, target) != nil { + c.inferWithPriority(n, source, target, InferencePriorityNakedTypeVariable) + return + } } } if target.flags&(TypeFlagsIndexedAccess|TypeFlagsSubstitution) != 0 { @@ -240,6 +244,11 @@ func (c *Checker) inferFromTypes(n *InferenceState, source *Type, target *Type) if source.symbol == target.symbol { c.inferFromTypes(n, source.AsStringMappingType().target, target.AsStringMappingType().target) } + case source.flags&TypeFlagsNegated != 0 && target.flags&TypeFlagsNegated != 0: + // Infer from 'not S' to 'not T' by inferring from the base type S to the base type T. + // Negation reverses subtyping (S <: T implies 'not T' <: 'not S'), so the base types + // occupy a contravariant position and inference is flipped accordingly. + c.inferFromContravariantTypes(n, source.AsNegatedType().baseType, target.AsNegatedType().baseType) case source.flags&TypeFlagsSubstitution != 0: c.inferFromTypes(n, source.AsSubstitutionType().baseType, target) // Make substitute inference at a lower priority @@ -719,6 +728,12 @@ func (c *Checker) inferFromObjectTypes(n *InferenceState, source *Type, target * if target.objectFlags&ObjectFlagsMapped != 0 && target.AsMappedType().declaration.NameType == nil { constraintType := c.getConstraintTypeFromMappedType(target) if c.inferToMappedType(n, source, target, constraintType) { + if constraintType.flags&TypeFlagsUnion != 0 { + savePriority := n.priority + n.priority |= InferencePriorityMappedTypeConstraint + c.inferFromProperties(n, source, target) + n.priority = savePriority + } return } } diff --git a/tsc/internal/checker/negated.go b/tsc/internal/checker/negated.go new file mode 100644 index 0000000000000..59d0a1a0eccdd --- /dev/null +++ b/tsc/internal/checker/negated.go @@ -0,0 +1,373 @@ +package checker + +import ( + "slices" + + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +// newNegatedType creates a new negated type 'not baseType'. +func (c *Checker) newNegatedType(baseType *Type, flags ObjectFlags) *Type { + data := &NegatedType{} + data.baseType = baseType + return c.newType(TypeFlagsNegated, flags, data.AsType(), typeKindNegated) +} + +// getNegatedType constructs the type 'not T', applying the negation identities: +// +// not any => any +// not unknown => never +// not never => unknown +// not not T => T +// not (A | B) => not A & not B (De Morgan) +// +// All other types are wrapped in a (cached) NegatedType. +func (c *Checker) getNegatedType(t *Type) *Type { + switch { + case t.flags&TypeFlagsAny != 0: + return t + case t.flags&TypeFlagsUnknown != 0: + return c.neverType + case t.flags&TypeFlagsNever != 0: + return c.unknownType + case t.flags&TypeFlagsNegated != 0: + return t.AsNegatedType().baseType + case t.flags&TypeFlagsUnion != 0: + return c.getIntersectionType(core.Map(t.Types(), c.getNegatedType)) + } + if cached := c.negatedTypes[t.id]; cached != nil { + return cached + } + result := c.newNegatedType(t, ObjectFlagsNone) + result.AsNegatedType().regularType = result + result.AsNegatedType().freshType = c.newNegatedType(t, ObjectFlagsFreshNegated) + result.AsNegatedType().freshType.AsNegatedType().regularType = result + result.AsNegatedType().freshType.AsNegatedType().freshType = result.AsNegatedType().freshType + c.negatedTypes[t.id] = result + return result +} + +// getFreshNegatedType is like getNegatedType, but the leaf negated types it constructs are marked +// fresh (ObjectFlagsFreshNegated). Fresh negated types are those introduced by control flow +// narrowing (as opposed to written explicitly by the user); they are widened away by getWidenedType +// when a narrowed type escapes into an inferred declaration, so they never leak into emitted +// declaration files. +func (c *Checker) getFreshNegatedType(t *Type) *Type { + if t.flags&TypeFlagsUnion != 0 { + return c.getIntersectionType(core.Map(t.Types(), c.getFreshNegatedType)) + } + negated := c.getNegatedType(t) + if negated.flags&TypeFlagsNegated == 0 { + return negated + } + return negated.AsNegatedType().freshType +} + +// isFreshNegatedType reports whether t is a fresh negated type introduced by control flow narrowing. +func isFreshNegatedType(t *Type) bool { + return t.flags&TypeFlagsNegated != 0 && t.objectFlags&ObjectFlagsFreshNegated != 0 +} + +// containsFreshNegatedType reports whether t is a fresh negated type or (transitively) contains one +// within a union or intersection. ObjectFlagsFreshNegated is a TypeFlagsNegated-only flag (its bit +// is reused for other meanings on unions and intersections), so it must never be read directly on a +// container type; this helper recurses instead. +func containsFreshNegatedType(t *Type) bool { + if isFreshNegatedType(t) { + return true + } + if t.flags&TypeFlagsUnionOrIntersection != 0 { + return core.Some(t.Types(), containsFreshNegatedType) + } + return false +} + +// containsNegatedType reports whether t is a negated type or (transitively) contains one within a +// union or intersection. It is used to decide whether a location wants a negation (and should +// therefore preserve a fresh control-flow negation rather than widening it away). +func containsNegatedType(t *Type) bool { + if t == nil { + return false + } + if t.flags&TypeFlagsNegated != 0 { + return true + } + if t.flags&TypeFlagsUnionOrIntersection != 0 { + return core.Some(t.Types(), containsNegatedType) + } + return false +} + +// removeFreshNegatedTypes strips fresh negated types (introduced by control flow narrowing) from t. +// It is used at inference barriers that do not go through getWidenedType (such as inferred type +// predicates) so that a CFA-introduced 'not X' never leaks into an inferred declaration. +func (c *Checker) removeFreshNegatedTypes(t *Type) *Type { + if !containsFreshNegatedType(t) { + return t + } + if isFreshNegatedType(t) { + return c.unknownType + } + if t.flags&TypeFlagsUnion != 0 { + return c.getUnionType(core.Map(t.Types(), c.removeFreshNegatedTypes)) + } + if t.flags&TypeFlagsIntersection != 0 { + return c.getIntersectionType(core.Map(t.Types(), c.removeFreshNegatedTypes)) + } + return t +} + +func (c *Checker) getRegularNegatedTypes(t *Type) *Type { + if !containsFreshNegatedType(t) { + return t + } + return c.mapType(t, func(t *Type) *Type { + if t.flags&TypeFlagsNegated != 0 { + return t.AsNegatedType().regularType + } + if t.flags&TypeFlagsIntersection != 0 { + return c.getIntersectionType(core.Map(t.Types(), c.getRegularNegatedTypes)) + } + return t + }) +} + +func (c *Checker) removeOrRegularizeNegatedTypes(t *Type, remove bool) *Type { + if remove { + return c.removeFreshNegatedTypes(t) + } + return c.getRegularNegatedTypes(t) +} + +// removeComplementaryNegatedTypes replaces 'Base & not C' with 'Base' when another branch covers +// 'Base & C'. That branch is retained unless it is also contained in Base. Removing one negation +// at a time preserves shared negative factors and allows successive reductions, for example +// '(T & A) | (T & B) | (T & not A & not B)' to '(T & A) | (T & B) | (T & not B)' and then 'T'. +// +// The input slice is assumed to be sorted (per CompareTypes); the result remains sorted. +func (c *Checker) removeComplementaryNegatedTypes(types []*Type) []*Type { + for index := 0; index < len(types); index++ { + candidate := types[index] + if candidate.flags&TypeFlagsIntersection == 0 || !core.Some(candidate.Types(), isNegatedType) { + continue + } + for _, negated := range candidate.Types() { + if !isNegatedType(negated) { + continue + } + base := c.getIntersectionType(core.Filter(candidate.Types(), func(member *Type) bool { return member != negated })) + positiveHalf := c.getIntersectionType([]*Type{base, negated.AsNegatedType().baseType}) + covered := false + for otherIndex, positive := range types { + if otherIndex != index && c.isTypeSubtypeOf(positiveHalf, positive) { + covered = true + break + } + } + if !covered { + continue + } + reducedTypes := make([]*Type, 0, len(types)) + for otherIndex, other := range types { + if otherIndex != index && !c.isTypeSubtypeOf(other, base) { + reducedTypes = append(reducedTypes, other) + } + } + types, _ = insertType(reducedTypes, base) + index = -1 + break + } + } + if core.Some(types, isNegatedType) { + if c.checkForSaturatedNegatedType(types) { + return []*Type{c.unknownType} + } + } + return types +} + +// checkForUnsatisfiedNegatedType returns true if the intersection in typeSet is empty (never) +// because some non-negated member is a subtype of the union of the negated members' base types. +// For example, in '"w" & not string' the non-negated member '"w"' is a subtype of 'string' +// (the base type of 'not string'), so the intersection reduces to never. +// During effective-constraint construction, only identity and union membership may be used: +// subtype checking can re-enter construction of the same effective constraint with a fresh relater. +func (c *Checker) checkForUnsatisfiedNegatedType(typeSet []*Type, flags IntersectionFlags) bool { + nonNegatedSet := core.Filter(typeSet, func(t *Type) bool { return t.flags&TypeFlagsNegated == 0 }) + if len(nonNegatedSet) == 0 { + return false + } + isSubtype := c.isTypeSubtypeOf + unionReduction := UnionReductionLiteral + if flags&IntersectionFlagsNoConstraintReduction != 0 { + isSubtype = c.isTypeSubsetOf + unionReduction = UnionReductionNone + } + negatedBounds := c.getUnionTypeEx(core.Map(core.Filter(typeSet, isNegatedType), func(t *Type) *Type { + return t.AsNegatedType().baseType + }), unionReduction, nil, nil) + for _, nonNegatedType := range nonNegatedSet { + if isSubtype(nonNegatedType, negatedBounds) { + return true + } + } + return false +} + +// checkForSaturatedNegatedType returns true if the union in typeSet covers every value (i.e. is the +// unknown type) because it contains a type and its complement. This is the union converse of +// checkForUnsatisfiedNegatedType: when a negated member 'not B' is combined with non-negated members +// whose union is a supertype of 'B', the non-negated part covers 'B' and 'not B' covers everything +// else, so the union is unknown. For example, 'T | not T' reduces to unknown, and 'string | not "w"' +// reduces to unknown because '"w"' is a subtype of 'string'. +func (c *Checker) checkForSaturatedNegatedType(typeSet []*Type) bool { + nonNegatedSet := core.Filter(typeSet, func(t *Type) bool { return t.flags&TypeFlagsNegated == 0 }) + if len(nonNegatedSet) == 0 { + return false + } + nonNegatedUnion := c.getUnionType(nonNegatedSet) + for _, negatedType := range core.Filter(typeSet, isNegatedType) { + if c.isTypeSubtypeOf(negatedType.AsNegatedType().baseType, nonNegatedUnion) { + return true + } + } + return false +} + +// removeNegatedSubtypes removes redundant negated members from an intersection. A member 'not X' +// is redundant when the combined non-negated part of the intersection is already a subtype of +// 'not X' (i.e. it is disjoint from X). For example, in 'false & not true' the non-negated part +// 'false' is a subtype of 'not true', so 'not true' is dropped, leaving just 'false'. +// +// A member 'not X' is also redundant when the non-negated part is mutually exclusive with X by +// virtue of a shared discriminant property (see objectTypesAreDisjointByProperties). For example, given +// discriminated types 'A = { kind: "a" }' and 'C = { kind: "c" }', the intersection 'C & not A' +// reduces to 'C' because no value of type C can be an A. +func (c *Checker) removeNegatedSubtypes(types []*Type) []*Type { + if len(types) == 0 { + return types + } + nonNegatedBounds := core.Filter(types, func(t *Type) bool { return t.flags&TypeFlagsNegated == 0 }) + if len(nonNegatedBounds) == 0 { + return types + } + nonNegativePart := c.getIntersectionType(nonNegatedBounds) + for i := range slices.Backward(types) { + if types[i].flags&TypeFlagsNegated == 0 { + continue + } + negatedBase := types[i].AsNegatedType().baseType + if isFreshNegatedType(types[i]) && c.typesAreInDisjointDomainsIncludingObjects(nonNegativePart, negatedBase) || c.objectTypesAreDisjointByProperties(nonNegativePart, negatedBase, false /*sourceIsClosed*/) || c.isTypeSubtypeOf(nonNegativePart, types[i]) { + types = slices.Delete(types, i, i+1) + } + } + return types +} + +// objectTypesAreDisjointByProperties reports whether 'source' and 'target' are provably mutually +// exclusive because they share a property whose types are in disjoint domains, or a discriminant +// property whose types have an empty (never) intersection. When sourceIsClosed is true, a required +// target property that cannot be supplied by the source also proves disjointness. +// For example '{ kind: "c" }' and '{ kind: "a" }' are disjoint by their 'kind' property, so +// 'C & not A' reduces to 'C'. +// +// Discriminant properties are located with isDiscriminantProperty over the union 'a | b' -- the +// same mechanism used for discriminated-union narrowing -- and disjointness of a single discriminant +// is decided by intersecting the two property types and checking for never. Other shared properties, +// including properties matched by an index signature, are only compared by their primitive domains, +// avoiding recursive intersections of object types. +// Deciding discriminant disjointness by intersecting the property types (rather than comparing them +// by identity) is important: an enum +// literal such as 'E.A' (where 'enum E { A = "a" }') is a distinct type from the string literal '"a"' +// yet is not mutually exclusive with it, so 'E.A & "a"' is not never. +// +// Only the (small, literal) discriminant property types are intersected here, never the full input +// types, so this stays cheap and avoids the circularities a general 'a & b is never' computation +// would risk during intersection construction. +func (c *Checker) objectTypesAreDisjointByProperties(source *Type, target *Type, sourceIsClosed bool) bool { + if source.flags&(TypeFlagsStructuredType|TypeFlagsPrimitive|TypeFlagsNonPrimitive) == 0 || target.flags&(TypeFlagsStructuredType|TypeFlagsPrimitive|TypeFlagsNonPrimitive) == 0 { + return false + } + union := c.getUnionType([]*Type{source, target}) + if union.flags&TypeFlagsUnion == 0 { + // 'source' and 'target' collapsed into a single type (e.g. one is a subtype of the other), so there is + // no discriminant to distinguish them. + return false + } + for _, prop := range c.getPropertiesOfType(source) { + sourcePropType := c.getTypeOfPropertyOfType(source, prop.Name()) + targetProp := c.getPropertyOfType(target, prop.Name()) + var targetPropType *Type + if targetProp != nil { + targetPropType = c.getTypeOfSymbol(targetProp) + } + if targetPropType == nil { + if indexInfo := c.getApplicableIndexInfoForName(target, prop.Name()); indexInfo != nil { + targetPropType = indexInfo.valueType + } + } + if sourcePropType == nil || targetPropType == nil { + continue + } + if (isRequiredProperty(prop) || isRequiredProperty(targetProp)) && + (typesAreInDisjointDomains(sourcePropType, targetPropType) || + c.isDiscriminantProperty(union, prop.Name()) && c.getIntersectionType([]*Type{sourcePropType, targetPropType}).flags&TypeFlagsNever != 0) { + return true + } + } + if sourceIsClosed { + for _, targetProp := range c.getUnmatchedProperties(source, target, false /*requireOptionalProperties*/, false /*matchDiscriminantProperties*/) { + sourceIndex := c.getApplicableIndexInfoForName(source, targetProp.Name()) + if sourceIndex == nil || typesAreInDisjointDomains(sourceIndex.valueType, c.getTypeOfSymbol(targetProp)) { + return true + } + } + } + return false +} + +func typesAreInDisjointDomains(a *Type, b *Type) bool { + aDomains := a.flags & TypeFlagsDisjointDomains + bDomains := b.flags & TypeFlagsDisjointDomains + return aDomains != 0 && bDomains != 0 && aDomains&bDomains == 0 +} + +func (c *Checker) typesAreInDisjointDomainsIncludingObjects(a *Type, b *Type) bool { + aDomains := c.getTypeDomains(a) + bDomains := c.getTypeDomains(b) + return aDomains != 0 && bDomains != 0 && aDomains&bDomains == 0 +} + +func (c *Checker) getTypeDomains(t *Type) TypeFlags { + var domains TypeFlags + if t.flags&TypeFlagsStringLike != 0 { + domains |= TypeFlagsString + } + if t.flags&TypeFlagsNumberLike != 0 { + domains |= TypeFlagsNumber + } + if t.flags&TypeFlagsBigIntLike != 0 { + domains |= TypeFlagsBigInt + } + if t.flags&TypeFlagsBooleanLike != 0 { + domains |= TypeFlagsBoolean + } + if t.flags&TypeFlagsESSymbolLike != 0 { + domains |= TypeFlagsESSymbol + } + if t.flags&TypeFlagsVoidLike != 0 { + domains |= TypeFlagsVoid + } + if t.flags&TypeFlagsNull != 0 { + domains |= TypeFlagsNull + } + if t.flags&(TypeFlagsObject|TypeFlagsNonPrimitive) != 0 && !c.IsEmptyAnonymousObjectType(t) { + domains |= TypeFlagsNonPrimitive + } + return domains +} + +func isRequiredProperty(prop *ast.Symbol) bool { + return prop != nil && prop.Flags()&ast.SymbolFlagsOptional == 0 && prop.CheckFlags()&ast.CheckFlagsPartial == 0 +} diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index 3d84ff3bd4094..3569280f5afbc 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -3675,6 +3675,11 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode { if t.flags&TypeFlagsConditional != 0 { return b.visitAndTransformType(t, (*NodeBuilderImpl).conditionalTypeToTypeNode) } + if t.flags&TypeFlagsNegated != 0 { + b.ctx.approximateLength += 4 + baseTypeNode := b.typeToTypeNode(t.AsNegatedType().baseType) + return b.f.NewTypeOperatorNode(ast.KindNotKeyword, baseTypeNode) + } if t.flags&TypeFlagsSubstitution != 0 { typeNode := b.typeToTypeNode(t.AsSubstitutionType().baseType) if !b.ch.isNoInferType(t) { diff --git a/tsc/internal/checker/relater.go b/tsc/internal/checker/relater.go index d3b6c86014498..c8c41a2d8f3d6 100644 --- a/tsc/internal/checker/relater.go +++ b/tsc/internal/checker/relater.go @@ -1083,7 +1083,8 @@ func (c *Checker) isDiscriminantProperty(t *Type, name string) bool { if prop != nil && prop.CheckFlags()&ast.CheckFlagsSyntheticProperty != 0 { if prop.CheckFlags()&ast.CheckFlagsIsDiscriminantComputed == 0 { prop.SetCheckFlags(prop.CheckFlags() | ast.CheckFlagsIsDiscriminantComputed) - if prop.CheckFlags()&ast.CheckFlagsNonUniformAndLiteral == ast.CheckFlagsNonUniformAndLiteral && !c.isGenericType(c.getTypeOfSymbol(prop)) { + pt := c.getTypeOfSymbol(prop) + if prop.CheckFlags()&ast.CheckFlagsNonUniformAndLiteral == ast.CheckFlagsNonUniformAndLiteral && !c.isGenericType(pt) { prop.SetCheckFlags(prop.CheckFlags() | ast.CheckFlagsIsDiscriminant) } } @@ -2317,7 +2318,7 @@ func (c *Checker) getEffectiveConstraintOfIntersection(types []*Type, targetIsUn var constraints []*Type hasDisjointDomainType := false for _, t := range types { - if t.flags&TypeFlagsInstantiable != 0 { + if t.flags&TypeFlagsInstantiable != 0 && t.flags&TypeFlagsNegated == 0 { // We keep following constraints as long as we have an instantiable type that is known // not to be circular or infinite (hence we stop on index access types). constraint := c.getConstraintOfType(t) @@ -2330,7 +2331,7 @@ func (c *Checker) getEffectiveConstraintOfIntersection(types []*Type, targetIsUn constraints = append(constraints, t) } } - } else if t.flags&TypeFlagsDisjointDomains != 0 || c.IsEmptyAnonymousObjectType(t) { + } else if t.flags&(TypeFlagsDisjointDomains|TypeFlagsNegated) != 0 || c.IsEmptyAnonymousObjectType(t) { hasDisjointDomainType = true } } @@ -2341,7 +2342,7 @@ func (c *Checker) getEffectiveConstraintOfIntersection(types []*Type, targetIsUn // We add any types belong to one of the disjoint domains because they might cause the final // intersection operation to reduce the union constraints. for _, t := range types { - if t.flags&TypeFlagsDisjointDomains != 0 || c.IsEmptyAnonymousObjectType(t) { + if t.flags&(TypeFlagsDisjointDomains|TypeFlagsNegated) != 0 || c.IsEmptyAnonymousObjectType(t) { constraints = append(constraints, t) } } @@ -2919,7 +2920,7 @@ func (r *Relater) unionOrIntersectionRelatedTo(source *Type, target *Type, repor // appear to be comparable to '2'. if r.relation == r.c.comparableRelation && target.flags&TypeFlagsPrimitive != 0 { constraints := core.SameMap(source.Types(), func(t *Type) *Type { - if t.flags&TypeFlagsInstantiable != 0 { + if t.flags&(TypeFlagsInstantiable & ^TypeFlagsNegated) != 0 { constraint := r.c.getBaseConstraintOfType(t) if constraint != nil { return constraint @@ -2946,7 +2947,25 @@ func (r *Relater) unionOrIntersectionRelatedTo(source *Type, target *Type, repor // Don't report errors though. Elaborating on whether a source constituent is related to the target is // not actually useful and leads to some confusing error messages. Instead, we rely on the caller // checking whether the full intersection viewed as an object is related to the target. - return r.someTypeRelatedToType(source, target, false /*reportErrors*/, IntersectionStateSource) + result := r.someTypeRelatedToType(source, target, false /*reportErrors*/, IntersectionStateSource) + if r.relation == r.c.comparableRelation { + // In the comparable relation we may have, e.g., 'string & not "a"' being related to '"a"' because + // 'string' and '"a"' are usually comparable - it's only the additional domain limiting provided by + // the negated intersection that narrows further. So we collect the negated domain bits and check + // that the target is comparable with each. If there's any negated domain bit for which it's not + // comparable, then the intersection as a whole shouldn't be comparable. + for _, negation := range source.Types() { + if negation.flags&TypeFlagsNegated == 0 { + continue + } + rel := r.isRelatedTo(target, negation, RecursionFlagsTarget, false /*reportErrors*/) + result &= rel + if result == TernaryFalse { + break + } + } + } + return result } func (r *Relater) someTypeRelatedToType(source *Type, target *Type, reportErrors bool, intersectionState IntersectionState) Ternary { @@ -3398,6 +3417,9 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo if source.AsStringMappingType().Symbol() == target.AsStringMappingType().Symbol() { return r.isRelatedTo(source.AsStringMappingType().target, target.AsStringMappingType().target, RecursionFlagsBoth, false /*reportErrors*/) } + case source.flags&TypeFlagsNegated != 0: + // 'not S' is identical to 'not T' if S is identical to T. + return r.isRelatedTo(source.AsNegatedType().baseType, target.AsNegatedType().baseType, RecursionFlagsBoth, false /*reportErrors*/) } if source.flags&TypeFlagsObject == 0 { return TernaryFalse @@ -3453,6 +3475,46 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo } } switch { + case target.flags&TypeFlagsNegated != 0: + if source.flags&TypeFlagsNegated != 0 { + // 'not S' is related to 'not T' if T is related to S. + return r.isRelatedTo(target.AsNegatedType().baseType, source.AsNegatedType().baseType, RecursionFlagsBoth, reportErrors) + } + // A type S is related to 'not T' if S and T are disjoint, i.e. S & T is never. + if r.c.getIntersectionType([]*Type{source, target.AsNegatedType().baseType}).flags&TypeFlagsNever != 0 { + return TernaryTrue + } + // A fresh object literal type is treated as a closed set of values that have exactly the + // declared properties. Such a type is disjoint from T (and thus related to 'not T') when it + // isn't related to T and their property domains cannot overlap. The latter check is the dual + // of relating a property union to a discriminated union: under negation, any overlap with the + // negated base prevents the source from relating to the complement. + if isObjectLiteralType(source) { + regularSource := r.c.getRegularTypeOfObjectLiteral(source) + negatedBase := target.AsNegatedType().baseType + switch r.isRelatedTo(regularSource, negatedBase, RecursionFlagsBoth, false /*reportErrors*/) { + case TernaryFalse: + if r.c.objectTypesAreDisjointByProperties(regularSource, negatedBase, true /*sourceIsClosed*/) { + return TernaryTrue + } + return TernaryFalse + case TernaryMaybe: + return TernaryMaybe + default: + return TernaryFalse + } + } + // Otherwise, if the source is a concrete (non-instantiable) type, it isn't assignable to 'not T'. + // For comparability, however, S overlaps with 'not T' unless every value in S is excluded by T. + // We must not fall through to the generic instantiable handling below, which would relate S to the + // (permissive) constraint of the negated type and incorrectly report relatedness. For instantiable + // sources we do fall through, so that constraint-based reasoning can still apply. + if source.flags&TypeFlagsInstantiable == 0 { + if r.relation == r.c.comparableRelation && !r.c.isTypeSubtypeOf(source, target.AsNegatedType().baseType) { + return TernaryTrue + } + return TernaryFalse + } case target.flags&TypeFlagsTypeParameter != 0: // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. if source.objectFlags&ObjectFlagsMapped != 0 && source.AsMappedType().declaration.NameType == nil && r.isRelatedTo(r.c.getIndexType(target), r.c.getConstraintTypeFromMappedType(source), RecursionFlagsBoth, false) != TernaryFalse { @@ -3554,7 +3616,8 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo nameType := r.c.getNameTypeFromMappedType(targetType) constraintType := r.c.getConstraintTypeFromMappedType(targetType) var targetKeys *Type - if nameType != nil && r.c.isMappedTypeWithKeyofConstraintDeclaration(targetType) { + isRemappedKeyof := nameType != nil && r.c.isMappedTypeWithKeyofConstraintDeclaration(targetType) + if isRemappedKeyof { // we need to get the apparent mappings and union them with the generic mappings, since some properties may be // missing from the `constraintType` which will otherwise be mapped in the object mappedKeys := r.c.getApparentMappedTypeKeys(nameType, targetType) @@ -3565,6 +3628,16 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo } else { targetKeys = constraintType } + if isRemappedKeyof && source.flags&TypeFlagsIntersection != 0 { + if filteredNameType := r.getOptionalSimplificationOfConditional(nameType); filteredNameType != nil && r.someTypeRelatedToType(source, constraintType, false, intersectionState) == TernaryTrue { + // Apply the filter only to a source already constrained to the mapped keys. + sourceInstantiatedTarget := r.c.instantiateType(filteredNameType, newSimpleTypeMapper(r.c.getTypeParameterFromMappedType(targetType), source)) + broadTargetKeys := r.c.getUnionType([]*Type{targetKeys, sourceInstantiatedTarget}) + if r.isRelatedTo(source, broadTargetKeys, RecursionFlagsTarget, false) == TernaryTrue { + return TernaryTrue + } + } + } if r.isRelatedTo(source, targetKeys, RecursionFlagsTarget, reportErrors) == TernaryTrue { return TernaryTrue } @@ -3601,6 +3674,11 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo return result } } + } else if simplifiedTarget := r.getOptionalSimplificationOfConditional(target); simplifiedTarget != nil { + result = r.isRelatedToEx(source, simplifiedTarget, RecursionFlagsTarget, false /*reportErrors*/, nil /*headMessage*/, intersectionState) + if result != TernaryFalse { + return result + } } case target.flags&TypeFlagsTemplateLiteral != 0: if source.flags&TypeFlagsTemplateLiteral != 0 { @@ -3695,6 +3773,17 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo } } switch { + case source.flags&TypeFlagsNegated != 0: + // 'not S' is related to a non-negated type T only via its base constraint (unknown), + // i.e. essentially only when T is 'unknown' or 'any'. + constraint := r.c.getBaseConstraintOfType(source) + if constraint == nil { + constraint = r.c.unknownType + } + result = r.isRelatedTo(constraint, target, RecursionFlagsSource, reportErrors) + if result != TernaryFalse { + return result + } case source.flags&TypeFlagsTypeVariable != 0: // IndexedAccess comparisons are handled above in the `target.flags&TypeFlagsIndexedAccess` branch if source.flags&TypeFlagsIndexedAccess == 0 || target.flags&TypeFlagsIndexedAccess == 0 { @@ -3845,6 +3934,7 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo return TernaryFalse } sourceIsPrimitive := source.flags&TypeFlagsPrimitive != 0 + originalSource := source if r.relation != r.c.identityRelation { source = r.c.getApparentType(source) } else if r.c.isGenericMappedType(source) { @@ -3923,7 +4013,7 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo if source.flags&(TypeFlagsObject|TypeFlagsIntersection) != 0 && target.flags&TypeFlagsUnion != 0 { objectOnlyTarget := r.c.extractTypesOfKind(target, TypeFlagsObject|TypeFlagsIntersection|TypeFlagsSubstitution) if objectOnlyTarget.flags&TypeFlagsUnion != 0 { - result := r.typeRelatedToDiscriminatedType(source, objectOnlyTarget) + result := r.typeRelatedToDiscriminatedType(originalSource, objectOnlyTarget) if result != TernaryFalse { return result } @@ -3933,6 +4023,74 @@ func (r *Relater) structuredTypeRelatedToWorker(source *Type, target *Type, repo return TernaryFalse } +// TODO: Replace this heuristic with proper distributive conditional type relationship rules. +// For a distributive A extends B ? never : Q without infer parameters, rewrite to Q. +// A definitely false check uses Q unchanged; a definitely true check cannot use the rewrite. +// Otherwise B must be independent of A, and Q must be never. The conditional already distributes, +// but we also probe whether Q agrees with Q | Q before moving the union inside Q. +// See Repeated in indexMappedTypeWithFilteredKeysWithNegationErrors.ts, where moving the union +// inside `${A}-${A}` would lose the correlation between occurrences of A. +func (r *Relater) getOptionalSimplificationOfConditional(target *Type) *Type { + if target.flags&TypeFlagsConditional == 0 { + return nil + } + conditional := target.AsConditionalType() + root := conditional.root + if !root.isDistributive || len(root.inferTypeParameters) != 0 || r.c.getTrueTypeFromConditionalType(target).flags&TypeFlagsNever == 0 { + return nil + } + permissiveExtendsType := r.c.getPermissiveInstantiation(conditional.extendsType) + skipTrue := !someType(r.c.getPermissiveInstantiation(conditional.checkType), func(t *Type) bool { + return r.c.isTypeAssignableTo(t, permissiveExtendsType) + }) + if skipTrue { + return r.c.getFalseTypeFromConditionalType(target) + } + if r.c.isTypeAssignableTo(r.c.getRestrictiveInstantiation(conditional.checkType), r.c.getRestrictiveInstantiation(conditional.extendsType)) { + return nil + } + checkType := getNonDistributedTypeParameter(root.checkType) + if r.c.isTypeParameterPossiblyReferenced(checkType, root.node.ExtendsType) { + return nil + } + falseType := r.c.getTypeFromTypeNode(root.node.FalseType) + if !r.canDistributeTypeInstantiation(falseType, checkType) { + return nil + } + return r.c.instantiateType( + falseType, + r.c.combineTypeMappers( + newSimpleTypeMapper(checkType, r.c.getIntersectionType([]*Type{root.checkType, r.c.getNegatedType(root.extendsType)})), + conditional.mapper, + ), + ) +} + +func (r *Relater) canDistributeTypeInstantiation(t *Type, typeParameter *Type) bool { + key := DistributiveInstantiationKey{typeId: t.id, typeParameterId: typeParameter.id} + if result, ok := r.c.distributiveInstantiationCache[key]; ok { + return result + } + // A recursive probe is unproven until the outer comparison completes. + r.c.distributiveInstantiationCache[key] = false + // Filtering can remove the entire check type, so the false branch must also preserve never. + if r.c.instantiateType(t, newSimpleTypeMapper(typeParameter, r.c.neverType)).flags&TypeFlagsNever == 0 { + return false + } + left := r.c.markerSuperType + right := r.c.markerOtherType + instantiate := func(argument *Type) *Type { + return r.c.getSimplifiedType(r.c.instantiateType(t, newSimpleTypeMapper(typeParameter, argument)), false /*writing*/) + } + // Require execution over unrelated union members to agree with distributing first. + // Use the existing identity comparison rather than introducing conditional relationship rules. + instantiatedUnion := instantiate(r.c.getUnionType([]*Type{left, right})) + unionOfInstantiations := r.c.getUnionType([]*Type{instantiate(left), instantiate(right)}) + result := r.c.isTypeIdenticalTo(instantiatedUnion, unionOfInstantiations) + r.c.distributiveInstantiationCache[key] = result + return result +} + func (r *Relater) typeArgumentsRelatedTo(sources []*Type, targets []*Type, variances []VarianceFlags, reportErrors bool, intersectionState IntersectionState) Ternary { if len(sources) != len(targets) && r.relation == r.c.identityRelation { return TernaryFalse @@ -4019,7 +4177,7 @@ func (r *Relater) mappedTypeRelatedTo(source *Type, target *Type, reportErrors b return TernaryFalse } -func (r *Relater) typeRelatedToDiscriminatedType(source *Type, target *Type) Ternary { +func (r *Relater) typeRelatedToDiscriminatedType(originalSource *Type, target *Type) Ternary { // 1. Generate the combinations of discriminant properties & types 'source' can satisfy. // a. If the number of combinations is above a set limit, the comparison is too complex. // 2. Filter 'target' to the subset of types whose discriminants exist in the matrix. @@ -4029,6 +4187,7 @@ func (r *Relater) typeRelatedToDiscriminatedType(source *Type, target *Type) Ter // // NOTE: See ~/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts // for examples. + source := r.c.getApparentType(originalSource) sourceProperties := r.c.getPropertiesOfType(source) sourcePropertiesFiltered := r.c.findDiscriminantProperties(sourceProperties, target) if len(sourcePropertiesFiltered) == 0 { @@ -4080,6 +4239,13 @@ func (r *Relater) typeRelatedToDiscriminatedType(source *Type, target *Type) Ter hasMatch := false outer: for _, t := range target.Types() { + if t.flags&TypeFlagsIntersection != 0 { + for _, constituent := range t.Types() { + if isNegatedType(constituent) && r.isRelatedTo(originalSource, constituent, RecursionFlagsTarget, false /*reportErrors*/) == TernaryFalse { + continue outer + } + } + } for i := range sourcePropertiesFiltered { sourceProperty := sourcePropertiesFiltered[i] targetProperty := r.c.getPropertyOfType(t, sourceProperty.Name()) @@ -4771,12 +4937,13 @@ func (r *Relater) reportErrorResults(originalSource *Type, originalTarget *Type, } } r.reportRelationError(headMessage, source, target) - if source.flags&TypeFlagsTypeParameter != 0 && source.symbol != nil && len(source.symbol.Declarations()) != 0 && r.c.getConstraintOfType(source) == nil { - syntheticParam := r.c.cloneTypeParameter(source) - syntheticParam.AsTypeParameter().constraint = r.c.instantiateType(target, newSimpleTypeMapper(source, syntheticParam)) + filteredSource := r.c.removeFreshNegatedTypes(source) // strip fresh negated types from the source for the next related info span + if filteredSource.flags&TypeFlagsTypeParameter != 0 && filteredSource.symbol != nil && len(filteredSource.symbol.Declarations()) != 0 && r.c.getConstraintOfType(filteredSource) == nil { + syntheticParam := r.c.cloneTypeParameter(filteredSource) + syntheticParam.AsTypeParameter().constraint = r.c.instantiateType(target, newSimpleTypeMapper(filteredSource, syntheticParam)) if r.c.hasNonCircularBaseConstraint(syntheticParam) { targetConstraintString := r.c.TypeToString(target) - r.relatedInfo = append(r.relatedInfo, NewDiagnosticForNode(source.symbol.Declarations()[0], diagnostics.This_type_parameter_might_need_an_extends_0_constraint, targetConstraintString)) + r.relatedInfo = append(r.relatedInfo, NewDiagnosticForNode(filteredSource.symbol.Declarations()[0], diagnostics.This_type_parameter_might_need_an_extends_0_constraint, targetConstraintString)) } } } diff --git a/tsc/internal/checker/types.go b/tsc/internal/checker/types.go index a3cfe28c2e735..f45e1b66d389c 100644 --- a/tsc/internal/checker/types.go +++ b/tsc/internal/checker/types.go @@ -501,7 +501,7 @@ type SignatureLinks struct { decoratorSignature *Signature // Signature for decorator as if invoked by the runtime } -type TypeFlags uint32 +type TypeFlags uint64 // Note that for types of different kinds, the numeric values of TypeFlags determine the order // computed by the CompareTypes function and therefore the order of constituent types in union types. @@ -536,13 +536,14 @@ const ( TypeFlagsTemplateLiteral TypeFlags = 1 << 22 // Template literal type TypeFlagsStringMapping TypeFlags = 1 << 23 // Uppercase/Lowercase type TypeFlagsSubstitution TypeFlags = 1 << 24 // Type parameter substitution - TypeFlagsIndexedAccess TypeFlags = 1 << 25 // T[K] - TypeFlagsConditional TypeFlags = 1 << 26 // T extends U ? X : Y - TypeFlagsUnion TypeFlags = 1 << 27 // Union (T | U) - TypeFlagsIntersection TypeFlags = 1 << 28 // Intersection (T & U) - TypeFlagsReserved1 TypeFlags = 1 << 29 // Used by union/intersection type construction - TypeFlagsReserved2 TypeFlags = 1 << 30 // Used by union/intersection type construction - TypeFlagsReserved3 TypeFlags = 1 << 31 + TypeFlagsNegated TypeFlags = 1 << 25 // not T + TypeFlagsIndexedAccess TypeFlags = 1 << 26 // T[K] + TypeFlagsConditional TypeFlags = 1 << 27 // T extends U ? X : Y + TypeFlagsUnion TypeFlags = 1 << 28 // Union (T | U) + TypeFlagsIntersection TypeFlags = 1 << 29 // Intersection (T & U) + TypeFlagsReserved1 TypeFlags = 1 << 30 // Used by union/intersection type construction + TypeFlagsReserved2 TypeFlags = 1 << 31 // Used by union/intersection type construction + TypeFlagsReserved3 TypeFlags = 1 << 32 TypeFlagsAnyOrUnknown = TypeFlagsAny | TypeFlagsUnknown TypeFlagsNullable = TypeFlagsUndefined | TypeFlagsNull @@ -567,7 +568,7 @@ const ( TypeFlagsUnionOrIntersection = TypeFlagsUnion | TypeFlagsIntersection TypeFlagsStructuredType = TypeFlagsObject | TypeFlagsUnion | TypeFlagsIntersection TypeFlagsTypeVariable = TypeFlagsTypeParameter | TypeFlagsIndexedAccess - TypeFlagsInstantiableNonPrimitive = TypeFlagsTypeVariable | TypeFlagsConditional | TypeFlagsSubstitution + TypeFlagsInstantiableNonPrimitive = TypeFlagsTypeVariable | TypeFlagsConditional | TypeFlagsSubstitution | TypeFlagsNegated TypeFlagsInstantiablePrimitive = TypeFlagsIndex | TypeFlagsTemplateLiteral | TypeFlagsStringMapping TypeFlagsInstantiable = TypeFlagsInstantiableNonPrimitive | TypeFlagsInstantiablePrimitive TypeFlagsStructuredOrInstantiable = TypeFlagsStructuredType | TypeFlagsInstantiable @@ -587,6 +588,7 @@ const ( TypeFlagsIncludesInstantiable = TypeFlagsSubstitution TypeFlagsIncludesConstrainedTypeVariable = TypeFlagsReserved1 TypeFlagsIncludesError = TypeFlagsReserved2 + TypeFlagsIncludesNegated = TypeFlagsReserved3 TypeFlagsNotPrimitiveUnion = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsVoid | TypeFlagsNever | TypeFlagsObject | TypeFlagsIntersection | TypeFlagsIncludesInstantiable ) @@ -623,11 +625,12 @@ var typeFlagNames = [...]struct { {TypeFlagsConditional, "Conditional"}, {TypeFlagsUnion, "Union"}, {TypeFlagsIntersection, "Intersection"}, + {TypeFlagsNegated, "Negated"}, } // FormatTypeFlags returns the individual flag names as a slice of strings. func FormatTypeFlags(flags TypeFlags) []string { - result := make([]string, 0, bits.OnesCount32(uint32(flags))) + result := make([]string, 0, bits.OnesCount64(uint64(flags))) for _, fn := range typeFlagNames { if flags&fn.flag != 0 { result = append(result, fn.name) @@ -730,6 +733,8 @@ const ( ObjectFlagsIsNeverIntersectionComputed = 1 << 25 // IsNeverLike flag has been computed ObjectFlagsIsNeverIntersection = 1 << 26 // Intersection reduces to never ObjectFlagsIsConstrainedTypeVariable = 1 << 27 // T & C, where T's constraint and C are primitives, object, or {} + // Flags that require TypeFlags.Negated + ObjectFlagsFreshNegated ObjectFlags = 1 << 25 // Negated type introduced by control flow narrowing; widened away when it escapes into an inferred declaration ) // TypeAlias @@ -770,6 +775,7 @@ const ( typeKindTemplateLiteral typeKindStringMapping typeKindSubstitution + typeKindNegated typeKindConditional typeKindObject typeKindTypeReference @@ -804,6 +810,7 @@ var ( _ [0 - unsafe.Offsetof(TemplateLiteralType{}.Type)]byte _ [0 - unsafe.Offsetof(StringMappingType{}.Type)]byte _ [0 - unsafe.Offsetof(SubstitutionType{}.Type)]byte + _ [0 - unsafe.Offsetof(NegatedType{}.Type)]byte _ [0 - unsafe.Offsetof(ConditionalType{}.Type)]byte _ [0 - unsafe.Offsetof(ObjectType{}.Type)]byte _ [0 - unsafe.Offsetof(TypeReference{}.Type)]byte @@ -884,6 +891,10 @@ func (t *Type) AsConditionalType() *ConditionalType { return castType[ConditionalType](t, typeKindConditional) } +func (t *Type) AsNegatedType() *NegatedType { + return castType[NegatedType](t, typeKindNegated) +} + // Casts for embedded struct types func (t *Type) AsConstrainedType() *ConstrainedType { @@ -1465,6 +1476,17 @@ type SubstitutionType struct { func (t *SubstitutionType) BaseType() *Type { return t.baseType } func (t *SubstitutionType) SubstConstraint() *Type { return t.constraint } +// NegatedType (the type 'not T') + +type NegatedType struct { + ConstrainedType + baseType *Type // The negated type T in 'not T' + freshType *Type // Fresh version of type + regularType *Type // Regular version of type +} + +func (t *NegatedType) BaseType() *Type { return t.baseType } + type ConditionalRoot struct { node *ast.ConditionalTypeNode checkType *Type diff --git a/tsc/internal/checker/types_test.go b/tsc/internal/checker/types_test.go index 86de2b089e06e..1be228aec5078 100644 --- a/tsc/internal/checker/types_test.go +++ b/tsc/internal/checker/types_test.go @@ -72,6 +72,7 @@ func TestTypeCasts(t *testing.T) { {typeKindTemplateLiteral, &TemplateLiteralType{}, func(t *Type) any { return t.AsTemplateLiteralType() }}, {typeKindStringMapping, &StringMappingType{}, func(t *Type) any { return t.AsStringMappingType() }}, {typeKindSubstitution, &SubstitutionType{}, func(t *Type) any { return t.AsSubstitutionType() }}, + {typeKindNegated, &NegatedType{}, func(t *Type) any { return t.AsNegatedType() }}, {typeKindConditional, &ConditionalType{}, func(t *Type) any { return t.AsConditionalType() }}, {typeKindObject, &ObjectType{}, func(t *Type) any { return t.AsObjectType() }}, {typeKindTypeReference, &TypeReference{}, func(t *Type) any { return t.AsTypeReference() }}, @@ -99,6 +100,7 @@ func TestTypeCasts(t *testing.T) { typ.objectFlags = ObjectFlagsReference assert.Equal(t, test.cast(typ), any(test.data)) assert.Assert(t, didPanic(func() { typ.AsLiteralType() }) == (test.kind != typeKindLiteral)) + assert.Assert(t, didPanic(func() { typ.AsNegatedType() }) == (test.kind != typeKindNegated)) } } @@ -110,7 +112,7 @@ func didPanic(f func()) (panicked bool) { func TestTypeHeaderSize(t *testing.T) { t.Parallel() - assert.Equal(t, unsafe.Sizeof(Type{}), 16+3*unsafe.Sizeof((*Checker)(nil))) + assert.Equal(t, unsafe.Sizeof(Type{}), 16+4*unsafe.Sizeof((*Checker)(nil))) } func TestKeyBuilder(t *testing.T) { diff --git a/tsc/internal/checker/utilities.go b/tsc/internal/checker/utilities.go index 3a7e9993ba879..d367035d309cb 100644 --- a/tsc/internal/checker/utilities.go +++ b/tsc/internal/checker/utilities.go @@ -984,6 +984,18 @@ func (s *orderedSet[T]) add(value T) { s.valuesByKey[value] = struct{}{} } +func (s *orderedSet[T]) replace(oldValue T, newValue T) bool { + if !s.contains(oldValue) { + return false + } + s.values[slices.Index(s.values, oldValue)] = newValue + if s.valuesByKey != nil { + delete(s.valuesByKey, oldValue) + s.valuesByKey[newValue] = struct{}{} + } + return true +} + func getContainingFunctionOrClassStaticBlock(node *ast.Node) *ast.Node { return ast.FindAncestor(node.Parent, ast.IsFunctionLikeOrClassStaticBlockDeclaration) } diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index c670d64ad21c2..3b0435efcdb9d 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -2746,7 +2746,7 @@ func (p *Parser) createUnionOrIntersectionTypeNode(operator ast.Kind, types *ast func (p *Parser) parseTypeOperatorOrHigher() *ast.TypeNode { operator := p.token switch operator { - case ast.KindKeyOfKeyword, ast.KindUniqueKeyword, ast.KindReadonlyKeyword: + case ast.KindKeyOfKeyword, ast.KindUniqueKeyword, ast.KindReadonlyKeyword, ast.KindNotKeyword: return p.parseTypeOperator(operator) case ast.KindInferKeyword: return p.parseInferType() diff --git a/tsc/internal/scanner/scanner.go b/tsc/internal/scanner/scanner.go index 785fe50a4e7df..2aa8ce45433d8 100644 --- a/tsc/internal/scanner/scanner.go +++ b/tsc/internal/scanner/scanner.go @@ -89,6 +89,7 @@ var textToKeyword = map[string]ast.Kind{ "namespace": ast.KindNamespaceKeyword, "never": ast.KindNeverKeyword, "new": ast.KindNewKeyword, + "not": ast.KindNotKeyword, "null": ast.KindNullKeyword, "number": ast.KindNumberKeyword, "object": ast.KindObjectKeyword, diff --git a/tsc/testdata/baselines/reference/compiler/constructorWithCapturedSuper.types b/tsc/testdata/baselines/reference/compiler/constructorWithCapturedSuper.types index b34db673f1f2b..57fd217c56b0d 100644 --- a/tsc/testdata/baselines/reference/compiler/constructorWithCapturedSuper.types +++ b/tsc/testdata/baselines/reference/compiler/constructorWithCapturedSuper.types @@ -33,7 +33,7 @@ class B extends A { } while (x < 2) { >x < 2 : boolean ->x : number +>x : number & not 1 >2 : 2 return; diff --git a/tsc/testdata/baselines/reference/compiler/continueInLoopsWithCapturedBlockScopedBindings1(target=es2015).types b/tsc/testdata/baselines/reference/compiler/continueInLoopsWithCapturedBlockScopedBindings1(target=es2015).types index 447d2903bbc2c..801d8a47f7852 100644 --- a/tsc/testdata/baselines/reference/compiler/continueInLoopsWithCapturedBlockScopedBindings1(target=es2015).types +++ b/tsc/testdata/baselines/reference/compiler/continueInLoopsWithCapturedBlockScopedBindings1(target=es2015).types @@ -25,7 +25,7 @@ function foo() { >() => { return i; } : () => number return i; ->i : number +>i : number & not 0 })(); } diff --git a/tsc/testdata/baselines/reference/compiler/declFileTypeAnnotationStringLiteral(target=es2015).types b/tsc/testdata/baselines/reference/compiler/declFileTypeAnnotationStringLiteral(target=es2015).types index f6f1ec56a63c2..47899fe8835ba 100644 --- a/tsc/testdata/baselines/reference/compiler/declFileTypeAnnotationStringLiteral(target=es2015).types +++ b/tsc/testdata/baselines/reference/compiler/declFileTypeAnnotationStringLiteral(target=es2015).types @@ -29,5 +29,5 @@ function foo(a: string): string | number { } return a; ->a : string +>a : string & not "hello" } diff --git a/tsc/testdata/baselines/reference/compiler/distributiveConditionalTypeConstraints.types b/tsc/testdata/baselines/reference/compiler/distributiveConditionalTypeConstraints.types index d38a982f44c8a..0afb018df8afd 100644 --- a/tsc/testdata/baselines/reference/compiler/distributiveConditionalTypeConstraints.types +++ b/tsc/testdata/baselines/reference/compiler/distributiveConditionalTypeConstraints.types @@ -180,7 +180,7 @@ function test3(y: T extends C ? number : string) { } else { y; // T extends C ? number : string ->y : T extends C ? number : string +>y : (T extends C ? number : string) & not string } const newY: string | number = y; >newY : string | number @@ -205,7 +205,7 @@ function test4(y: T extends C ? string : number) { } else { y; // T extends C ? string : number ->y : T extends C ? string : number +>y : (T extends C ? string : number) & not string } const newY: string | number = y; >newY : string | number diff --git a/tsc/testdata/baselines/reference/compiler/doubleUnderscoreLabels.types b/tsc/testdata/baselines/reference/compiler/doubleUnderscoreLabels.types index c631dcbb519d9..0407a5d56be0f 100644 --- a/tsc/testdata/baselines/reference/compiler/doubleUnderscoreLabels.types +++ b/tsc/testdata/baselines/reference/compiler/doubleUnderscoreLabels.types @@ -16,7 +16,7 @@ function doThing() { >i : number >10 : 10 >i++ : number ->i : number +>i : number & not 3 & not 5 if (i === 3) { >i === 3 : boolean @@ -28,7 +28,7 @@ function doThing() { } if (i === 5) { >i === 5 : boolean ->i : number +>i : number & not 3 >5 : 5 break aLabel; diff --git a/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types index 4dc48c9f792e4..38ee6c70ca933 100644 --- a/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types +++ b/tsc/testdata/baselines/reference/compiler/embeddedNumericCompoundAssignmentAfterExcludedLiterals.types @@ -14,7 +14,7 @@ function ease(value: number, divisor: number) { value /= divisor; >value /= divisor : number ->value : number +>value : number & not 0 >divisor : number if (value === 2) return 2; @@ -34,7 +34,7 @@ function ease(value: number, divisor: number) { >10 : 10 >(value -= 1) : number >value -= 1 : number ->value : number +>value : number & not 2 >1 : 1 } diff --git a/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=false).types b/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=false).types index c9807fa2b6a26..d599401da3e19 100644 --- a/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=false).types +++ b/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=false).types @@ -14,7 +14,7 @@ if (nonNull === "foo") { } else { nonNull; ->nonNull : {} +>nonNull : {} & not "foo" } declare let obj: { a: string }; diff --git a/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=true).types b/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=true).types index 29367e5df7797..18e70362d0e40 100644 --- a/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=true).types +++ b/tsc/testdata/baselines/reference/compiler/emptyAnonymousObjectNarrowing(strictnullchecks=true).types @@ -14,7 +14,7 @@ if (nonNull === "foo") { } else { nonNull; ->nonNull : {} +>nonNull : {} & not "foo" } declare let obj: { a: string }; diff --git a/tsc/testdata/baselines/reference/compiler/emptyThenWithoutWarning.types b/tsc/testdata/baselines/reference/compiler/emptyThenWithoutWarning.types index 714c202ae6b23..07be0c5fec4b6 100644 --- a/tsc/testdata/baselines/reference/compiler/emptyThenWithoutWarning.types +++ b/tsc/testdata/baselines/reference/compiler/emptyThenWithoutWarning.types @@ -12,10 +12,10 @@ if(a === 1 || a === 2 || a === 3) { >a : number >1 : 1 >a === 2 : boolean ->a : number +>a : number & not 1 >2 : 2 >a === 3 : boolean ->a : number +>a : number & not 1 & not 2 >3 : 3 } else { diff --git a/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types index 7a3d3f9e4ad78..4b6f276596adf 100644 --- a/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types +++ b/tsc/testdata/baselines/reference/compiler/excludedNumericLiteralAfterDecrement.types @@ -12,7 +12,7 @@ function decrement(count: number) { count--; >count-- : number ->count : number +>count : number & not 0 if (count === 0) return; >count === 0 : boolean diff --git a/tsc/testdata/baselines/reference/compiler/extractExcludePartition.errors.txt b/tsc/testdata/baselines/reference/compiler/extractExcludePartition.errors.txt new file mode 100644 index 0000000000000..30d4fd64e1cc4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/extractExcludePartition.errors.txt @@ -0,0 +1,280 @@ +extractExcludePartition.ts(109,5): error TS2322: Type 'T' is not assignable to type 'MyExtract | (T & not B)'. + Type 'T' is not assignable to type 'T & not B'. + Type 'T' is not assignable to type 'not B'. +extractExcludePartition.ts(120,5): error TS2322: Type 'Q | T' is not assignable to type 'MismatchedPartition'. + Type 'Q' is not assignable to type 'MismatchedPartition'. + Type 'Q' is not assignable to type 'MyExtract'. + Type 'Q' is not assignable to type 'T'. + 'T' could be instantiated with an arbitrary type which could be unrelated to 'Q'. +extractExcludePartition.ts(164,7): error TS2322: Type 'RecursivePartition' is not assignable to type 'number'. + Type '{ next: RecursivePartition; value: string; }' is not assignable to type 'number'. +extractExcludePartition.ts(199,5): error TS2322: Type '{ next: unknown; }' is not assignable to type 'ComplementPartition'. + Type '{ next: unknown; }' is not assignable to type '{ next: unknown; } & not { value: string; }'. + Type '{ next: unknown; }' is not assignable to type 'not { value: string; }'. +extractExcludePartition.ts(209,7): error TS2322: Type 'unknown' is not assignable to type 'number'. +extractExcludePartition.ts(219,5): error TS2322: Type '{ next: unknown; }' is not assignable to type 'ForwardComplementPartition'. + Type '{ next: unknown; }' is not assignable to type '{ next: unknown; } & not { value: string; }'. + Type '{ next: unknown; }' is not assignable to type 'not { value: string; }'. +extractExcludePartition.ts(228,7): error TS2322: Type 'unknown' is not assignable to type 'number'. + + +==== extractExcludePartition.ts (7 errors) ==== + type MyExtract = T & U; + type MyExclude = T & not U; + type MyOmit = Pick>; + type Partition = MyExtract | MyExclude; + + function partition(value: T): Partition { + return value; + } + + function identity(value: Partition): T { + return value; + } + + type UnionPartition = MyExtract | MyExclude; + + function unionPartition(value: T): UnionPartition { + return value; + } + + function unionIdentity(value: UnionPartition): T { + return value; + } + + type RepeatedPartition = Partition | Partition; + + function repeatedPartition(value: T): RepeatedPartition { + return value; + } + + function repeatedIdentity(value: RepeatedPartition): T { + return value; + } + + type DifferentBasePartitions = Partition | Partition; + + function differentBasePartitions(value: T | Q): DifferentBasePartitions { + return value; + } + + function differentBaseIdentity(value: DifferentBasePartitions): T | Q { + return value; + } + + type UnionBasePartition = Partition; + + function unionBasePartition(value: T | U): UnionBasePartition { + return value; + } + + function unionBaseIdentity(value: UnionBasePartition): T | U { + return value; + } + + type RepeatedUnionPartition = Partition | Partition; + + function repeatedUnionPartition(value: T): RepeatedUnionPartition { + return value; + } + + function repeatedUnionIdentity(value: RepeatedUnionPartition): T { + return value; + } + + type BooleanPartition = + | MyExtract, B> + | MyExclude, B> + | MyExtract, B> + | MyExclude, B>; + + function booleanPartition(value: T): BooleanPartition { + return value; + } + + function booleanIdentity(value: BooleanPartition): T { + return value; + } + + type PartitionWithRemainder = MyExtract | MyExclude | R; + + function partitionWithRemainder(value: T | R): PartitionWithRemainder { + return value; + } + + function remainderIdentity(value: PartitionWithRemainder): T | R { + return value; + } + + type IntersectionBasePartition = MyExtract | MyExclude; + + function intersectionBasePartition(value: T & Q): IntersectionBasePartition { + return value; + } + + function intersectionBaseIdentity(value: IntersectionBasePartition): T & Q { + return value; + } + + type NeverPartition = MyExtract | MyExclude; + type UnknownPartition = MyExtract | MyExclude; + + function degeneratePartitions(neverPartition: NeverPartition, unknownPartition: UnknownPartition): T { + return Math.random() ? neverPartition : unknownPartition; + } + + type IncompletePartition = MyExtract | MyExclude; + + function incompletePartition(value: T): IncompletePartition { + // Error: The positive branch does not cover B. + return value; + ~~~~~~ +!!! error TS2322: Type 'T' is not assignable to type 'MyExtract | (T & not B)'. +!!! error TS2322: Type 'T' is not assignable to type 'T & not B'. +!!! error TS2322: Type 'T' is not assignable to type 'not B'. +!!! related TS2208 extractExcludePartition.ts:107:30: This type parameter might need an `extends not B` constraint. +!!! related TS2208 extractExcludePartition.ts:107:30: This type parameter might need an `extends T & not B` constraint. +!!! related TS2208 extractExcludePartition.ts:107:30: This type parameter might need an `extends MyExtract | (T & not B)` constraint. + } + + function incompleteIdentity(value: IncompletePartition): T { + return value; + } + + type MismatchedPartition = MyExtract | MyExclude; + + function mismatchedPartition(value: T | Q): MismatchedPartition { + // Error: The positive and negative branches have different bases. + return value; + ~~~~~~ +!!! error TS2322: Type 'Q | T' is not assignable to type 'MismatchedPartition'. +!!! error TS2322: Type 'Q' is not assignable to type 'MismatchedPartition'. +!!! error TS2322: Type 'Q' is not assignable to type 'MyExtract'. +!!! error TS2322: Type 'Q' is not assignable to type 'T'. +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Q'. +!!! related TS2208 extractExcludePartition.ts:118:33: This type parameter might need an `extends T` constraint. +!!! related TS2208 extractExcludePartition.ts:118:33: This type parameter might need an `extends MyExtract` constraint. +!!! related TS2208 extractExcludePartition.ts:118:33: This type parameter might need an `extends MismatchedPartition` constraint. + } + + function mismatchedIdentity(value: MismatchedPartition): T | Q { + return value; + } + + type InjectedProps = { + owner: string; + }; + + declare function withOwner(props: MyOmit & InjectedProps): T; + + function render(props: T) { + return withOwner(props); + } + + type NegatedBasePartition = MyExtract, U> | MyExclude, U>; + + function negatedBasePartition(value: T & not V): NegatedBasePartition { + return value; + } + + function negatedBaseIdentity(value: NegatedBasePartition): T & not V { + return value; + } + + type DeferredPartition = MyExtract | MyExclude; + + function instantiatedPartition(value: T): DeferredPartition { + return value; + } + + function instantiatedIdentity(value: DeferredPartition): T { + return value; + } + + type RecursivePartition = + | { next: RecursivePartition; value: string } + | ({ next: unknown } & not { value: string }); + + declare const recursivePartition: RecursivePartition; + const recursiveNext: unknown = recursivePartition.next; + // Error: The recursive union is not a number. + const recursiveNumber: number = recursivePartition; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'RecursivePartition' is not assignable to type 'number'. +!!! error TS2322: Type '{ next: RecursivePartition; value: string; }' is not assignable to type 'number'. + + type PartitionWithPositiveRemainder = (T & U) | (T & not U & V); + + function positiveRemainder(value: T & U): PartitionWithPositiveRemainder { + return value; + } + + function reducedBase(value: T & V): PartitionWithPositiveRemainder { + return value; + } + + function positiveRemainderIdentity(value: PartitionWithPositiveRemainder): (T & U) | (T & V) { + return value; + } + + type PartitionContainer = { value: Value }; + type OuterPartition = PartitionContainer; + type InnerPartition = "chosen" | (string & not "chosen"); + + function nestedPartition(value: string): InnerPartition { + return value; + } + + function nestedPartitionElement(value: string): OuterPartition["value"] { + return value; + } + + type ComplementPartition = + | { next: ComplementPartition; value: string } + | ({ next: unknown } & not { value: string }) + | { next: unknown; value: string }; + + function recursiveComplement(value: { next: unknown }): ComplementPartition { + // Error: Recursive reduction commits to the unreduced union. + return value; + ~~~~~~ +!!! error TS2322: Type '{ next: unknown; }' is not assignable to type 'ComplementPartition'. +!!! error TS2322: Type '{ next: unknown; }' is not assignable to type '{ next: unknown; } & not { value: string; }'. +!!! error TS2322: Type '{ next: unknown; }' is not assignable to type 'not { value: string; }'. + } + + function recursiveComplementMember(value: unknown): ComplementPartition["next"] { + return value; + } + + declare const complementPartition: ComplementPartition; + const complementNode: unknown = complementPartition.next; + // Error: Reduction must not turn a recursive member into any. + const complementNumber: number = complementPartition.next; + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + + type ForwardComplementMember = ForwardComplementPartition["next"]; + type ForwardComplementPartition = + | { next: ForwardComplementPartition; value: string } + | ({ next: unknown } & not { value: string }) + | { next: unknown; value: string }; + + function forwardComplement(value: { next: unknown }): ForwardComplementPartition { + // Error: Recursive reduction commits to the unreduced union. + return value; + ~~~~~~ +!!! error TS2322: Type '{ next: unknown; }' is not assignable to type 'ForwardComplementPartition'. +!!! error TS2322: Type '{ next: unknown; }' is not assignable to type '{ next: unknown; } & not { value: string; }'. +!!! error TS2322: Type '{ next: unknown; }' is not assignable to type 'not { value: string; }'. + } + + function forwardComplementMember(value: unknown): ForwardComplementMember { + return value; + } + + declare const forwardComplementValue: ForwardComplementMember; + // Error: Resolving the indexed access first must still produce unknown. + const forwardComplementNumber: number = forwardComplementValue; + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/extractExcludePartition.symbols b/tsc/testdata/baselines/reference/compiler/extractExcludePartition.symbols new file mode 100644 index 0000000000000..903afcc53645f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/extractExcludePartition.symbols @@ -0,0 +1,946 @@ +//// [tests/cases/compiler/extractExcludePartition.ts] //// + +=== extractExcludePartition.ts === +type MyExtract = T & U; +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 0, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 0, 17)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 0, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 0, 17)) + +type MyExclude = T & not U; +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 1, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 1, 17)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 1, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 1, 17)) + +type MyOmit = Pick>; +>MyOmit : Symbol(MyOmit, Decl(extractExcludePartition.ts, 1, 33)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 2, 12)) +>K : Symbol(K, Decl(extractExcludePartition.ts, 2, 14)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 2, 12)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 2, 12)) +>K : Symbol(K, Decl(extractExcludePartition.ts, 2, 14)) + +type Partition = MyExtract | MyExclude; +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 3, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 3, 17)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 3, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 3, 17)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 3, 15)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 3, 17)) + +function partition(value: T): Partition { +>partition : Symbol(partition, Decl(extractExcludePartition.ts, 3, 57)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 5, 19)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 5, 21)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 5, 25)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 5, 19)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 5, 19)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 5, 21)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 5, 25)) +} + +function identity(value: Partition): T { +>identity : Symbol(identity, Decl(extractExcludePartition.ts, 7, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 9, 18)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 9, 20)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 9, 24)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 9, 18)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 9, 20)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 9, 18)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 9, 24)) +} + +type UnionPartition = MyExtract | MyExclude; +>UnionPartition : Symbol(UnionPartition, Decl(extractExcludePartition.ts, 11, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 13, 20)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 13, 22)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 13, 25)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 13, 20)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 13, 22)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 13, 25)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 13, 20)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 13, 22)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 13, 25)) + +function unionPartition(value: T): UnionPartition { +>unionPartition : Symbol(unionPartition, Decl(extractExcludePartition.ts, 13, 73)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 15, 24)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 15, 26)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 15, 29)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 15, 33)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 15, 24)) +>UnionPartition : Symbol(UnionPartition, Decl(extractExcludePartition.ts, 11, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 15, 24)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 15, 26)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 15, 29)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 15, 33)) +} + +function unionIdentity(value: UnionPartition): T { +>unionIdentity : Symbol(unionIdentity, Decl(extractExcludePartition.ts, 17, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 19, 23)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 19, 25)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 19, 28)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 19, 32)) +>UnionPartition : Symbol(UnionPartition, Decl(extractExcludePartition.ts, 11, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 19, 23)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 19, 25)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 19, 28)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 19, 23)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 19, 32)) +} + +type RepeatedPartition = Partition | Partition; +>RepeatedPartition : Symbol(RepeatedPartition, Decl(extractExcludePartition.ts, 21, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 23, 23)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 23, 25)) +>W : Symbol(W, Decl(extractExcludePartition.ts, 23, 28)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 23, 23)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 23, 25)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 23, 23)) +>W : Symbol(W, Decl(extractExcludePartition.ts, 23, 28)) + +function repeatedPartition(value: T): RepeatedPartition { +>repeatedPartition : Symbol(repeatedPartition, Decl(extractExcludePartition.ts, 23, 68)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 25, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 25, 29)) +>W : Symbol(W, Decl(extractExcludePartition.ts, 25, 32)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 25, 36)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 25, 27)) +>RepeatedPartition : Symbol(RepeatedPartition, Decl(extractExcludePartition.ts, 21, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 25, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 25, 29)) +>W : Symbol(W, Decl(extractExcludePartition.ts, 25, 32)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 25, 36)) +} + +function repeatedIdentity(value: RepeatedPartition): T { +>repeatedIdentity : Symbol(repeatedIdentity, Decl(extractExcludePartition.ts, 27, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 29, 26)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 29, 28)) +>W : Symbol(W, Decl(extractExcludePartition.ts, 29, 31)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 29, 35)) +>RepeatedPartition : Symbol(RepeatedPartition, Decl(extractExcludePartition.ts, 21, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 29, 26)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 29, 28)) +>W : Symbol(W, Decl(extractExcludePartition.ts, 29, 31)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 29, 26)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 29, 35)) +} + +type DifferentBasePartitions = Partition | Partition; +>DifferentBasePartitions : Symbol(DifferentBasePartitions, Decl(extractExcludePartition.ts, 31, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 33, 29)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 33, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 33, 34)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 33, 29)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 33, 34)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 33, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 33, 34)) + +function differentBasePartitions(value: T | Q): DifferentBasePartitions { +>differentBasePartitions : Symbol(differentBasePartitions, Decl(extractExcludePartition.ts, 33, 74)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 35, 33)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 35, 35)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 35, 38)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 35, 42)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 35, 33)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 35, 35)) +>DifferentBasePartitions : Symbol(DifferentBasePartitions, Decl(extractExcludePartition.ts, 31, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 35, 33)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 35, 35)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 35, 38)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 35, 42)) +} + +function differentBaseIdentity(value: DifferentBasePartitions): T | Q { +>differentBaseIdentity : Symbol(differentBaseIdentity, Decl(extractExcludePartition.ts, 37, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 39, 31)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 39, 33)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 39, 36)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 39, 40)) +>DifferentBasePartitions : Symbol(DifferentBasePartitions, Decl(extractExcludePartition.ts, 31, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 39, 31)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 39, 33)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 39, 36)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 39, 31)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 39, 33)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 39, 40)) +} + +type UnionBasePartition = Partition; +>UnionBasePartition : Symbol(UnionBasePartition, Decl(extractExcludePartition.ts, 41, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 43, 24)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 43, 26)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 43, 29)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 43, 32)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 43, 24)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 43, 26)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 43, 29)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 43, 32)) + +function unionBasePartition(value: T | U): UnionBasePartition { +>unionBasePartition : Symbol(unionBasePartition, Decl(extractExcludePartition.ts, 43, 62)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 45, 28)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 45, 30)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 45, 33)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 45, 36)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 45, 40)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 45, 28)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 45, 30)) +>UnionBasePartition : Symbol(UnionBasePartition, Decl(extractExcludePartition.ts, 41, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 45, 28)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 45, 30)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 45, 33)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 45, 36)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 45, 40)) +} + +function unionBaseIdentity(value: UnionBasePartition): T | U { +>unionBaseIdentity : Symbol(unionBaseIdentity, Decl(extractExcludePartition.ts, 47, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 49, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 49, 29)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 49, 32)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 49, 35)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 49, 39)) +>UnionBasePartition : Symbol(UnionBasePartition, Decl(extractExcludePartition.ts, 41, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 49, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 49, 29)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 49, 32)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 49, 35)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 49, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 49, 29)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 49, 39)) +} + +type RepeatedUnionPartition = Partition | Partition; +>RepeatedUnionPartition : Symbol(RepeatedUnionPartition, Decl(extractExcludePartition.ts, 51, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 53, 28)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 53, 30)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 53, 33)) +>C : Symbol(C, Decl(extractExcludePartition.ts, 53, 36)) +>D : Symbol(D, Decl(extractExcludePartition.ts, 53, 39)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 53, 28)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 53, 30)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 53, 33)) +>Partition : Symbol(Partition, Decl(extractExcludePartition.ts, 2, 69)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 53, 28)) +>C : Symbol(C, Decl(extractExcludePartition.ts, 53, 36)) +>D : Symbol(D, Decl(extractExcludePartition.ts, 53, 39)) + +function repeatedUnionPartition(value: T): RepeatedUnionPartition { +>repeatedUnionPartition : Symbol(repeatedUnionPartition, Decl(extractExcludePartition.ts, 53, 87)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 55, 32)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 55, 34)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 55, 37)) +>C : Symbol(C, Decl(extractExcludePartition.ts, 55, 40)) +>D : Symbol(D, Decl(extractExcludePartition.ts, 55, 43)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 55, 47)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 55, 32)) +>RepeatedUnionPartition : Symbol(RepeatedUnionPartition, Decl(extractExcludePartition.ts, 51, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 55, 32)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 55, 34)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 55, 37)) +>C : Symbol(C, Decl(extractExcludePartition.ts, 55, 40)) +>D : Symbol(D, Decl(extractExcludePartition.ts, 55, 43)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 55, 47)) +} + +function repeatedUnionIdentity(value: RepeatedUnionPartition): T { +>repeatedUnionIdentity : Symbol(repeatedUnionIdentity, Decl(extractExcludePartition.ts, 57, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 59, 31)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 59, 33)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 59, 36)) +>C : Symbol(C, Decl(extractExcludePartition.ts, 59, 39)) +>D : Symbol(D, Decl(extractExcludePartition.ts, 59, 42)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 59, 46)) +>RepeatedUnionPartition : Symbol(RepeatedUnionPartition, Decl(extractExcludePartition.ts, 51, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 59, 31)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 59, 33)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 59, 36)) +>C : Symbol(C, Decl(extractExcludePartition.ts, 59, 39)) +>D : Symbol(D, Decl(extractExcludePartition.ts, 59, 42)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 59, 31)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 59, 46)) +} + +type BooleanPartition = +>BooleanPartition : Symbol(BooleanPartition, Decl(extractExcludePartition.ts, 61, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 63, 22)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 63, 24)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 63, 27)) + + | MyExtract, B> +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 63, 22)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 63, 24)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 63, 27)) + + | MyExclude, B> +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 63, 22)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 63, 24)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 63, 27)) + + | MyExtract, B> +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 63, 22)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 63, 24)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 63, 27)) + + | MyExclude, B>; +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 63, 22)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 63, 24)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 63, 27)) + +function booleanPartition(value: T): BooleanPartition { +>booleanPartition : Symbol(booleanPartition, Decl(extractExcludePartition.ts, 67, 36)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 69, 26)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 69, 28)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 69, 31)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 69, 35)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 69, 26)) +>BooleanPartition : Symbol(BooleanPartition, Decl(extractExcludePartition.ts, 61, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 69, 26)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 69, 28)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 69, 31)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 69, 35)) +} + +function booleanIdentity(value: BooleanPartition): T { +>booleanIdentity : Symbol(booleanIdentity, Decl(extractExcludePartition.ts, 71, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 73, 25)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 73, 27)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 73, 30)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 73, 34)) +>BooleanPartition : Symbol(BooleanPartition, Decl(extractExcludePartition.ts, 61, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 73, 25)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 73, 27)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 73, 30)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 73, 25)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 73, 34)) +} + +type PartitionWithRemainder = MyExtract | MyExclude | R; +>PartitionWithRemainder : Symbol(PartitionWithRemainder, Decl(extractExcludePartition.ts, 75, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 77, 28)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 77, 30)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 77, 33)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 77, 28)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 77, 30)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 77, 28)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 77, 30)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 77, 33)) + +function partitionWithRemainder(value: T | R): PartitionWithRemainder { +>partitionWithRemainder : Symbol(partitionWithRemainder, Decl(extractExcludePartition.ts, 77, 77)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 79, 32)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 79, 34)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 79, 37)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 79, 41)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 79, 32)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 79, 37)) +>PartitionWithRemainder : Symbol(PartitionWithRemainder, Decl(extractExcludePartition.ts, 75, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 79, 32)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 79, 34)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 79, 37)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 79, 41)) +} + +function remainderIdentity(value: PartitionWithRemainder): T | R { +>remainderIdentity : Symbol(remainderIdentity, Decl(extractExcludePartition.ts, 81, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 83, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 83, 29)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 83, 32)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 83, 36)) +>PartitionWithRemainder : Symbol(PartitionWithRemainder, Decl(extractExcludePartition.ts, 75, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 83, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 83, 29)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 83, 32)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 83, 27)) +>R : Symbol(R, Decl(extractExcludePartition.ts, 83, 32)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 83, 36)) +} + +type IntersectionBasePartition = MyExtract | MyExclude; +>IntersectionBasePartition : Symbol(IntersectionBasePartition, Decl(extractExcludePartition.ts, 85, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 87, 31)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 87, 33)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 87, 36)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 87, 31)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 87, 33)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 87, 36)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 87, 31)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 87, 33)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 87, 36)) + +function intersectionBasePartition(value: T & Q): IntersectionBasePartition { +>intersectionBasePartition : Symbol(intersectionBasePartition, Decl(extractExcludePartition.ts, 87, 84)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 89, 35)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 89, 37)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 89, 40)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 89, 44)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 89, 35)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 89, 37)) +>IntersectionBasePartition : Symbol(IntersectionBasePartition, Decl(extractExcludePartition.ts, 85, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 89, 35)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 89, 37)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 89, 40)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 89, 44)) +} + +function intersectionBaseIdentity(value: IntersectionBasePartition): T & Q { +>intersectionBaseIdentity : Symbol(intersectionBaseIdentity, Decl(extractExcludePartition.ts, 91, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 93, 34)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 93, 36)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 93, 39)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 93, 43)) +>IntersectionBasePartition : Symbol(IntersectionBasePartition, Decl(extractExcludePartition.ts, 85, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 93, 34)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 93, 36)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 93, 39)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 93, 34)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 93, 36)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 93, 43)) +} + +type NeverPartition = MyExtract | MyExclude; +>NeverPartition : Symbol(NeverPartition, Decl(extractExcludePartition.ts, 95, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 97, 20)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 97, 20)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 97, 20)) + +type UnknownPartition = MyExtract | MyExclude; +>UnknownPartition : Symbol(UnknownPartition, Decl(extractExcludePartition.ts, 97, 67)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 98, 22)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 98, 22)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 98, 22)) + +function degeneratePartitions(neverPartition: NeverPartition, unknownPartition: UnknownPartition): T { +>degeneratePartitions : Symbol(degeneratePartitions, Decl(extractExcludePartition.ts, 98, 73)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 100, 30)) +>neverPartition : Symbol(neverPartition, Decl(extractExcludePartition.ts, 100, 33)) +>NeverPartition : Symbol(NeverPartition, Decl(extractExcludePartition.ts, 95, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 100, 30)) +>unknownPartition : Symbol(unknownPartition, Decl(extractExcludePartition.ts, 100, 67)) +>UnknownPartition : Symbol(UnknownPartition, Decl(extractExcludePartition.ts, 97, 67)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 100, 30)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 100, 30)) + + return Math.random() ? neverPartition : unknownPartition; +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2025.float16.d.ts, --, --) ... and 1 more) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>neverPartition : Symbol(neverPartition, Decl(extractExcludePartition.ts, 100, 33)) +>unknownPartition : Symbol(unknownPartition, Decl(extractExcludePartition.ts, 100, 67)) +} + +type IncompletePartition = MyExtract | MyExclude; +>IncompletePartition : Symbol(IncompletePartition, Decl(extractExcludePartition.ts, 102, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 104, 25)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 104, 27)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 104, 30)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 104, 25)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 104, 27)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 104, 25)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 104, 27)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 104, 30)) + +function incompletePartition(value: T): IncompletePartition { +>incompletePartition : Symbol(incompletePartition, Decl(extractExcludePartition.ts, 104, 74)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 106, 29)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 106, 31)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 106, 34)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 106, 38)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 106, 29)) +>IncompletePartition : Symbol(IncompletePartition, Decl(extractExcludePartition.ts, 102, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 106, 29)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 106, 31)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 106, 34)) + + // Error: The positive branch does not cover B. + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 106, 38)) +} + +function incompleteIdentity(value: IncompletePartition): T { +>incompleteIdentity : Symbol(incompleteIdentity, Decl(extractExcludePartition.ts, 109, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 111, 28)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 111, 30)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 111, 33)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 111, 37)) +>IncompletePartition : Symbol(IncompletePartition, Decl(extractExcludePartition.ts, 102, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 111, 28)) +>A : Symbol(A, Decl(extractExcludePartition.ts, 111, 30)) +>B : Symbol(B, Decl(extractExcludePartition.ts, 111, 33)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 111, 28)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 111, 37)) +} + +type MismatchedPartition = MyExtract | MyExclude; +>MismatchedPartition : Symbol(MismatchedPartition, Decl(extractExcludePartition.ts, 113, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 115, 25)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 115, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 115, 30)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 115, 25)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 115, 30)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 115, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 115, 30)) + +function mismatchedPartition(value: T | Q): MismatchedPartition { +>mismatchedPartition : Symbol(mismatchedPartition, Decl(extractExcludePartition.ts, 115, 70)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 117, 29)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 117, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 117, 34)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 117, 38)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 117, 29)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 117, 31)) +>MismatchedPartition : Symbol(MismatchedPartition, Decl(extractExcludePartition.ts, 113, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 117, 29)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 117, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 117, 34)) + + // Error: The positive and negative branches have different bases. + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 117, 38)) +} + +function mismatchedIdentity(value: MismatchedPartition): T | Q { +>mismatchedIdentity : Symbol(mismatchedIdentity, Decl(extractExcludePartition.ts, 120, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 122, 28)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 122, 30)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 122, 33)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 122, 37)) +>MismatchedPartition : Symbol(MismatchedPartition, Decl(extractExcludePartition.ts, 113, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 122, 28)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 122, 30)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 122, 33)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 122, 28)) +>Q : Symbol(Q, Decl(extractExcludePartition.ts, 122, 30)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 122, 37)) +} + +type InjectedProps = { +>InjectedProps : Symbol(InjectedProps, Decl(extractExcludePartition.ts, 124, 1)) + + owner: string; +>owner : Symbol(owner, Decl(extractExcludePartition.ts, 126, 22)) + +}; + +declare function withOwner(props: MyOmit & InjectedProps): T; +>withOwner : Symbol(withOwner, Decl(extractExcludePartition.ts, 128, 2)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 130, 27)) +>InjectedProps : Symbol(InjectedProps, Decl(extractExcludePartition.ts, 124, 1)) +>props : Symbol(props, Decl(extractExcludePartition.ts, 130, 52)) +>MyOmit : Symbol(MyOmit, Decl(extractExcludePartition.ts, 1, 33)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 130, 27)) +>InjectedProps : Symbol(InjectedProps, Decl(extractExcludePartition.ts, 124, 1)) +>InjectedProps : Symbol(InjectedProps, Decl(extractExcludePartition.ts, 124, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 130, 27)) + +function render(props: T) { +>render : Symbol(render, Decl(extractExcludePartition.ts, 130, 110)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 132, 16)) +>InjectedProps : Symbol(InjectedProps, Decl(extractExcludePartition.ts, 124, 1)) +>props : Symbol(props, Decl(extractExcludePartition.ts, 132, 41)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 132, 16)) + + return withOwner(props); +>withOwner : Symbol(withOwner, Decl(extractExcludePartition.ts, 128, 2)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 132, 16)) +>props : Symbol(props, Decl(extractExcludePartition.ts, 132, 41)) +} + +type NegatedBasePartition = MyExtract, U> | MyExclude, U>; +>NegatedBasePartition : Symbol(NegatedBasePartition, Decl(extractExcludePartition.ts, 134, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 136, 26)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 136, 28)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 136, 31)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 136, 26)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 136, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 136, 28)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 136, 26)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 136, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 136, 28)) + +function negatedBasePartition(value: T & not V): NegatedBasePartition { +>negatedBasePartition : Symbol(negatedBasePartition, Decl(extractExcludePartition.ts, 136, 99)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 138, 30)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 138, 32)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 138, 35)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 138, 39)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 138, 30)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 138, 35)) +>NegatedBasePartition : Symbol(NegatedBasePartition, Decl(extractExcludePartition.ts, 134, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 138, 30)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 138, 32)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 138, 35)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 138, 39)) +} + +function negatedBaseIdentity(value: NegatedBasePartition): T & not V { +>negatedBaseIdentity : Symbol(negatedBaseIdentity, Decl(extractExcludePartition.ts, 140, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 142, 29)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 142, 31)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 142, 34)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 142, 38)) +>NegatedBasePartition : Symbol(NegatedBasePartition, Decl(extractExcludePartition.ts, 134, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 142, 29)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 142, 31)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 142, 34)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 142, 29)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 142, 34)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 142, 38)) +} + +type DeferredPartition = MyExtract | MyExclude; +>DeferredPartition : Symbol(DeferredPartition, Decl(extractExcludePartition.ts, 144, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 146, 23)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 146, 25)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 146, 28)) +>MyExtract : Symbol(MyExtract, Decl(extractExcludePartition.ts, 0, 0)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 146, 23)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 146, 25)) +>MyExclude : Symbol(MyExclude, Decl(extractExcludePartition.ts, 0, 29)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 146, 23)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 146, 28)) + +function instantiatedPartition(value: T): DeferredPartition { +>instantiatedPartition : Symbol(instantiatedPartition, Decl(extractExcludePartition.ts, 146, 68)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 148, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 148, 33)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 148, 37)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 148, 31)) +>DeferredPartition : Symbol(DeferredPartition, Decl(extractExcludePartition.ts, 144, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 148, 31)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 148, 33)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 148, 33)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 148, 37)) +} + +function instantiatedIdentity(value: DeferredPartition): T { +>instantiatedIdentity : Symbol(instantiatedIdentity, Decl(extractExcludePartition.ts, 150, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 152, 30)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 152, 32)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 152, 36)) +>DeferredPartition : Symbol(DeferredPartition, Decl(extractExcludePartition.ts, 144, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 152, 30)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 152, 32)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 152, 32)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 152, 30)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 152, 36)) +} + +type RecursivePartition = +>RecursivePartition : Symbol(RecursivePartition, Decl(extractExcludePartition.ts, 154, 1)) + + | { next: RecursivePartition; value: string } +>next : Symbol(next, Decl(extractExcludePartition.ts, 157, 7)) +>RecursivePartition : Symbol(RecursivePartition, Decl(extractExcludePartition.ts, 154, 1)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 157, 33)) + + | ({ next: unknown } & not { value: string }); +>next : Symbol(next, Decl(extractExcludePartition.ts, 158, 8)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 158, 32)) + +declare const recursivePartition: RecursivePartition; +>recursivePartition : Symbol(recursivePartition, Decl(extractExcludePartition.ts, 160, 13)) +>RecursivePartition : Symbol(RecursivePartition, Decl(extractExcludePartition.ts, 154, 1)) + +const recursiveNext: unknown = recursivePartition.next; +>recursiveNext : Symbol(recursiveNext, Decl(extractExcludePartition.ts, 161, 5)) +>recursivePartition.next : Symbol(next, Decl(extractExcludePartition.ts, 157, 7), Decl(extractExcludePartition.ts, 158, 8)) +>recursivePartition : Symbol(recursivePartition, Decl(extractExcludePartition.ts, 160, 13)) +>next : Symbol(next, Decl(extractExcludePartition.ts, 157, 7), Decl(extractExcludePartition.ts, 158, 8)) + +// Error: The recursive union is not a number. +const recursiveNumber: number = recursivePartition; +>recursiveNumber : Symbol(recursiveNumber, Decl(extractExcludePartition.ts, 163, 5)) +>recursivePartition : Symbol(recursivePartition, Decl(extractExcludePartition.ts, 160, 13)) + +type PartitionWithPositiveRemainder = (T & U) | (T & not U & V); +>PartitionWithPositiveRemainder : Symbol(PartitionWithPositiveRemainder, Decl(extractExcludePartition.ts, 163, 51)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 165, 36)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 165, 38)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 165, 41)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 165, 36)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 165, 38)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 165, 36)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 165, 38)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 165, 41)) + +function positiveRemainder(value: T & U): PartitionWithPositiveRemainder { +>positiveRemainder : Symbol(positiveRemainder, Decl(extractExcludePartition.ts, 165, 73)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 167, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 167, 29)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 167, 32)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 167, 36)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 167, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 167, 29)) +>PartitionWithPositiveRemainder : Symbol(PartitionWithPositiveRemainder, Decl(extractExcludePartition.ts, 163, 51)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 167, 27)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 167, 29)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 167, 32)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 167, 36)) +} + +function reducedBase(value: T & V): PartitionWithPositiveRemainder { +>reducedBase : Symbol(reducedBase, Decl(extractExcludePartition.ts, 169, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 171, 21)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 171, 23)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 171, 26)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 171, 30)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 171, 21)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 171, 26)) +>PartitionWithPositiveRemainder : Symbol(PartitionWithPositiveRemainder, Decl(extractExcludePartition.ts, 163, 51)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 171, 21)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 171, 23)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 171, 26)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 171, 30)) +} + +function positiveRemainderIdentity(value: PartitionWithPositiveRemainder): (T & U) | (T & V) { +>positiveRemainderIdentity : Symbol(positiveRemainderIdentity, Decl(extractExcludePartition.ts, 173, 1)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 175, 35)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 175, 37)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 175, 40)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 175, 44)) +>PartitionWithPositiveRemainder : Symbol(PartitionWithPositiveRemainder, Decl(extractExcludePartition.ts, 163, 51)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 175, 35)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 175, 37)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 175, 40)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 175, 35)) +>U : Symbol(U, Decl(extractExcludePartition.ts, 175, 37)) +>T : Symbol(T, Decl(extractExcludePartition.ts, 175, 35)) +>V : Symbol(V, Decl(extractExcludePartition.ts, 175, 40)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 175, 44)) +} + +type PartitionContainer = { value: Value }; +>PartitionContainer : Symbol(PartitionContainer, Decl(extractExcludePartition.ts, 177, 1)) +>Value : Symbol(Value, Decl(extractExcludePartition.ts, 179, 24)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 179, 34)) +>Value : Symbol(Value, Decl(extractExcludePartition.ts, 179, 24)) + +type OuterPartition = PartitionContainer; +>OuterPartition : Symbol(OuterPartition, Decl(extractExcludePartition.ts, 179, 50)) +>PartitionContainer : Symbol(PartitionContainer, Decl(extractExcludePartition.ts, 177, 1)) +>InnerPartition : Symbol(InnerPartition, Decl(extractExcludePartition.ts, 180, 57)) + +type InnerPartition = "chosen" | (string & not "chosen"); +>InnerPartition : Symbol(InnerPartition, Decl(extractExcludePartition.ts, 180, 57)) + +function nestedPartition(value: string): InnerPartition { +>nestedPartition : Symbol(nestedPartition, Decl(extractExcludePartition.ts, 181, 57)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 183, 25)) +>InnerPartition : Symbol(InnerPartition, Decl(extractExcludePartition.ts, 180, 57)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 183, 25)) +} + +function nestedPartitionElement(value: string): OuterPartition["value"] { +>nestedPartitionElement : Symbol(nestedPartitionElement, Decl(extractExcludePartition.ts, 185, 1)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 187, 32)) +>OuterPartition : Symbol(OuterPartition, Decl(extractExcludePartition.ts, 179, 50)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 187, 32)) +} + +type ComplementPartition = +>ComplementPartition : Symbol(ComplementPartition, Decl(extractExcludePartition.ts, 189, 1)) + + | { next: ComplementPartition; value: string } +>next : Symbol(next, Decl(extractExcludePartition.ts, 192, 7)) +>ComplementPartition : Symbol(ComplementPartition, Decl(extractExcludePartition.ts, 189, 1)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 192, 34)) + + | ({ next: unknown } & not { value: string }) +>next : Symbol(next, Decl(extractExcludePartition.ts, 193, 8)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 193, 32)) + + | { next: unknown; value: string }; +>next : Symbol(next, Decl(extractExcludePartition.ts, 194, 7)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 194, 22)) + +function recursiveComplement(value: { next: unknown }): ComplementPartition { +>recursiveComplement : Symbol(recursiveComplement, Decl(extractExcludePartition.ts, 194, 39)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 196, 29)) +>next : Symbol(next, Decl(extractExcludePartition.ts, 196, 37)) +>ComplementPartition : Symbol(ComplementPartition, Decl(extractExcludePartition.ts, 189, 1)) + + // Error: Recursive reduction commits to the unreduced union. + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 196, 29)) +} + +function recursiveComplementMember(value: unknown): ComplementPartition["next"] { +>recursiveComplementMember : Symbol(recursiveComplementMember, Decl(extractExcludePartition.ts, 199, 1)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 201, 35)) +>ComplementPartition : Symbol(ComplementPartition, Decl(extractExcludePartition.ts, 189, 1)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 201, 35)) +} + +declare const complementPartition: ComplementPartition; +>complementPartition : Symbol(complementPartition, Decl(extractExcludePartition.ts, 205, 13)) +>ComplementPartition : Symbol(ComplementPartition, Decl(extractExcludePartition.ts, 189, 1)) + +const complementNode: unknown = complementPartition.next; +>complementNode : Symbol(complementNode, Decl(extractExcludePartition.ts, 206, 5)) +>complementPartition.next : Symbol(next, Decl(extractExcludePartition.ts, 192, 7), Decl(extractExcludePartition.ts, 194, 7), Decl(extractExcludePartition.ts, 193, 8)) +>complementPartition : Symbol(complementPartition, Decl(extractExcludePartition.ts, 205, 13)) +>next : Symbol(next, Decl(extractExcludePartition.ts, 192, 7), Decl(extractExcludePartition.ts, 194, 7), Decl(extractExcludePartition.ts, 193, 8)) + +// Error: Reduction must not turn a recursive member into any. +const complementNumber: number = complementPartition.next; +>complementNumber : Symbol(complementNumber, Decl(extractExcludePartition.ts, 208, 5)) +>complementPartition.next : Symbol(next, Decl(extractExcludePartition.ts, 192, 7), Decl(extractExcludePartition.ts, 194, 7), Decl(extractExcludePartition.ts, 193, 8)) +>complementPartition : Symbol(complementPartition, Decl(extractExcludePartition.ts, 205, 13)) +>next : Symbol(next, Decl(extractExcludePartition.ts, 192, 7), Decl(extractExcludePartition.ts, 194, 7), Decl(extractExcludePartition.ts, 193, 8)) + +type ForwardComplementMember = ForwardComplementPartition["next"]; +>ForwardComplementMember : Symbol(ForwardComplementMember, Decl(extractExcludePartition.ts, 208, 58)) +>ForwardComplementPartition : Symbol(ForwardComplementPartition, Decl(extractExcludePartition.ts, 210, 66)) + +type ForwardComplementPartition = +>ForwardComplementPartition : Symbol(ForwardComplementPartition, Decl(extractExcludePartition.ts, 210, 66)) + + | { next: ForwardComplementPartition; value: string } +>next : Symbol(next, Decl(extractExcludePartition.ts, 212, 7)) +>ForwardComplementPartition : Symbol(ForwardComplementPartition, Decl(extractExcludePartition.ts, 210, 66)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 212, 41)) + + | ({ next: unknown } & not { value: string }) +>next : Symbol(next, Decl(extractExcludePartition.ts, 213, 8)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 213, 32)) + + | { next: unknown; value: string }; +>next : Symbol(next, Decl(extractExcludePartition.ts, 214, 7)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 214, 22)) + +function forwardComplement(value: { next: unknown }): ForwardComplementPartition { +>forwardComplement : Symbol(forwardComplement, Decl(extractExcludePartition.ts, 214, 39)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 216, 27)) +>next : Symbol(next, Decl(extractExcludePartition.ts, 216, 35)) +>ForwardComplementPartition : Symbol(ForwardComplementPartition, Decl(extractExcludePartition.ts, 210, 66)) + + // Error: Recursive reduction commits to the unreduced union. + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 216, 27)) +} + +function forwardComplementMember(value: unknown): ForwardComplementMember { +>forwardComplementMember : Symbol(forwardComplementMember, Decl(extractExcludePartition.ts, 219, 1)) +>value : Symbol(value, Decl(extractExcludePartition.ts, 221, 33)) +>ForwardComplementMember : Symbol(ForwardComplementMember, Decl(extractExcludePartition.ts, 208, 58)) + + return value; +>value : Symbol(value, Decl(extractExcludePartition.ts, 221, 33)) +} + +declare const forwardComplementValue: ForwardComplementMember; +>forwardComplementValue : Symbol(forwardComplementValue, Decl(extractExcludePartition.ts, 225, 13)) +>ForwardComplementMember : Symbol(ForwardComplementMember, Decl(extractExcludePartition.ts, 208, 58)) + +// Error: Resolving the indexed access first must still produce unknown. +const forwardComplementNumber: number = forwardComplementValue; +>forwardComplementNumber : Symbol(forwardComplementNumber, Decl(extractExcludePartition.ts, 227, 5)) +>forwardComplementValue : Symbol(forwardComplementValue, Decl(extractExcludePartition.ts, 225, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/extractExcludePartition.types b/tsc/testdata/baselines/reference/compiler/extractExcludePartition.types new file mode 100644 index 0000000000000..7826afe2f68e7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/extractExcludePartition.types @@ -0,0 +1,480 @@ +//// [tests/cases/compiler/extractExcludePartition.ts] //// + +=== extractExcludePartition.ts === +type MyExtract = T & U; +>MyExtract : MyExtract + +type MyExclude = T & not U; +>MyExclude : MyExclude + +type MyOmit = Pick>; +>MyOmit : MyOmit + +type Partition = MyExtract | MyExclude; +>Partition : T + +function partition(value: T): Partition { +>partition : (value: T) => Partition +>value : T + + return value; +>value : T +} + +function identity(value: Partition): T { +>identity : (value: Partition) => T +>value : T + + return value; +>value : T +} + +type UnionPartition = MyExtract | MyExclude; +>UnionPartition : T + +function unionPartition(value: T): UnionPartition { +>unionPartition : (value: T) => UnionPartition +>value : T + + return value; +>value : T +} + +function unionIdentity(value: UnionPartition): T { +>unionIdentity : (value: UnionPartition) => T +>value : T + + return value; +>value : T +} + +type RepeatedPartition = Partition | Partition; +>RepeatedPartition : T + +function repeatedPartition(value: T): RepeatedPartition { +>repeatedPartition : (value: T) => RepeatedPartition +>value : T + + return value; +>value : T +} + +function repeatedIdentity(value: RepeatedPartition): T { +>repeatedIdentity : (value: RepeatedPartition) => T +>value : T + + return value; +>value : T +} + +type DifferentBasePartitions = Partition | Partition; +>DifferentBasePartitions : Q | T + +function differentBasePartitions(value: T | Q): DifferentBasePartitions { +>differentBasePartitions : (value: T | Q) => DifferentBasePartitions +>value : Q | T + + return value; +>value : Q | T +} + +function differentBaseIdentity(value: DifferentBasePartitions): T | Q { +>differentBaseIdentity : (value: DifferentBasePartitions) => T | Q +>value : Q | T + + return value; +>value : Q | T +} + +type UnionBasePartition = Partition; +>UnionBasePartition : T | U + +function unionBasePartition(value: T | U): UnionBasePartition { +>unionBasePartition : (value: T | U) => UnionBasePartition +>value : T | U + + return value; +>value : T | U +} + +function unionBaseIdentity(value: UnionBasePartition): T | U { +>unionBaseIdentity : (value: UnionBasePartition) => T | U +>value : T | U + + return value; +>value : T | U +} + +type RepeatedUnionPartition = Partition | Partition; +>RepeatedUnionPartition : T + +function repeatedUnionPartition(value: T): RepeatedUnionPartition { +>repeatedUnionPartition : (value: T) => RepeatedUnionPartition +>value : T + + return value; +>value : T +} + +function repeatedUnionIdentity(value: RepeatedUnionPartition): T { +>repeatedUnionIdentity : (value: RepeatedUnionPartition) => T +>value : T + + return value; +>value : T +} + +type BooleanPartition = +>BooleanPartition : T + + | MyExtract, B> + | MyExclude, B> + | MyExtract, B> + | MyExclude, B>; + +function booleanPartition(value: T): BooleanPartition { +>booleanPartition : (value: T) => BooleanPartition +>value : T + + return value; +>value : T +} + +function booleanIdentity(value: BooleanPartition): T { +>booleanIdentity : (value: BooleanPartition) => T +>value : T + + return value; +>value : T +} + +type PartitionWithRemainder = MyExtract | MyExclude | R; +>PartitionWithRemainder : R | T + +function partitionWithRemainder(value: T | R): PartitionWithRemainder { +>partitionWithRemainder : (value: T | R) => PartitionWithRemainder +>value : R | T + + return value; +>value : R | T +} + +function remainderIdentity(value: PartitionWithRemainder): T | R { +>remainderIdentity : (value: PartitionWithRemainder) => T | R +>value : R | T + + return value; +>value : R | T +} + +type IntersectionBasePartition = MyExtract | MyExclude; +>IntersectionBasePartition : T & Q + +function intersectionBasePartition(value: T & Q): IntersectionBasePartition { +>intersectionBasePartition : (value: T & Q) => IntersectionBasePartition +>value : T & Q + + return value; +>value : T & Q +} + +function intersectionBaseIdentity(value: IntersectionBasePartition): T & Q { +>intersectionBaseIdentity : (value: IntersectionBasePartition) => T & Q +>value : T & Q + + return value; +>value : T & Q +} + +type NeverPartition = MyExtract | MyExclude; +>NeverPartition : T + +type UnknownPartition = MyExtract | MyExclude; +>UnknownPartition : T + +function degeneratePartitions(neverPartition: NeverPartition, unknownPartition: UnknownPartition): T { +>degeneratePartitions : (neverPartition: NeverPartition, unknownPartition: UnknownPartition) => T +>neverPartition : T +>unknownPartition : T + + return Math.random() ? neverPartition : unknownPartition; +>Math.random() ? neverPartition : unknownPartition : T +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>neverPartition : T +>unknownPartition : T +} + +type IncompletePartition = MyExtract | MyExclude; +>IncompletePartition : MyExtract | (T & not B) + +function incompletePartition(value: T): IncompletePartition { +>incompletePartition : (value: T) => IncompletePartition +>value : T + + // Error: The positive branch does not cover B. + return value; +>value : T +} + +function incompleteIdentity(value: IncompletePartition): T { +>incompleteIdentity : (value: IncompletePartition) => T +>value : MyExtract | (T & not B) + + return value; +>value : MyExtract | (T & not B) +} + +type MismatchedPartition = MyExtract | MyExclude; +>MismatchedPartition : MismatchedPartition + +function mismatchedPartition(value: T | Q): MismatchedPartition { +>mismatchedPartition : (value: T | Q) => MismatchedPartition +>value : Q | T + + // Error: The positive and negative branches have different bases. + return value; +>value : Q | T +} + +function mismatchedIdentity(value: MismatchedPartition): T | Q { +>mismatchedIdentity : (value: MismatchedPartition) => T | Q +>value : MismatchedPartition + + return value; +>value : MismatchedPartition +} + +type InjectedProps = { +>InjectedProps : InjectedProps + + owner: string; +>owner : string + +}; + +declare function withOwner(props: MyOmit & InjectedProps): T; +>withOwner : (props: MyOmit & InjectedProps) => T +>props : MyOmit & InjectedProps + +function render(props: T) { +>render : (props: T) => T +>props : T + + return withOwner(props); +>withOwner(props) : T +>withOwner : (props: MyOmit & InjectedProps) => T_1 +>props : T +} + +type NegatedBasePartition = MyExtract, U> | MyExclude, U>; +>NegatedBasePartition : T & not V + +function negatedBasePartition(value: T & not V): NegatedBasePartition { +>negatedBasePartition : (value: T & not V) => NegatedBasePartition +>value : T & not V + + return value; +>value : T & not V +} + +function negatedBaseIdentity(value: NegatedBasePartition): T & not V { +>negatedBaseIdentity : (value: NegatedBasePartition) => T & not V +>value : T & not V + + return value; +>value : T & not V +} + +type DeferredPartition = MyExtract | MyExclude; +>DeferredPartition : DeferredPartition + +function instantiatedPartition(value: T): DeferredPartition { +>instantiatedPartition : (value: T) => DeferredPartition +>value : T + + return value; +>value : T +} + +function instantiatedIdentity(value: DeferredPartition): T { +>instantiatedIdentity : (value: DeferredPartition) => T +>value : T + + return value; +>value : T +} + +type RecursivePartition = +>RecursivePartition : RecursivePartition + + | { next: RecursivePartition; value: string } +>next : RecursivePartition +>value : string + + | ({ next: unknown } & not { value: string }); +>next : unknown +>value : string + +declare const recursivePartition: RecursivePartition; +>recursivePartition : RecursivePartition + +const recursiveNext: unknown = recursivePartition.next; +>recursiveNext : unknown +>recursivePartition.next : unknown +>recursivePartition : RecursivePartition +>next : unknown + +// Error: The recursive union is not a number. +const recursiveNumber: number = recursivePartition; +>recursiveNumber : number +>recursivePartition : RecursivePartition + +type PartitionWithPositiveRemainder = (T & U) | (T & not U & V); +>PartitionWithPositiveRemainder : (T & U) | (T & V) + +function positiveRemainder(value: T & U): PartitionWithPositiveRemainder { +>positiveRemainder : (value: T & U) => PartitionWithPositiveRemainder +>value : T & U + + return value; +>value : T & U +} + +function reducedBase(value: T & V): PartitionWithPositiveRemainder { +>reducedBase : (value: T & V) => PartitionWithPositiveRemainder +>value : T & V + + return value; +>value : T & V +} + +function positiveRemainderIdentity(value: PartitionWithPositiveRemainder): (T & U) | (T & V) { +>positiveRemainderIdentity : (value: PartitionWithPositiveRemainder) => (T & U) | (T & V) +>value : (T & U) | (T & V) + + return value; +>value : (T & U) | (T & V) +} + +type PartitionContainer = { value: Value }; +>PartitionContainer : PartitionContainer +>value : Value + +type OuterPartition = PartitionContainer; +>OuterPartition : OuterPartition + +type InnerPartition = "chosen" | (string & not "chosen"); +>InnerPartition : string + +function nestedPartition(value: string): InnerPartition { +>nestedPartition : (value: string) => InnerPartition +>value : string + + return value; +>value : string +} + +function nestedPartitionElement(value: string): OuterPartition["value"] { +>nestedPartitionElement : (value: string) => OuterPartition["value"] +>value : string + + return value; +>value : string +} + +type ComplementPartition = +>ComplementPartition : ComplementPartition + + | { next: ComplementPartition; value: string } +>next : ComplementPartition +>value : string + + | ({ next: unknown } & not { value: string }) +>next : unknown +>value : string + + | { next: unknown; value: string }; +>next : unknown +>value : string + +function recursiveComplement(value: { next: unknown }): ComplementPartition { +>recursiveComplement : (value: { next: unknown; }) => ComplementPartition +>value : { next: unknown; } +>next : unknown + + // Error: Recursive reduction commits to the unreduced union. + return value; +>value : { next: unknown; } +} + +function recursiveComplementMember(value: unknown): ComplementPartition["next"] { +>recursiveComplementMember : (value: unknown) => ComplementPartition["next"] +>value : unknown + + return value; +>value : unknown +} + +declare const complementPartition: ComplementPartition; +>complementPartition : ComplementPartition + +const complementNode: unknown = complementPartition.next; +>complementNode : unknown +>complementPartition.next : unknown +>complementPartition : ComplementPartition +>next : unknown + +// Error: Reduction must not turn a recursive member into any. +const complementNumber: number = complementPartition.next; +>complementNumber : number +>complementPartition.next : unknown +>complementPartition : ComplementPartition +>next : unknown + +type ForwardComplementMember = ForwardComplementPartition["next"]; +>ForwardComplementMember : unknown + +type ForwardComplementPartition = +>ForwardComplementPartition : ForwardComplementPartition + + | { next: ForwardComplementPartition; value: string } +>next : ForwardComplementPartition +>value : string + + | ({ next: unknown } & not { value: string }) +>next : unknown +>value : string + + | { next: unknown; value: string }; +>next : unknown +>value : string + +function forwardComplement(value: { next: unknown }): ForwardComplementPartition { +>forwardComplement : (value: { next: unknown; }) => ForwardComplementPartition +>value : { next: unknown; } +>next : unknown + + // Error: Recursive reduction commits to the unreduced union. + return value; +>value : { next: unknown; } +} + +function forwardComplementMember(value: unknown): ForwardComplementMember { +>forwardComplementMember : (value: unknown) => ForwardComplementMember +>value : unknown + + return value; +>value : unknown +} + +declare const forwardComplementValue: ForwardComplementMember; +>forwardComplementValue : unknown + +// Error: Resolving the indexed access first must still produce unknown. +const forwardComplementNumber: number = forwardComplementValue; +>forwardComplementNumber : number +>forwardComplementValue : unknown + diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.js b/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.js new file mode 100644 index 0000000000000..4e8abd811ab14 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.js @@ -0,0 +1,119 @@ +//// [tests/cases/compiler/freshNegatedIntersectionReduction.ts] //// + +//// [freshNegatedIntersectionReduction.ts] +export function narrowedArray(value: Value) { + if (typeof value !== "undefined") { + for (const element of value) {} + return [...value]; + } + return []; +} + +export function explicitUndefined(value: Value & not undefined) { + if (typeof value !== "undefined") { + const retained = value; + return retained; + } + throw new Error(); +} + +export function explicitNull(value: Value & not null) { + if (value !== null) { + const retained = value; + return retained; + } + throw new Error(); +} + +export function freshOnly(value: Value) { + if (typeof value !== "string") { + const widened = value; + return widened; + } + throw new Error(); +} + +export function explicitString(value: Value & not string) { + if (typeof value !== "string") { + const retained = value; + return retained; + } + throw new Error(); +} + +export function unionFreshFirst(value: unknown, regular: not string, choose: boolean) { + if (typeof value !== "string") { + const merged = choose ? value : regular; + return merged; + } + throw new Error(); +} + +export function unionRegularFirst(value: unknown, regular: not string, choose: boolean) { + if (typeof value !== "string") { + const merged = choose ? regular : value; + return merged; + } + throw new Error(); +} + +//// [freshNegatedIntersectionReduction.js] +export function narrowedArray(value) { + if (typeof value !== "undefined") { + for (const element of value) { } + return [...value]; + } + return []; +} +export function explicitUndefined(value) { + if (typeof value !== "undefined") { + const retained = value; + return retained; + } + throw new Error(); +} +export function explicitNull(value) { + if (value !== null) { + const retained = value; + return retained; + } + throw new Error(); +} +export function freshOnly(value) { + if (typeof value !== "string") { + const widened = value; + return widened; + } + throw new Error(); +} +export function explicitString(value) { + if (typeof value !== "string") { + const retained = value; + return retained; + } + throw new Error(); +} +export function unionFreshFirst(value, regular, choose) { + if (typeof value !== "string") { + const merged = choose ? value : regular; + return merged; + } + throw new Error(); +} +export function unionRegularFirst(value, regular, choose) { + if (typeof value !== "string") { + const merged = choose ? regular : value; + return merged; + } + throw new Error(); +} + + +//// [freshNegatedIntersectionReduction.d.ts] +export declare function narrowedArray(value: Value): (Value & {})[number][]; +export declare function explicitUndefined(value: Value & not undefined): Value & not undefined; +export declare function explicitNull(value: Value & not null): Value & not null; +export declare function freshOnly(value: Value): Value; +export declare function explicitString(value: Value & not string): Value & not string; +export declare function unionFreshFirst(value: unknown, regular: not string, choose: boolean): not string; +export declare function unionRegularFirst(value: unknown, regular: not string, choose: boolean): not string; diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.symbols b/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.symbols new file mode 100644 index 0000000000000..c41ba254d31a2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.symbols @@ -0,0 +1,145 @@ +//// [tests/cases/compiler/freshNegatedIntersectionReduction.ts] //// + +=== freshNegatedIntersectionReduction.ts === +export function narrowedArray(value: Value) { +>narrowedArray : Symbol(narrowedArray, Decl(freshNegatedIntersectionReduction.ts, 0, 0)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 0, 30)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 0, 67)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 0, 30)) + + if (typeof value !== "undefined") { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 0, 67)) + + for (const element of value) {} +>element : Symbol(element, Decl(freshNegatedIntersectionReduction.ts, 2, 18)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 0, 67)) + + return [...value]; +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 0, 67)) + } + return []; +} + +export function explicitUndefined(value: Value & not undefined) { +>explicitUndefined : Symbol(explicitUndefined, Decl(freshNegatedIntersectionReduction.ts, 6, 1)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 8, 34)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 8, 41)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 8, 34)) + + if (typeof value !== "undefined") { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 8, 41)) + + const retained = value; +>retained : Symbol(retained, Decl(freshNegatedIntersectionReduction.ts, 10, 13)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 8, 41)) + + return retained; +>retained : Symbol(retained, Decl(freshNegatedIntersectionReduction.ts, 10, 13)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +export function explicitNull(value: Value & not null) { +>explicitNull : Symbol(explicitNull, Decl(freshNegatedIntersectionReduction.ts, 14, 1)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 16, 29)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 16, 36)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 16, 29)) + + if (value !== null) { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 16, 36)) + + const retained = value; +>retained : Symbol(retained, Decl(freshNegatedIntersectionReduction.ts, 18, 13)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 16, 36)) + + return retained; +>retained : Symbol(retained, Decl(freshNegatedIntersectionReduction.ts, 18, 13)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +export function freshOnly(value: Value) { +>freshOnly : Symbol(freshOnly, Decl(freshNegatedIntersectionReduction.ts, 22, 1)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 24, 26)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 24, 33)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 24, 26)) + + if (typeof value !== "string") { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 24, 33)) + + const widened = value; +>widened : Symbol(widened, Decl(freshNegatedIntersectionReduction.ts, 26, 13)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 24, 33)) + + return widened; +>widened : Symbol(widened, Decl(freshNegatedIntersectionReduction.ts, 26, 13)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +export function explicitString(value: Value & not string) { +>explicitString : Symbol(explicitString, Decl(freshNegatedIntersectionReduction.ts, 30, 1)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 32, 31)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 32, 38)) +>Value : Symbol(Value, Decl(freshNegatedIntersectionReduction.ts, 32, 31)) + + if (typeof value !== "string") { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 32, 38)) + + const retained = value; +>retained : Symbol(retained, Decl(freshNegatedIntersectionReduction.ts, 34, 13)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 32, 38)) + + return retained; +>retained : Symbol(retained, Decl(freshNegatedIntersectionReduction.ts, 34, 13)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +export function unionFreshFirst(value: unknown, regular: not string, choose: boolean) { +>unionFreshFirst : Symbol(unionFreshFirst, Decl(freshNegatedIntersectionReduction.ts, 38, 1)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 40, 32)) +>regular : Symbol(regular, Decl(freshNegatedIntersectionReduction.ts, 40, 47)) +>choose : Symbol(choose, Decl(freshNegatedIntersectionReduction.ts, 40, 68)) + + if (typeof value !== "string") { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 40, 32)) + + const merged = choose ? value : regular; +>merged : Symbol(merged, Decl(freshNegatedIntersectionReduction.ts, 42, 13)) +>choose : Symbol(choose, Decl(freshNegatedIntersectionReduction.ts, 40, 68)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 40, 32)) +>regular : Symbol(regular, Decl(freshNegatedIntersectionReduction.ts, 40, 47)) + + return merged; +>merged : Symbol(merged, Decl(freshNegatedIntersectionReduction.ts, 42, 13)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +export function unionRegularFirst(value: unknown, regular: not string, choose: boolean) { +>unionRegularFirst : Symbol(unionRegularFirst, Decl(freshNegatedIntersectionReduction.ts, 46, 1)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 48, 34)) +>regular : Symbol(regular, Decl(freshNegatedIntersectionReduction.ts, 48, 49)) +>choose : Symbol(choose, Decl(freshNegatedIntersectionReduction.ts, 48, 70)) + + if (typeof value !== "string") { +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 48, 34)) + + const merged = choose ? regular : value; +>merged : Symbol(merged, Decl(freshNegatedIntersectionReduction.ts, 50, 13)) +>choose : Symbol(choose, Decl(freshNegatedIntersectionReduction.ts, 48, 70)) +>regular : Symbol(regular, Decl(freshNegatedIntersectionReduction.ts, 48, 49)) +>value : Symbol(value, Decl(freshNegatedIntersectionReduction.ts, 48, 34)) + + return merged; +>merged : Symbol(merged, Decl(freshNegatedIntersectionReduction.ts, 50, 13)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.types b/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.types new file mode 100644 index 0000000000000..c30089c2b86f9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedIntersectionReduction.types @@ -0,0 +1,165 @@ +//// [tests/cases/compiler/freshNegatedIntersectionReduction.ts] //// + +=== freshNegatedIntersectionReduction.ts === +export function narrowedArray(value: Value) { +>narrowedArray : (value: Value) => (Value & {})[number][] +>value : Value + + if (typeof value !== "undefined") { +>typeof value !== "undefined" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : Value +>"undefined" : "undefined" + + for (const element of value) {} +>element : unknown +>value : Value & {} + + return [...value]; +>[...value] : (Value & {})[number][] +>...value : unknown +>value : Value & {} + } + return []; +>[] : never[] +} + +export function explicitUndefined(value: Value & not undefined) { +>explicitUndefined : (value: Value & not undefined) => Value & not undefined +>value : Value & not undefined + + if (typeof value !== "undefined") { +>typeof value !== "undefined" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : Value & not undefined +>"undefined" : "undefined" + + const retained = value; +>retained : Value & not undefined +>value : Value & not undefined + + return retained; +>retained : Value & not undefined + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +export function explicitNull(value: Value & not null) { +>explicitNull : (value: Value & not null) => Value & not null +>value : Value & not null + + if (value !== null) { +>value !== null : boolean +>value : Value & not null + + const retained = value; +>retained : Value & not null +>value : Value & not null + + return retained; +>retained : Value & not null + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +export function freshOnly(value: Value) { +>freshOnly : (value: Value) => Value +>value : Value + + if (typeof value !== "string") { +>typeof value !== "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : Value +>"string" : "string" + + const widened = value; +>widened : Value +>value : Value & not string + + return widened; +>widened : Value + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +export function explicitString(value: Value & not string) { +>explicitString : (value: Value & not string) => Value & not string +>value : Value & not string + + if (typeof value !== "string") { +>typeof value !== "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : Value & not string +>"string" : "string" + + const retained = value; +>retained : Value & not string +>value : Value & not string + + return retained; +>retained : Value & not string + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +export function unionFreshFirst(value: unknown, regular: not string, choose: boolean) { +>unionFreshFirst : (value: unknown, regular: not string, choose: boolean) => not string +>value : unknown +>regular : not string +>choose : boolean + + if (typeof value !== "string") { +>typeof value !== "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const merged = choose ? value : regular; +>merged : not string +>choose ? value : regular : not string +>choose : boolean +>value : not string +>regular : not string + + return merged; +>merged : not string + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +export function unionRegularFirst(value: unknown, regular: not string, choose: boolean) { +>unionRegularFirst : (value: unknown, regular: not string, choose: boolean) => not string +>value : unknown +>regular : not string +>choose : boolean + + if (typeof value !== "string") { +>typeof value !== "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const merged = choose ? regular : value; +>merged : not string +>choose ? regular : value : not string +>choose : boolean +>regular : not string +>value : not string + + return merged; +>merged : not string + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.errors.txt b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.errors.txt new file mode 100644 index 0000000000000..62e2a136971f5 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.errors.txt @@ -0,0 +1,92 @@ +freshNegatedTypeWidening.ts(19,1): error TS2352: Conversion of type 'BaseNode & not WrappedNode' to type 'WrappedNode' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + Property 'expression' is missing in type 'BaseNode' but required in type 'WrappedNode'. +freshNegatedTypeWidening.ts(62,1): error TS2352: Conversion of type '{} & not string' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + + +==== freshNegatedTypeWidening.ts (2 errors) ==== + interface BaseNode { + kind: number; + } + + interface WrappedNode extends BaseNode { + expression: BaseNode; + } + + declare function isWrappedNode(node: BaseNode): node is WrappedNode; + + function assertWrappedNode(node: BaseNode) { + if (!isWrappedNode(node)) { + return node as WrappedNode; + } + return node; + } + + declare const explicitlyUnwrapped: BaseNode & not WrappedNode; + explicitlyUnwrapped as WrappedNode; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Conversion of type 'BaseNode & not WrappedNode' to type 'WrappedNode' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. +!!! error TS2352: Property 'expression' is missing in type 'BaseNode' but required in type 'WrappedNode'. +!!! related TS2728 freshNegatedTypeWidening.ts:6:5: 'expression' is declared here. + + function skipWrappers(node: WrappedNode): WrappedNode; + function skipWrappers(node: BaseNode): BaseNode; + function skipWrappers(node: BaseNode) { + while (isWrappedNode(node)) { + node = node.expression; + } + return node; + } + + interface NamedNode extends BaseNode { + name: string; + } + + declare function isSpecialNode(node: BaseNode): node is WrappedNode | NamedNode; + + function skipSpecialNodes(node: WrappedNode): WrappedNode; + function skipSpecialNodes(node: BaseNode): BaseNode; + function skipSpecialNodes(node: BaseNode) { + while (isSpecialNode(node)) { + node = { kind: 0 }; + } + return node; + } + + function isOrdinaryNode(node: BaseNode) { + return !isSpecialNode(node); + } + + declare const candidate: BaseNode; + if (!isOrdinaryNode(candidate)) { + candidate.kind; + } + + function assertString(value: {}) { + if (typeof value !== "string") { + return value as string; + } + return value; + } + + declare const explicitlyNotString: {} & not string; + explicitlyNotString as string; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Conversion of type '{} & not string' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + + function skipStrings(value: string): string; + function skipStrings(value: {}): {}; + function skipStrings(value: {}) { + while (typeof value === "string") { + value = {}; + } + return value; + } + + function isNotString(value: {}) { + return typeof value !== "string"; + } + + declare const nonNullValue: {}; + if (!isNotString(nonNullValue)) { + nonNullValue.toString(); + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.js b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.js new file mode 100644 index 0000000000000..428ba17e1d24f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.js @@ -0,0 +1,158 @@ +//// [tests/cases/compiler/freshNegatedTypeWidening.ts] //// + +//// [freshNegatedTypeWidening.ts] +interface BaseNode { + kind: number; +} + +interface WrappedNode extends BaseNode { + expression: BaseNode; +} + +declare function isWrappedNode(node: BaseNode): node is WrappedNode; + +function assertWrappedNode(node: BaseNode) { + if (!isWrappedNode(node)) { + return node as WrappedNode; + } + return node; +} + +declare const explicitlyUnwrapped: BaseNode & not WrappedNode; +explicitlyUnwrapped as WrappedNode; + +function skipWrappers(node: WrappedNode): WrappedNode; +function skipWrappers(node: BaseNode): BaseNode; +function skipWrappers(node: BaseNode) { + while (isWrappedNode(node)) { + node = node.expression; + } + return node; +} + +interface NamedNode extends BaseNode { + name: string; +} + +declare function isSpecialNode(node: BaseNode): node is WrappedNode | NamedNode; + +function skipSpecialNodes(node: WrappedNode): WrappedNode; +function skipSpecialNodes(node: BaseNode): BaseNode; +function skipSpecialNodes(node: BaseNode) { + while (isSpecialNode(node)) { + node = { kind: 0 }; + } + return node; +} + +function isOrdinaryNode(node: BaseNode) { + return !isSpecialNode(node); +} + +declare const candidate: BaseNode; +if (!isOrdinaryNode(candidate)) { + candidate.kind; +} + +function assertString(value: {}) { + if (typeof value !== "string") { + return value as string; + } + return value; +} + +declare const explicitlyNotString: {} & not string; +explicitlyNotString as string; + +function skipStrings(value: string): string; +function skipStrings(value: {}): {}; +function skipStrings(value: {}) { + while (typeof value === "string") { + value = {}; + } + return value; +} + +function isNotString(value: {}) { + return typeof value !== "string"; +} + +declare const nonNullValue: {}; +if (!isNotString(nonNullValue)) { + nonNullValue.toString(); +} + +//// [freshNegatedTypeWidening.js] +"use strict"; +function assertWrappedNode(node) { + if (!isWrappedNode(node)) { + return node; + } + return node; +} +explicitlyUnwrapped; +function skipWrappers(node) { + while (isWrappedNode(node)) { + node = node.expression; + } + return node; +} +function skipSpecialNodes(node) { + while (isSpecialNode(node)) { + node = { kind: 0 }; + } + return node; +} +function isOrdinaryNode(node) { + return !isSpecialNode(node); +} +if (!isOrdinaryNode(candidate)) { + candidate.kind; +} +function assertString(value) { + if (typeof value !== "string") { + return value; + } + return value; +} +explicitlyNotString; +function skipStrings(value) { + while (typeof value === "string") { + value = {}; + } + return value; +} +function isNotString(value) { + return typeof value !== "string"; +} +if (!isNotString(nonNullValue)) { + nonNullValue.toString(); +} + + +//// [freshNegatedTypeWidening.d.ts] +interface BaseNode { + kind: number; +} +interface WrappedNode extends BaseNode { + expression: BaseNode; +} +declare function isWrappedNode(node: BaseNode): node is WrappedNode; +declare function assertWrappedNode(node: BaseNode): WrappedNode; +declare const explicitlyUnwrapped: BaseNode & not WrappedNode; +declare function skipWrappers(node: WrappedNode): WrappedNode; +declare function skipWrappers(node: BaseNode): BaseNode; +interface NamedNode extends BaseNode { + name: string; +} +declare function isSpecialNode(node: BaseNode): node is WrappedNode | NamedNode; +declare function skipSpecialNodes(node: WrappedNode): WrappedNode; +declare function skipSpecialNodes(node: BaseNode): BaseNode; +declare function isOrdinaryNode(node: BaseNode): boolean; +declare const candidate: BaseNode; +declare function assertString(value: {}): string; +declare const explicitlyNotString: {} & not string; +declare function skipStrings(value: string): string; +declare function skipStrings(value: {}): {}; +declare function isNotString(value: {}): boolean; +declare const nonNullValue: {}; diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.symbols b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.symbols new file mode 100644 index 0000000000000..bb4203e4b2cda --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.symbols @@ -0,0 +1,214 @@ +//// [tests/cases/compiler/freshNegatedTypeWidening.ts] //// + +=== freshNegatedTypeWidening.ts === +interface BaseNode { +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + kind: number; +>kind : Symbol(BaseNode.kind, Decl(freshNegatedTypeWidening.ts, 0, 20)) +} + +interface WrappedNode extends BaseNode { +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + expression: BaseNode; +>expression : Symbol(WrappedNode.expression, Decl(freshNegatedTypeWidening.ts, 4, 40)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) +} + +declare function isWrappedNode(node: BaseNode): node is WrappedNode; +>isWrappedNode : Symbol(isWrappedNode, Decl(freshNegatedTypeWidening.ts, 6, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 8, 31)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 8, 31)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) + +function assertWrappedNode(node: BaseNode) { +>assertWrappedNode : Symbol(assertWrappedNode, Decl(freshNegatedTypeWidening.ts, 8, 68)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 10, 27)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + if (!isWrappedNode(node)) { +>isWrappedNode : Symbol(isWrappedNode, Decl(freshNegatedTypeWidening.ts, 6, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 10, 27)) + + return node as WrappedNode; +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 10, 27)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) + } + return node; +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 10, 27)) +} + +declare const explicitlyUnwrapped: BaseNode & not WrappedNode; +>explicitlyUnwrapped : Symbol(explicitlyUnwrapped, Decl(freshNegatedTypeWidening.ts, 17, 13)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) + +explicitlyUnwrapped as WrappedNode; +>explicitlyUnwrapped : Symbol(explicitlyUnwrapped, Decl(freshNegatedTypeWidening.ts, 17, 13)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) + +function skipWrappers(node: WrappedNode): WrappedNode; +>skipWrappers : Symbol(skipWrappers, Decl(freshNegatedTypeWidening.ts, 18, 35), Decl(freshNegatedTypeWidening.ts, 20, 54), Decl(freshNegatedTypeWidening.ts, 21, 48)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 20, 22)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) + +function skipWrappers(node: BaseNode): BaseNode; +>skipWrappers : Symbol(skipWrappers, Decl(freshNegatedTypeWidening.ts, 18, 35), Decl(freshNegatedTypeWidening.ts, 20, 54), Decl(freshNegatedTypeWidening.ts, 21, 48)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 21, 22)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + +function skipWrappers(node: BaseNode) { +>skipWrappers : Symbol(skipWrappers, Decl(freshNegatedTypeWidening.ts, 18, 35), Decl(freshNegatedTypeWidening.ts, 20, 54), Decl(freshNegatedTypeWidening.ts, 21, 48)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 22, 22)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + while (isWrappedNode(node)) { +>isWrappedNode : Symbol(isWrappedNode, Decl(freshNegatedTypeWidening.ts, 6, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 22, 22)) + + node = node.expression; +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 22, 22)) +>node.expression : Symbol(WrappedNode.expression, Decl(freshNegatedTypeWidening.ts, 4, 40)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 22, 22)) +>expression : Symbol(WrappedNode.expression, Decl(freshNegatedTypeWidening.ts, 4, 40)) + } + return node; +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 22, 22)) +} + +interface NamedNode extends BaseNode { +>NamedNode : Symbol(NamedNode, Decl(freshNegatedTypeWidening.ts, 27, 1)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + name: string; +>name : Symbol(NamedNode.name, Decl(freshNegatedTypeWidening.ts, 29, 38)) +} + +declare function isSpecialNode(node: BaseNode): node is WrappedNode | NamedNode; +>isSpecialNode : Symbol(isSpecialNode, Decl(freshNegatedTypeWidening.ts, 31, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 33, 31)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 33, 31)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) +>NamedNode : Symbol(NamedNode, Decl(freshNegatedTypeWidening.ts, 27, 1)) + +function skipSpecialNodes(node: WrappedNode): WrappedNode; +>skipSpecialNodes : Symbol(skipSpecialNodes, Decl(freshNegatedTypeWidening.ts, 33, 80), Decl(freshNegatedTypeWidening.ts, 35, 58), Decl(freshNegatedTypeWidening.ts, 36, 52)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 35, 26)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) +>WrappedNode : Symbol(WrappedNode, Decl(freshNegatedTypeWidening.ts, 2, 1)) + +function skipSpecialNodes(node: BaseNode): BaseNode; +>skipSpecialNodes : Symbol(skipSpecialNodes, Decl(freshNegatedTypeWidening.ts, 33, 80), Decl(freshNegatedTypeWidening.ts, 35, 58), Decl(freshNegatedTypeWidening.ts, 36, 52)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 36, 26)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + +function skipSpecialNodes(node: BaseNode) { +>skipSpecialNodes : Symbol(skipSpecialNodes, Decl(freshNegatedTypeWidening.ts, 33, 80), Decl(freshNegatedTypeWidening.ts, 35, 58), Decl(freshNegatedTypeWidening.ts, 36, 52)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 37, 26)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + while (isSpecialNode(node)) { +>isSpecialNode : Symbol(isSpecialNode, Decl(freshNegatedTypeWidening.ts, 31, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 37, 26)) + + node = { kind: 0 }; +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 37, 26)) +>kind : Symbol(kind, Decl(freshNegatedTypeWidening.ts, 39, 16)) + } + return node; +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 37, 26)) +} + +function isOrdinaryNode(node: BaseNode) { +>isOrdinaryNode : Symbol(isOrdinaryNode, Decl(freshNegatedTypeWidening.ts, 42, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 44, 24)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + + return !isSpecialNode(node); +>isSpecialNode : Symbol(isSpecialNode, Decl(freshNegatedTypeWidening.ts, 31, 1)) +>node : Symbol(node, Decl(freshNegatedTypeWidening.ts, 44, 24)) +} + +declare const candidate: BaseNode; +>candidate : Symbol(candidate, Decl(freshNegatedTypeWidening.ts, 48, 13)) +>BaseNode : Symbol(BaseNode, Decl(freshNegatedTypeWidening.ts, 0, 0)) + +if (!isOrdinaryNode(candidate)) { +>isOrdinaryNode : Symbol(isOrdinaryNode, Decl(freshNegatedTypeWidening.ts, 42, 1)) +>candidate : Symbol(candidate, Decl(freshNegatedTypeWidening.ts, 48, 13)) + + candidate.kind; +>candidate.kind : Symbol(BaseNode.kind, Decl(freshNegatedTypeWidening.ts, 0, 20)) +>candidate : Symbol(candidate, Decl(freshNegatedTypeWidening.ts, 48, 13)) +>kind : Symbol(BaseNode.kind, Decl(freshNegatedTypeWidening.ts, 0, 20)) +} + +function assertString(value: {}) { +>assertString : Symbol(assertString, Decl(freshNegatedTypeWidening.ts, 51, 1)) +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 53, 22)) + + if (typeof value !== "string") { +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 53, 22)) + + return value as string; +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 53, 22)) + } + return value; +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 53, 22)) +} + +declare const explicitlyNotString: {} & not string; +>explicitlyNotString : Symbol(explicitlyNotString, Decl(freshNegatedTypeWidening.ts, 60, 13)) + +explicitlyNotString as string; +>explicitlyNotString : Symbol(explicitlyNotString, Decl(freshNegatedTypeWidening.ts, 60, 13)) + +function skipStrings(value: string): string; +>skipStrings : Symbol(skipStrings, Decl(freshNegatedTypeWidening.ts, 61, 30), Decl(freshNegatedTypeWidening.ts, 63, 44), Decl(freshNegatedTypeWidening.ts, 64, 36)) +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 63, 21)) + +function skipStrings(value: {}): {}; +>skipStrings : Symbol(skipStrings, Decl(freshNegatedTypeWidening.ts, 61, 30), Decl(freshNegatedTypeWidening.ts, 63, 44), Decl(freshNegatedTypeWidening.ts, 64, 36)) +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 64, 21)) + +function skipStrings(value: {}) { +>skipStrings : Symbol(skipStrings, Decl(freshNegatedTypeWidening.ts, 61, 30), Decl(freshNegatedTypeWidening.ts, 63, 44), Decl(freshNegatedTypeWidening.ts, 64, 36)) +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 65, 21)) + + while (typeof value === "string") { +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 65, 21)) + + value = {}; +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 65, 21)) + } + return value; +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 65, 21)) +} + +function isNotString(value: {}) { +>isNotString : Symbol(isNotString, Decl(freshNegatedTypeWidening.ts, 70, 1)) +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 72, 21)) + + return typeof value !== "string"; +>value : Symbol(value, Decl(freshNegatedTypeWidening.ts, 72, 21)) +} + +declare const nonNullValue: {}; +>nonNullValue : Symbol(nonNullValue, Decl(freshNegatedTypeWidening.ts, 76, 13)) + +if (!isNotString(nonNullValue)) { +>isNotString : Symbol(isNotString, Decl(freshNegatedTypeWidening.ts, 70, 1)) +>nonNullValue : Symbol(nonNullValue, Decl(freshNegatedTypeWidening.ts, 76, 13)) + + nonNullValue.toString(); +>nonNullValue.toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) +>nonNullValue : Symbol(nonNullValue, Decl(freshNegatedTypeWidening.ts, 76, 13)) +>toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.types b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.types new file mode 100644 index 0000000000000..66916df25e811 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/freshNegatedTypeWidening.types @@ -0,0 +1,211 @@ +//// [tests/cases/compiler/freshNegatedTypeWidening.ts] //// + +=== freshNegatedTypeWidening.ts === +interface BaseNode { + kind: number; +>kind : number +} + +interface WrappedNode extends BaseNode { + expression: BaseNode; +>expression : BaseNode +} + +declare function isWrappedNode(node: BaseNode): node is WrappedNode; +>isWrappedNode : (node: BaseNode) => node is WrappedNode +>node : BaseNode + +function assertWrappedNode(node: BaseNode) { +>assertWrappedNode : (node: BaseNode) => WrappedNode +>node : BaseNode + + if (!isWrappedNode(node)) { +>!isWrappedNode(node) : boolean +>isWrappedNode(node) : boolean +>isWrappedNode : (node: BaseNode) => node is WrappedNode +>node : BaseNode + + return node as WrappedNode; +>node as WrappedNode : WrappedNode +>node : BaseNode + } + return node; +>node : WrappedNode +} + +declare const explicitlyUnwrapped: BaseNode & not WrappedNode; +>explicitlyUnwrapped : BaseNode & not WrappedNode + +explicitlyUnwrapped as WrappedNode; +>explicitlyUnwrapped as WrappedNode : WrappedNode +>explicitlyUnwrapped : BaseNode & not WrappedNode + +function skipWrappers(node: WrappedNode): WrappedNode; +>skipWrappers : { (node: WrappedNode): WrappedNode; (node: BaseNode): BaseNode; } +>node : WrappedNode + +function skipWrappers(node: BaseNode): BaseNode; +>skipWrappers : { (node: WrappedNode): WrappedNode; (node: BaseNode): BaseNode; } +>node : BaseNode + +function skipWrappers(node: BaseNode) { +>skipWrappers : { (node: WrappedNode): WrappedNode; (node: BaseNode): BaseNode; } +>node : BaseNode + + while (isWrappedNode(node)) { +>isWrappedNode(node) : boolean +>isWrappedNode : (node: BaseNode) => node is WrappedNode +>node : BaseNode + + node = node.expression; +>node = node.expression : BaseNode +>node : BaseNode +>node.expression : BaseNode +>node : WrappedNode +>expression : BaseNode + } + return node; +>node : BaseNode +} + +interface NamedNode extends BaseNode { + name: string; +>name : string +} + +declare function isSpecialNode(node: BaseNode): node is WrappedNode | NamedNode; +>isSpecialNode : (node: BaseNode) => node is WrappedNode | NamedNode +>node : BaseNode + +function skipSpecialNodes(node: WrappedNode): WrappedNode; +>skipSpecialNodes : { (node: WrappedNode): WrappedNode; (node: BaseNode): BaseNode; } +>node : WrappedNode + +function skipSpecialNodes(node: BaseNode): BaseNode; +>skipSpecialNodes : { (node: WrappedNode): WrappedNode; (node: BaseNode): BaseNode; } +>node : BaseNode + +function skipSpecialNodes(node: BaseNode) { +>skipSpecialNodes : { (node: WrappedNode): WrappedNode; (node: BaseNode): BaseNode; } +>node : BaseNode + + while (isSpecialNode(node)) { +>isSpecialNode(node) : boolean +>isSpecialNode : (node: BaseNode) => node is WrappedNode | NamedNode +>node : BaseNode + + node = { kind: 0 }; +>node = { kind: 0 } : { kind: number; } +>node : BaseNode +>{ kind: 0 } : { kind: number; } +>kind : number +>0 : 0 + } + return node; +>node : BaseNode +} + +function isOrdinaryNode(node: BaseNode) { +>isOrdinaryNode : (node: BaseNode) => boolean +>node : BaseNode + + return !isSpecialNode(node); +>!isSpecialNode(node) : boolean +>isSpecialNode(node) : boolean +>isSpecialNode : (node: BaseNode) => node is WrappedNode | NamedNode +>node : BaseNode +} + +declare const candidate: BaseNode; +>candidate : BaseNode + +if (!isOrdinaryNode(candidate)) { +>!isOrdinaryNode(candidate) : boolean +>isOrdinaryNode(candidate) : boolean +>isOrdinaryNode : (node: BaseNode) => boolean +>candidate : BaseNode + + candidate.kind; +>candidate.kind : number +>candidate : BaseNode +>kind : number +} + +function assertString(value: {}) { +>assertString : (value: {}) => string +>value : {} + + if (typeof value !== "string") { +>typeof value !== "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : {} +>"string" : "string" + + return value as string; +>value as string : string +>value : {} & not string + } + return value; +>value : string +} + +declare const explicitlyNotString: {} & not string; +>explicitlyNotString : {} & not string + +explicitlyNotString as string; +>explicitlyNotString as string : string +>explicitlyNotString : {} & not string + +function skipStrings(value: string): string; +>skipStrings : { (value: string): string; (value: {}): {}; } +>value : string + +function skipStrings(value: {}): {}; +>skipStrings : { (value: string): string; (value: {}): {}; } +>value : {} + +function skipStrings(value: {}) { +>skipStrings : { (value: string): string; (value: {}): {}; } +>value : {} + + while (typeof value === "string") { +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : {} +>"string" : "string" + + value = {}; +>value = {} : {} +>value : {} +>{} : {} + } + return value; +>value : {} & not string +} + +function isNotString(value: {}) { +>isNotString : (value: {}) => boolean +>value : {} + + return typeof value !== "string"; +>typeof value !== "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : {} +>"string" : "string" +} + +declare const nonNullValue: {}; +>nonNullValue : {} + +if (!isNotString(nonNullValue)) { +>!isNotString(nonNullValue) : boolean +>isNotString(nonNullValue) : boolean +>isNotString : (value: {}) => boolean +>nonNullValue : {} + + nonNullValue.toString(); +>nonNullValue.toString() : string +>nonNullValue.toString : () => string +>nonNullValue : {} +>toString : () => string +} diff --git a/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.errors.txt b/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.errors.txt new file mode 100644 index 0000000000000..b18e0c8a3ad74 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.errors.txt @@ -0,0 +1,41 @@ +functionIntersectionUnionCalls.ts(9,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +functionIntersectionUnionCalls.ts(12,14): error TS2345: Argument of type '1' is not assignable to parameter of type 'never'. +functionIntersectionUnionCalls.ts(15,1): error TS2349: This expression is not callable. + Not all constituents of type '{ tag: string; } | (() => void)' are callable. + Type '{ tag: string; }' has no call signatures. +functionIntersectionUnionCalls.ts(18,1): error TS2349: This expression is not callable. + Not all constituents of type '(() => void) | (Function & (new () => object))' are callable. + Type 'Function & (new () => object)' has no call signatures. + + +==== functionIntersectionUnionCalls.ts (4 errors) ==== + declare const untyped: (Function & { tag: string }) | (() => string); + const result = untyped(); + + declare const primitive: (string & Function) | (() => string); + const primitiveResult = primitive(); + + declare const typed: (Function & ((value: number) => number)) | ((value: number) => string); + const typedResult: number | string = typed(1); + typed("wrong"); + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + + declare const incompatible: ((value: number) => void) | ((value: string) => void); + incompatible(1); + ~ +!!! error TS2345: Argument of type '1' is not assignable to parameter of type 'never'. + + declare const nonCallable: { tag: string } | (() => void); + nonCallable(); + ~~~~~~~~~~~ +!!! error TS2349: This expression is not callable. +!!! error TS2349: Not all constituents of type '{ tag: string; } | (() => void)' are callable. +!!! error TS2349: Type '{ tag: string; }' has no call signatures. + + declare const constructor: (Function & (new () => object)) | (() => void); + constructor(); + ~~~~~~~~~~~ +!!! error TS2349: This expression is not callable. +!!! error TS2349: Not all constituents of type '(() => void) | (Function & (new () => object))' are callable. +!!! error TS2349: Type 'Function & (new () => object)' has no call signatures. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.symbols b/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.symbols new file mode 100644 index 0000000000000..ba1c03d0ce374 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.symbols @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/functionIntersectionUnionCalls.ts] //// + +=== functionIntersectionUnionCalls.ts === +declare const untyped: (Function & { tag: string }) | (() => string); +>untyped : Symbol(untyped, Decl(functionIntersectionUnionCalls.ts, 0, 13)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>tag : Symbol(tag, Decl(functionIntersectionUnionCalls.ts, 0, 36)) + +const result = untyped(); +>result : Symbol(result, Decl(functionIntersectionUnionCalls.ts, 1, 5)) +>untyped : Symbol(untyped, Decl(functionIntersectionUnionCalls.ts, 0, 13)) + +declare const primitive: (string & Function) | (() => string); +>primitive : Symbol(primitive, Decl(functionIntersectionUnionCalls.ts, 3, 13)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +const primitiveResult = primitive(); +>primitiveResult : Symbol(primitiveResult, Decl(functionIntersectionUnionCalls.ts, 4, 5)) +>primitive : Symbol(primitive, Decl(functionIntersectionUnionCalls.ts, 3, 13)) + +declare const typed: (Function & ((value: number) => number)) | ((value: number) => string); +>typed : Symbol(typed, Decl(functionIntersectionUnionCalls.ts, 6, 13)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(functionIntersectionUnionCalls.ts, 6, 35)) +>value : Symbol(value, Decl(functionIntersectionUnionCalls.ts, 6, 66)) + +const typedResult: number | string = typed(1); +>typedResult : Symbol(typedResult, Decl(functionIntersectionUnionCalls.ts, 7, 5)) +>typed : Symbol(typed, Decl(functionIntersectionUnionCalls.ts, 6, 13)) + +typed("wrong"); +>typed : Symbol(typed, Decl(functionIntersectionUnionCalls.ts, 6, 13)) + +declare const incompatible: ((value: number) => void) | ((value: string) => void); +>incompatible : Symbol(incompatible, Decl(functionIntersectionUnionCalls.ts, 10, 13)) +>value : Symbol(value, Decl(functionIntersectionUnionCalls.ts, 10, 30)) +>value : Symbol(value, Decl(functionIntersectionUnionCalls.ts, 10, 58)) + +incompatible(1); +>incompatible : Symbol(incompatible, Decl(functionIntersectionUnionCalls.ts, 10, 13)) + +declare const nonCallable: { tag: string } | (() => void); +>nonCallable : Symbol(nonCallable, Decl(functionIntersectionUnionCalls.ts, 13, 13)) +>tag : Symbol(tag, Decl(functionIntersectionUnionCalls.ts, 13, 28)) + +nonCallable(); +>nonCallable : Symbol(nonCallable, Decl(functionIntersectionUnionCalls.ts, 13, 13)) + +declare const constructor: (Function & (new () => object)) | (() => void); +>constructor : Symbol(constructor, Decl(functionIntersectionUnionCalls.ts, 16, 13)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +constructor(); +>constructor : Symbol(constructor, Decl(functionIntersectionUnionCalls.ts, 16, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.types b/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.types new file mode 100644 index 0000000000000..8f2c522081aa7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/functionIntersectionUnionCalls.types @@ -0,0 +1,61 @@ +//// [tests/cases/compiler/functionIntersectionUnionCalls.ts] //// + +=== functionIntersectionUnionCalls.ts === +declare const untyped: (Function & { tag: string }) | (() => string); +>untyped : (() => string) | (Function & { tag: string; }) +>tag : string + +const result = untyped(); +>result : any +>untyped() : any +>untyped : (() => string) | (Function & { tag: string; }) + +declare const primitive: (string & Function) | (() => string); +>primitive : (() => string) | (string & Function) + +const primitiveResult = primitive(); +>primitiveResult : any +>primitive() : any +>primitive : (() => string) | (string & Function) + +declare const typed: (Function & ((value: number) => number)) | ((value: number) => string); +>typed : ((value: number) => string) | (Function & ((value: number) => number)) +>value : number +>value : number + +const typedResult: number | string = typed(1); +>typedResult : string | number +>typed(1) : string | number +>typed : ((value: number) => string) | (Function & ((value: number) => number)) +>1 : 1 + +typed("wrong"); +>typed("wrong") : string | number +>typed : ((value: number) => string) | (Function & ((value: number) => number)) +>"wrong" : "wrong" + +declare const incompatible: ((value: number) => void) | ((value: string) => void); +>incompatible : ((value: number) => void) | ((value: string) => void) +>value : number +>value : string + +incompatible(1); +>incompatible(1) : void +>incompatible : ((value: number) => void) | ((value: string) => void) +>1 : 1 + +declare const nonCallable: { tag: string } | (() => void); +>nonCallable : { tag: string; } | (() => void) +>tag : string + +nonCallable(); +>nonCallable() : any +>nonCallable : { tag: string; } | (() => void) + +declare const constructor: (Function & (new () => object)) | (() => void); +>constructor : (() => void) | (Function & (new () => object)) + +constructor(); +>constructor() : any +>constructor : (() => void) | (Function & (new () => object)) + diff --git a/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types index d057373eefd39..b8ba976edc120 100644 --- a/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types +++ b/tsc/testdata/baselines/reference/compiler/genericCallInNegativeTypeofBranch.types @@ -18,6 +18,6 @@ function normalize(value: unknown) { >value : string >identity(value) : unknown >identity : (value: T) => T ->value : unknown +>value : not string } diff --git a/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.errors.txt b/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.errors.txt index f627cfba48352..0ad57d3251d2e 100644 --- a/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.errors.txt @@ -12,7 +12,7 @@ inDoesNotOperateOnPrimitiveTypes.ts(27,12): error TS2322: Type 'T | U' is not as Type 'string' is not assignable to type 'object'. inDoesNotOperateOnPrimitiveTypes.ts(34,12): error TS2322: Type 'string | number | T' is not assignable to type 'object'. Type 'string' is not assignable to type 'object'. -inDoesNotOperateOnPrimitiveTypes.ts(36,14): error TS2322: Type 'T' is not assignable to type 'object'. +inDoesNotOperateOnPrimitiveTypes.ts(36,14): error TS2322: Type 'T & not string & not number' is not assignable to type 'object'. inDoesNotOperateOnPrimitiveTypes.ts(41,12): error TS2322: Type 'T' is not assignable to type 'object'. Type '"hello" | object' is not assignable to type 'object'. Type 'string' is not assignable to type 'object'. @@ -83,7 +83,7 @@ inDoesNotOperateOnPrimitiveTypes.ts(64,12): error TS2322: Type 'T & (0 | 1 | 2)' if (typeof thing !== "string" && typeof thing !== "number") { "key" in thing; // Ok (because further narrowing is impossible) ~~~~~ -!!! error TS2322: Type 'T' is not assignable to type 'object'. +!!! error TS2322: Type 'T & not string & not number' is not assignable to type 'object'. !!! related TS2208 inDoesNotOperateOnPrimitiveTypes.ts:33:17: This type parameter might need an `extends object` constraint. } } diff --git a/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.types b/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.types index a5f65767dd8da..6e5c1a4765503 100644 --- a/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.types +++ b/tsc/testdata/baselines/reference/compiler/inDoesNotOperateOnPrimitiveTypes.types @@ -102,13 +102,13 @@ function union3(thing: T | string | number) { >"string" : "string" >typeof thing !== "number" : boolean >typeof thing : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" ->thing : number | T +>thing : number | (T & not string) >"number" : "number" "key" in thing; // Ok (because further narrowing is impossible) >"key" in thing : boolean >"key" : "key" ->thing : T +>thing : T & not string & not number } } diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.js b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.js new file mode 100644 index 0000000000000..bd0ec8a4a61fd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.js @@ -0,0 +1,188 @@ +//// [tests/cases/compiler/indexMappedTypeWithFilteredKeysWithNegation.ts] //// + +//// [indexMappedTypeWithFilteredKeysWithNegation.ts] +// homomorphic - mapped type causes `keyof ExcludeKey` to not simplify, relater operates with full mapped type awareness +type ExcludeKey = { + [K in keyof T as K extends TKey ? never : K]: T[K] +}; + +interface Test { + a: string; + b: number; + c: boolean; +} + +declare const test: ExcludeKey; +declare var possibleKey: string & keyof Test & not "b"; + +test[possibleKey]; + +function f(test: ExcludeKey, possibleKey: string & keyof T & not "b") { + test[possibleKey]; +} + +// non-homomorphic - mapped type declared with `keyof T & string` causes `keyof PathTuples` to simplify to `(keyof T & string) extends '_key' ? never : (keyof T & string)` +// relater must operate without mapped type awareness +// ultimate comparison is `keyof T & string & not '_key'` to `(keyof T & string) extends '_key' ? never : (keyof T & string)` +type LocalExclude = T & not U; +type ChildPaths = [PathTuples] extends [never] ? [] : PathTuples; +type PathTuples = T extends object + ? { + [K in keyof T & string as K extends '_key' ? never : K]: [PathTuples] extends [never] + ? never + : readonly [K, ...ChildPaths]; + }[LocalExclude] + : []; + +type T1 = PathTuples<{ a: string; _key: string; b: { c: number } }>; +const t1: T1 = ['b', 'c']; + +type S1 = { [K in keyof T & string as K extends '_key' ? never : K]: 1 }[LocalExclude]; +type S2 = { [K in string & keyof T as K extends '_key' ? never : K]: 1 }[LocalExclude]; + +type ConditionalExclude = T extends U ? never : T; + +function exclude(value: T & not U): ConditionalExclude { + return value; +} + +type Identity = T; +type AliasedExclude = T extends U ? never : Identity; + +function aliasedExclude(value: T & not U): AliasedExclude { + return value; +} + +function mappedExclude(value: keyof T & not U): keyof ExcludeKey { + return value; +} + +type AliasedExcludeKey = { + [K in keyof T as ConditionalExclude]: T[K] +}; + +function aliasedMappedExclude(value: keyof T & not U): keyof AliasedExcludeKey { + return value; +} + +type Prefixed = T extends "skip" ? never : `prefix${T}`; + +function prefixed(value: `prefix${T & not "skip"}`): Prefixed { + return value; +} + +type WithSuffix = T extends "skip" ? never : `prefix${T}:${S}`; + +function withSuffix(value: `prefix${T & not "skip"}:${S}`): WithSuffix { + return value; +} + +type Cased = Uppercase<`prefix${Lowercase}`>; +type FilteredCased = T extends "skip" ? never : Cased; + +function cased(value: Cased): FilteredCased { + return value; +} + +type Alternatives = T extends "skip" ? never : `left${T}` | `right${Uppercase}`; + +function alternatives( + value: `left${T & not "skip"}` | `right${Uppercase}` +): Alternatives { + return value; +} + +type Branded = T extends "skip" ? never : T & { brand: true }; + +function branded(value: T & not "skip" & { brand: true }): Branded { + return value; +} + +interface Values { + a: 1; + b: 2; + skip: 3; +} + +type Lookup = T extends "skip" ? never : Values[T]; + +function lookup(value: Values[T & not "skip"]): Lookup { + return value; +} + +type PrefixedKeys = { + [K in keyof T & string as K extends "_key" ? never : `prefix${K}`]: T[K] +}; + +function prefixedKey(value: `prefix${keyof T & string & not "_key"}`): keyof PrefixedKeys { + return value; +} + +type FunctionResult = T extends string ? never : () => T; + +function falseFunction(value: () => [T]): FunctionResult<[T]> { + return value; +} + +type TupleResult = T extends string ? never : [T, T]; + +function falseTuple(value: [[T], [T]]): TupleResult<[T]> { + return value; +} + +type Nested = T extends "skip" ? never : ConditionalExclude<`prefix${T}`, "prefixomit">; + +function nested(value: ConditionalExclude<`prefix${T & not "skip"}`, "prefixomit">): Nested { + return value; +} + + +//// [indexMappedTypeWithFilteredKeysWithNegation.js] +"use strict"; +test[possibleKey]; +function f(test, possibleKey) { + test[possibleKey]; +} +const t1 = ['b', 'c']; +function exclude(value) { + return value; +} +function aliasedExclude(value) { + return value; +} +function mappedExclude(value) { + return value; +} +function aliasedMappedExclude(value) { + return value; +} +function prefixed(value) { + return value; +} +function withSuffix(value) { + return value; +} +function cased(value) { + return value; +} +function alternatives(value) { + return value; +} +function branded(value) { + return value; +} +function lookup(value) { + return value; +} +function prefixedKey(value) { + return value; +} +function falseFunction(value) { + return value; +} +function falseTuple(value) { + return value; +} +function nested(value) { + return value; +} diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.symbols b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.symbols new file mode 100644 index 0000000000000..5a5380e57106b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.symbols @@ -0,0 +1,470 @@ +//// [tests/cases/compiler/indexMappedTypeWithFilteredKeysWithNegation.ts] //// + +=== indexMappedTypeWithFilteredKeysWithNegation.ts === +// homomorphic - mapped type causes `keyof ExcludeKey` to not simplify, relater operates with full mapped type awareness +type ExcludeKey = { +>ExcludeKey : Symbol(ExcludeKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 0, 0)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 1, 16)) +>TKey : Symbol(TKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 1, 18)) + + [K in keyof T as K extends TKey ? never : K]: T[K] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 2, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 1, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 2, 5)) +>TKey : Symbol(TKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 1, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 2, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 1, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 2, 5)) + +}; + +interface Test { +>Test : Symbol(Test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 3, 2)) + + a: string; +>a : Symbol(Test.a, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 5, 16)) + + b: number; +>b : Symbol(Test.b, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 6, 14)) + + c: boolean; +>c : Symbol(Test.c, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 7, 14)) +} + +declare const test: ExcludeKey; +>test : Symbol(test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 11, 13)) +>ExcludeKey : Symbol(ExcludeKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 0, 0)) +>Test : Symbol(Test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 3, 2)) + +declare var possibleKey: string & keyof Test & not "b"; +>possibleKey : Symbol(possibleKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 12, 11)) +>Test : Symbol(Test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 3, 2)) + +test[possibleKey]; +>test : Symbol(test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 11, 13)) +>possibleKey : Symbol(possibleKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 12, 11)) + +function f(test: ExcludeKey, possibleKey: string & keyof T & not "b") { +>f : Symbol(f, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 14, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 11)) +>Test : Symbol(Test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 3, 2)) +>test : Symbol(test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 27)) +>ExcludeKey : Symbol(ExcludeKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 0, 0)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 11)) +>possibleKey : Symbol(possibleKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 52)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 11)) + + test[possibleKey]; +>test : Symbol(test, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 27)) +>possibleKey : Symbol(possibleKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 16, 52)) +} + +// non-homomorphic - mapped type declared with `keyof T & string` causes `keyof PathTuples` to simplify to `(keyof T & string) extends '_key' ? never : (keyof T & string)` +// relater must operate without mapped type awareness +// ultimate comparison is `keyof T & string & not '_key'` to `(keyof T & string) extends '_key' ? never : (keyof T & string)` +type LocalExclude = T & not U; +>LocalExclude : Symbol(LocalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 18, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 23, 18)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 23, 20)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 23, 18)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 23, 20)) + +type ChildPaths = [PathTuples] extends [never] ? [] : PathTuples; +>ChildPaths : Symbol(ChildPaths, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 23, 36)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 16)) +>PathTuples : Symbol(PathTuples, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 74)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 16)) +>PathTuples : Symbol(PathTuples, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 74)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 16)) + +type PathTuples = T extends object +>PathTuples : Symbol(PathTuples, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 74)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 25, 16)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 25, 16)) + + ? { + [K in keyof T & string as K extends '_key' ? never : K]: [PathTuples] extends [never] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 27, 7)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 25, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 27, 7)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 27, 7)) +>PathTuples : Symbol(PathTuples, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 74)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 25, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 27, 7)) + + ? never + : readonly [K, ...ChildPaths]; +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 27, 7)) +>ChildPaths : Symbol(ChildPaths, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 23, 36)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 25, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 27, 7)) + + }[LocalExclude] +>LocalExclude : Symbol(LocalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 18, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 25, 16)) + + : []; + +type T1 = PathTuples<{ a: string; _key: string; b: { c: number } }>; +>T1 : Symbol(T1, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 31, 7)) +>PathTuples : Symbol(PathTuples, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 24, 74)) +>a : Symbol(a, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 33, 22)) +>_key : Symbol(_key, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 33, 33)) +>b : Symbol(b, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 33, 47)) +>c : Symbol(c, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 33, 52)) + +const t1: T1 = ['b', 'c']; +>t1 : Symbol(t1, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 34, 5)) +>T1 : Symbol(T1, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 31, 7)) + +type S1 = { [K in keyof T & string as K extends '_key' ? never : K]: 1 }[LocalExclude]; +>S1 : Symbol(S1, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 34, 26)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 8)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 16)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 8)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 16)) +>LocalExclude : Symbol(LocalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 18, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 8)) + +type S2 = { [K in string & keyof T as K extends '_key' ? never : K]: 1 }[LocalExclude]; +>S2 : Symbol(S2, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 36, 116)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 8)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 16)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 8)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 16)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 16)) +>LocalExclude : Symbol(LocalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 18, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 8)) + +type ConditionalExclude = T extends U ? never : T; +>ConditionalExclude : Symbol(ConditionalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 116)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 39, 24)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 39, 26)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 39, 24)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 39, 26)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 39, 24)) + +function exclude(value: T & not U): ConditionalExclude { +>exclude : Symbol(exclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 39, 56)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 17)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 19)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 23)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 17)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 19)) +>ConditionalExclude : Symbol(ConditionalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 116)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 17)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 19)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 41, 23)) +} + +type Identity = T; +>Identity : Symbol(Identity, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 43, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 45, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 45, 14)) + +type AliasedExclude = T extends U ? never : Identity; +>AliasedExclude : Symbol(AliasedExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 45, 21)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 46, 20)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 46, 22)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 46, 20)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 46, 22)) +>Identity : Symbol(Identity, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 43, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 46, 20)) + +function aliasedExclude(value: T & not U): AliasedExclude { +>aliasedExclude : Symbol(aliasedExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 46, 62)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 24)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 26)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 30)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 24)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 26)) +>AliasedExclude : Symbol(AliasedExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 45, 21)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 24)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 26)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 48, 30)) +} + +function mappedExclude(value: keyof T & not U): keyof ExcludeKey { +>mappedExclude : Symbol(mappedExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 50, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 23)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 25)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 29)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 23)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 25)) +>ExcludeKey : Symbol(ExcludeKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 0, 0)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 23)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 25)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 52, 29)) +} + +type AliasedExcludeKey = { +>AliasedExcludeKey : Symbol(AliasedExcludeKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 54, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 56, 23)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 56, 25)) + + [K in keyof T as ConditionalExclude]: T[K] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 57, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 56, 23)) +>ConditionalExclude : Symbol(ConditionalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 116)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 57, 5)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 56, 25)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 56, 23)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 57, 5)) + +}; + +function aliasedMappedExclude(value: keyof T & not U): keyof AliasedExcludeKey { +>aliasedMappedExclude : Symbol(aliasedMappedExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 58, 2)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 30)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 32)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 36)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 30)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 32)) +>AliasedExcludeKey : Symbol(AliasedExcludeKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 54, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 30)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 32)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 60, 36)) +} + +type Prefixed = T extends "skip" ? never : `prefix${T}`; +>Prefixed : Symbol(Prefixed, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 62, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 64, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 64, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 64, 14)) + +function prefixed(value: `prefix${T & not "skip"}`): Prefixed { +>prefixed : Symbol(prefixed, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 64, 74)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 66, 18)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 66, 36)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 66, 18)) +>Prefixed : Symbol(Prefixed, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 62, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 66, 18)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 66, 36)) +} + +type WithSuffix = T extends "skip" ? never : `prefix${T}:${S}`; +>WithSuffix : Symbol(WithSuffix, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 68, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 70, 16)) +>S : Symbol(S, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 70, 33)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 70, 16)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 70, 16)) +>S : Symbol(S, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 70, 33)) + +function withSuffix(value: `prefix${T & not "skip"}:${S}`): WithSuffix { +>withSuffix : Symbol(withSuffix, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 70, 99)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 20)) +>S : Symbol(S, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 37)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 56)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 20)) +>S : Symbol(S, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 37)) +>WithSuffix : Symbol(WithSuffix, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 68, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 20)) +>S : Symbol(S, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 37)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 72, 56)) +} + +type Cased = Uppercase<`prefix${Lowercase}`>; +>Cased : Symbol(Cased, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 74, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 76, 11)) +>Uppercase : Symbol(Uppercase, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 76, 11)) + +type FilteredCased = T extends "skip" ? never : Cased; +>FilteredCased : Symbol(FilteredCased, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 76, 66)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 77, 19)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 77, 19)) +>Cased : Symbol(Cased, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 74, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 77, 19)) + +function cased(value: Cased): FilteredCased { +>cased : Symbol(cased, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 77, 75)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 79, 15)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 79, 33)) +>Cased : Symbol(Cased, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 74, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 79, 15)) +>FilteredCased : Symbol(FilteredCased, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 76, 66)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 79, 15)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 79, 33)) +} + +type Alternatives = T extends "skip" ? never : `left${T}` | `right${Uppercase}`; +>Alternatives : Symbol(Alternatives, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 81, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 83, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 83, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 83, 18)) +>Uppercase : Symbol(Uppercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 83, 18)) + +function alternatives( +>alternatives : Symbol(alternatives, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 83, 101)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 85, 22)) + + value: `left${T & not "skip"}` | `right${Uppercase}` +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 85, 40)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 85, 22)) +>Uppercase : Symbol(Uppercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 85, 22)) + +): Alternatives { +>Alternatives : Symbol(Alternatives, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 81, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 85, 22)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 85, 40)) +} + +type Branded = T extends "skip" ? never : T & { brand: true }; +>Branded : Symbol(Branded, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 89, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 91, 13)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 91, 13)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 91, 13)) +>brand : Symbol(brand, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 91, 50)) + +function branded(value: T & not "skip" & { brand: true }): Branded { +>branded : Symbol(branded, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 91, 65)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 93, 17)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 93, 20)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 93, 17)) +>brand : Symbol(brand, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 93, 45)) +>Branded : Symbol(Branded, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 89, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 93, 17)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 93, 20)) +} + +interface Values { +>Values : Symbol(Values, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 95, 1)) + + a: 1; +>a : Symbol(Values.a, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 97, 18)) + + b: 2; +>b : Symbol(Values.b, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 98, 9)) + + skip: 3; +>skip : Symbol(Values.skip, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 99, 9)) +} + +type Lookup = T extends "skip" ? never : Values[T]; +>Lookup : Symbol(Lookup, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 101, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 103, 12)) +>Values : Symbol(Values, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 95, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 103, 12)) +>Values : Symbol(Values, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 95, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 103, 12)) + +function lookup(value: Values[T & not "skip"]): Lookup { +>lookup : Symbol(lookup, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 103, 75)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 105, 16)) +>Values : Symbol(Values, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 95, 1)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 105, 40)) +>Values : Symbol(Values, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 95, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 105, 16)) +>Lookup : Symbol(Lookup, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 101, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 105, 16)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 105, 40)) +} + +type PrefixedKeys = { +>PrefixedKeys : Symbol(PrefixedKeys, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 107, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 109, 18)) + + [K in keyof T & string as K extends "_key" ? never : `prefix${K}`]: T[K] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 110, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 109, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 110, 5)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 110, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 109, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 110, 5)) + +}; + +function prefixedKey(value: `prefix${keyof T & string & not "_key"}`): keyof PrefixedKeys { +>prefixedKey : Symbol(prefixedKey, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 111, 2)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 113, 21)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 113, 24)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 113, 21)) +>PrefixedKeys : Symbol(PrefixedKeys, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 107, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 113, 21)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 113, 24)) +} + +type FunctionResult = T extends string ? never : () => T; +>FunctionResult : Symbol(FunctionResult, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 115, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 117, 20)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 117, 20)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 117, 20)) + +function falseFunction(value: () => [T]): FunctionResult<[T]> { +>falseFunction : Symbol(falseFunction, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 117, 60)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 119, 23)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 119, 26)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 119, 23)) +>FunctionResult : Symbol(FunctionResult, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 115, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 119, 23)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 119, 26)) +} + +type TupleResult = T extends string ? never : [T, T]; +>TupleResult : Symbol(TupleResult, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 121, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 123, 17)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 123, 17)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 123, 17)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 123, 17)) + +function falseTuple(value: [[T], [T]]): TupleResult<[T]> { +>falseTuple : Symbol(falseTuple, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 123, 56)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 125, 20)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 125, 23)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 125, 20)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 125, 20)) +>TupleResult : Symbol(TupleResult, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 121, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 125, 20)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 125, 23)) +} + +type Nested = T extends "skip" ? never : ConditionalExclude<`prefix${T}`, "prefixomit">; +>Nested : Symbol(Nested, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 127, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 129, 12)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 129, 12)) +>ConditionalExclude : Symbol(ConditionalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 116)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 129, 12)) + +function nested(value: ConditionalExclude<`prefix${T & not "skip"}`, "prefixomit">): Nested { +>nested : Symbol(nested, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 129, 106)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 131, 16)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 131, 34)) +>ConditionalExclude : Symbol(ConditionalExclude, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 37, 116)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 131, 16)) +>Nested : Symbol(Nested, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 127, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 131, 16)) + + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegation.ts, 131, 34)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.types b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.types new file mode 100644 index 0000000000000..414a259a75d3f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegation.types @@ -0,0 +1,262 @@ +//// [tests/cases/compiler/indexMappedTypeWithFilteredKeysWithNegation.ts] //// + +=== indexMappedTypeWithFilteredKeysWithNegation.ts === +// homomorphic - mapped type causes `keyof ExcludeKey` to not simplify, relater operates with full mapped type awareness +type ExcludeKey = { +>ExcludeKey : ExcludeKey + + [K in keyof T as K extends TKey ? never : K]: T[K] +}; + +interface Test { + a: string; +>a : string + + b: number; +>b : number + + c: boolean; +>c : boolean +} + +declare const test: ExcludeKey; +>test : ExcludeKey + +declare var possibleKey: string & keyof Test & not "b"; +>possibleKey : "a" | "c" + +test[possibleKey]; +>test[possibleKey] : string | boolean +>test : ExcludeKey +>possibleKey : "a" | "c" + +function f(test: ExcludeKey, possibleKey: string & keyof T & not "b") { +>f : (test: ExcludeKey, possibleKey: string & keyof T & not "b") => void +>test : ExcludeKey +>possibleKey : string & keyof T & not "b" + + test[possibleKey]; +>test[possibleKey] : ExcludeKey[string & keyof T & not "b"] +>test : ExcludeKey +>possibleKey : string & keyof T & not "b" +} + +// non-homomorphic - mapped type declared with `keyof T & string` causes `keyof PathTuples` to simplify to `(keyof T & string) extends '_key' ? never : (keyof T & string)` +// relater must operate without mapped type awareness +// ultimate comparison is `keyof T & string & not '_key'` to `(keyof T & string) extends '_key' ? never : (keyof T & string)` +type LocalExclude = T & not U; +>LocalExclude : LocalExclude + +type ChildPaths = [PathTuples] extends [never] ? [] : PathTuples; +>ChildPaths : ChildPaths + +type PathTuples = T extends object +>PathTuples : PathTuples + + ? { + [K in keyof T & string as K extends '_key' ? never : K]: [PathTuples] extends [never] + ? never + : readonly [K, ...ChildPaths]; + }[LocalExclude] + : []; + +type T1 = PathTuples<{ a: string; _key: string; b: { c: number } }>; +>T1 : readonly ["a"] | readonly ["b", "c"] +>a : string +>_key : string +>b : { c: number; } +>c : number + +const t1: T1 = ['b', 'c']; +>t1 : readonly ["a"] | readonly ["b", "c"] +>['b', 'c'] : ["b", "c"] +>'b' : "b" +>'c' : "c" + +type S1 = { [K in keyof T & string as K extends '_key' ? never : K]: 1 }[LocalExclude]; +>S1 : S1 + +type S2 = { [K in string & keyof T as K extends '_key' ? never : K]: 1 }[LocalExclude]; +>S2 : S2 + +type ConditionalExclude = T extends U ? never : T; +>ConditionalExclude : ConditionalExclude + +function exclude(value: T & not U): ConditionalExclude { +>exclude : (value: T & not U) => ConditionalExclude +>value : T & not U + + return value; +>value : T & not U +} + +type Identity = T; +>Identity : T + +type AliasedExclude = T extends U ? never : Identity; +>AliasedExclude : AliasedExclude + +function aliasedExclude(value: T & not U): AliasedExclude { +>aliasedExclude : (value: T & not U) => AliasedExclude +>value : T & not U + + return value; +>value : T & not U +} + +function mappedExclude(value: keyof T & not U): keyof ExcludeKey { +>mappedExclude : (value: keyof T & not U) => keyof ExcludeKey +>value : keyof T & not U + + return value; +>value : keyof T & not U +} + +type AliasedExcludeKey = { +>AliasedExcludeKey : AliasedExcludeKey + + [K in keyof T as ConditionalExclude]: T[K] +}; + +function aliasedMappedExclude(value: keyof T & not U): keyof AliasedExcludeKey { +>aliasedMappedExclude : (value: keyof T & not U) => keyof AliasedExcludeKey +>value : keyof T & not U + + return value; +>value : keyof T & not U +} + +type Prefixed = T extends "skip" ? never : `prefix${T}`; +>Prefixed : Prefixed + +function prefixed(value: `prefix${T & not "skip"}`): Prefixed { +>prefixed : (value: `prefix${T & not "skip"}`) => Prefixed +>value : `prefix${T & not "skip"}` + + return value; +>value : `prefix${T & not "skip"}` +} + +type WithSuffix = T extends "skip" ? never : `prefix${T}:${S}`; +>WithSuffix : WithSuffix + +function withSuffix(value: `prefix${T & not "skip"}:${S}`): WithSuffix { +>withSuffix : (value: `prefix${T & not "skip"}:${S}`) => WithSuffix +>value : `prefix${T & not "skip"}:${S}` + + return value; +>value : `prefix${T & not "skip"}:${S}` +} + +type Cased = Uppercase<`prefix${Lowercase}`>; +>Cased : `PREFIX${Uppercase>}` + +type FilteredCased = T extends "skip" ? never : Cased; +>FilteredCased : FilteredCased + +function cased(value: Cased): FilteredCased { +>cased : (value: Cased) => FilteredCased +>value : `PREFIX${Uppercase>}` + + return value; +>value : `PREFIX${Uppercase>}` +} + +type Alternatives = T extends "skip" ? never : `left${T}` | `right${Uppercase}`; +>Alternatives : Alternatives + +function alternatives( +>alternatives : (value: `left${T & not "skip"}` | `right${Uppercase}`) => Alternatives + + value: `left${T & not "skip"}` | `right${Uppercase}` +>value : `left${T & not "skip"}` | `right${Uppercase}` + +): Alternatives { + return value; +>value : `left${T & not "skip"}` | `right${Uppercase}` +} + +type Branded = T extends "skip" ? never : T & { brand: true }; +>Branded : Branded +>brand : true +>true : true + +function branded(value: T & not "skip" & { brand: true }): Branded { +>branded : (value: T & not "skip" & { brand: true; }) => Branded +>value : T & not "skip" & { brand: true; } +>brand : true +>true : true + + return value; +>value : T & not "skip" & { brand: true; } +} + +interface Values { + a: 1; +>a : 1 + + b: 2; +>b : 2 + + skip: 3; +>skip : 3 +} + +type Lookup = T extends "skip" ? never : Values[T]; +>Lookup : Lookup + +function lookup(value: Values[T & not "skip"]): Lookup { +>lookup : (value: Values[T & not "skip"]) => Lookup +>value : Values[T & not "skip"] + + return value; +>value : Values[T & not "skip"] +} + +type PrefixedKeys = { +>PrefixedKeys : PrefixedKeys + + [K in keyof T & string as K extends "_key" ? never : `prefix${K}`]: T[K] +}; + +function prefixedKey(value: `prefix${keyof T & string & not "_key"}`): keyof PrefixedKeys { +>prefixedKey : (value: `prefix${keyof T & string & not "_key"}`) => keyof PrefixedKeys +>value : `prefix${keyof T & string & not "_key"}` + + return value; +>value : `prefix${keyof T & string & not "_key"}` +} + +type FunctionResult = T extends string ? never : () => T; +>FunctionResult : FunctionResult + +function falseFunction(value: () => [T]): FunctionResult<[T]> { +>falseFunction : (value: () => [T]) => FunctionResult<[T]> +>value : () => [T] + + return value; +>value : () => [T] +} + +type TupleResult = T extends string ? never : [T, T]; +>TupleResult : TupleResult + +function falseTuple(value: [[T], [T]]): TupleResult<[T]> { +>falseTuple : (value: [[T], [T]]) => TupleResult<[T]> +>value : [[T], [T]] + + return value; +>value : [[T], [T]] +} + +type Nested = T extends "skip" ? never : ConditionalExclude<`prefix${T}`, "prefixomit">; +>Nested : Nested + +function nested(value: ConditionalExclude<`prefix${T & not "skip"}`, "prefixomit">): Nested { +>nested : (value: ConditionalExclude<`prefix${T & not "skip"}`, "prefixomit">) => Nested +>value : ConditionalExclude<`prefix${T & not "skip"}`, "prefixomit"> + + return value; +>value : ConditionalExclude<`prefix${T & not "skip"}`, "prefixomit"> +} + diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.errors.txt b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.errors.txt new file mode 100644 index 0000000000000..252365eef68ba --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.errors.txt @@ -0,0 +1,148 @@ +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(5,5): error TS2322: Type '() => never' is not assignable to type 'FilteredFunction'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(14,5): error TS2322: Type '[T & not false & not true, T & not false & not true]' is not assignable to type 'FilteredPair'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(24,5): error TS2322: Type 'T & not Omitted' is not assignable to type 'DependentFilter'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(33,5): error TS2322: Type 'T' is not assignable to type 'Filter'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(42,5): error TS2322: Type 'keyof T & not "c"' is not assignable to type 'keyof FilteredKeys'. + Type 'keyof T & not "c"' is not assignable to type 'K extends "b" ? never : K'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(47,5): error TS2322: Type 'string & not "b"' is not assignable to type 'keyof FilteredKeys'. + Type 'string & not "b"' is not assignable to type 'K extends "b" ? never : K'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(58,5): error TS2322: Type 'keyof T & not "c"' is not assignable to type 'keyof RemappedKeys'. + Type 'keyof T & not "c"' is not assignable to type '"a" | "b" extends K ? K : never'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(67,5): error TS2322: Type 'keyof T & not Omitted' is not assignable to type 'keyof DependentKeys'. + Type 'keyof T & not Omitted' is not assignable to type 'K extends Omitted ? never : K'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(74,5): error TS2322: Type '`${T & not "skip"}-${T & not "skip"}`' is not assignable to type 'Repeated'. + Type '`${string}-${string}`' is not assignable to type 'Repeated'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(83,5): error TS2322: Type 'T & not string & { value: T & not string; }' is not assignable to type 'Correlated'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(88,5): error TS2322: Type '() => string & { value: T; }' is not assignable to type 'never'. +indexMappedTypeWithFilteredKeysWithNegationErrors.ts(93,5): error TS2322: Type '() => string | [T]' is not assignable to type '() => [T]'. + Type 'string | [T]' is not assignable to type '[T]'. + Type 'string' is not assignable to type '[T]'. + + +==== indexMappedTypeWithFilteredKeysWithNegationErrors.ts (12 errors) ==== + type FilteredFunction = T extends string ? never : () => T; + + function makeFunction(): FilteredFunction { + // When T is string, FilteredFunction is never, but this still returns a function. + return () => { throw new Error(); }; + ~~~~~~ +!!! error TS2322: Type '() => never' is not assignable to type 'FilteredFunction'. + } + + const impossibleFunction: never = makeFunction(); + + type FilteredPair = T extends boolean ? never : [T, T]; + + function makePair(value: [T & not boolean, T & not boolean]): FilteredPair { + // The tuple elements can come from different union members, unlike the distributed FilteredPair. + return value; + ~~~~~~ +!!! error TS2322: Type '[T & not false & not true, T & not false & not true]' is not assignable to type 'FilteredPair'. + } + + const homogeneousPair: [string, string] | [number, number] = makePair(["a", 1]); + + type Omitted = "a" extends T ? never : "b"; + type DependentFilter = T extends Omitted ? never : T; + + function dependentFilter(value: T & not Omitted): DependentFilter { + // For T = "a" | "b", Omitted is never, so value can be "b", but DependentFilter is "a". + return value; + ~~~~~~ +!!! error TS2322: Type 'T & not Omitted' is not assignable to type 'DependentFilter'. + } + + const onlyA: "a" = dependentFilter<"a" | "b">("b"); + + type Filter = T extends U ? never : T; + + function unfiltered(value: T): Filter { + // value can still belong to U, whose members are excluded from Filter. + return value; + ~~~~~~ +!!! error TS2322: Type 'T' is not assignable to type 'Filter'. + } + + type FilteredKeys = { + [K in keyof T as K extends "b" ? never : K]: T[K] + }; + + function excludedKey(value: keyof T & not "c"): keyof FilteredKeys { + // Excluding "c" does not prevent value from being the filtered-out key "b". + return value; + ~~~~~~ +!!! error TS2322: Type 'keyof T & not "c"' is not assignable to type 'keyof FilteredKeys'. +!!! error TS2322: Type 'keyof T & not "c"' is not assignable to type 'K extends "b" ? never : K'. + } + + function unrelatedKey(value: string & not "b"): keyof FilteredKeys { + // value is not constrained to keyof T and may name a property T does not have. + return value; + ~~~~~~ +!!! error TS2322: Type 'string & not "b"' is not assignable to type 'keyof FilteredKeys'. +!!! error TS2322: Type 'string & not "b"' is not assignable to type 'K extends "b" ? never : K'. + } + + type RemappedKeys = { + [K in keyof T as ("a" | "b") extends K ? K : never]: T[K] + }; + + function remappedKey( + value: keyof T & not "c" + ): keyof RemappedKeys { + // For T with just "a" and "b", neither key accepts their union, so no keys survive. + return value; + ~~~~~~ +!!! error TS2322: Type 'keyof T & not "c"' is not assignable to type 'keyof RemappedKeys'. +!!! error TS2322: Type 'keyof T & not "c"' is not assignable to type '"a" | "b" extends K ? K : never'. + } + + type DependentKeys = { + [K in keyof T as K extends Omitted ? never : K]: T[K] + }; + + function dependentKey(value: keyof T & not Omitted): keyof DependentKeys { + // For T = { a: number; b: number }, value can be "b", but only "a" survives the per-key filter. + return value; + ~~~~~~ +!!! error TS2322: Type 'keyof T & not Omitted' is not assignable to type 'keyof DependentKeys'. +!!! error TS2322: Type 'keyof T & not Omitted' is not assignable to type 'K extends Omitted ? never : K'. + } + + type Repeated = T extends "skip" ? never : `${T}-${T}`; + + function repeated(value: `${T & not "skip"}-${T & not "skip"}`): Repeated { + // value can mix different union members in its two T positions, unlike Repeated. + return value; + ~~~~~~ +!!! error TS2322: Type '`${T & not "skip"}-${T & not "skip"}`' is not assignable to type 'Repeated'. +!!! error TS2322: Type '`${string}-${string}`' is not assignable to type 'Repeated'. + } + + const same: "a-a" | "b-b" = repeated<"a" | "b">("a-b"); + + type Correlated = T extends string ? never : T & { value: T }; + + function correlated(value: T & not string & { value: T & not string }): Correlated { + // The outer T and the value property's T can come from different union members, unlike Correlated. + return value; + ~~~~~~ +!!! error TS2322: Type 'T & not string & { value: T & not string; }' is not assignable to type 'Correlated'. + } + + function trueFunction(value: () => (string & { value: T })): FilteredFunction { + // The check type always extends string, so the result is never, not a function. + return value; + ~~~~~~ +!!! error TS2322: Type '() => string & { value: T; }' is not assignable to type 'never'. + } + + function unionFunction(value: () => ([T] | string)): FilteredFunction<[T] | string> { + // The string union member is filtered out, so the returned function must return [T], not string. + return value; + ~~~~~~ +!!! error TS2322: Type '() => string | [T]' is not assignable to type '() => [T]'. +!!! error TS2322: Type 'string | [T]' is not assignable to type '[T]'. +!!! error TS2322: Type 'string' is not assignable to type '[T]'. + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.js b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.js new file mode 100644 index 0000000000000..e0850ce82cc07 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.js @@ -0,0 +1,153 @@ +//// [tests/cases/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.ts] //// + +//// [indexMappedTypeWithFilteredKeysWithNegationErrors.ts] +type FilteredFunction = T extends string ? never : () => T; + +function makeFunction(): FilteredFunction { + // When T is string, FilteredFunction is never, but this still returns a function. + return () => { throw new Error(); }; +} + +const impossibleFunction: never = makeFunction(); + +type FilteredPair = T extends boolean ? never : [T, T]; + +function makePair(value: [T & not boolean, T & not boolean]): FilteredPair { + // The tuple elements can come from different union members, unlike the distributed FilteredPair. + return value; +} + +const homogeneousPair: [string, string] | [number, number] = makePair(["a", 1]); + +type Omitted = "a" extends T ? never : "b"; +type DependentFilter = T extends Omitted ? never : T; + +function dependentFilter(value: T & not Omitted): DependentFilter { + // For T = "a" | "b", Omitted is never, so value can be "b", but DependentFilter is "a". + return value; +} + +const onlyA: "a" = dependentFilter<"a" | "b">("b"); + +type Filter = T extends U ? never : T; + +function unfiltered(value: T): Filter { + // value can still belong to U, whose members are excluded from Filter. + return value; +} + +type FilteredKeys = { + [K in keyof T as K extends "b" ? never : K]: T[K] +}; + +function excludedKey(value: keyof T & not "c"): keyof FilteredKeys { + // Excluding "c" does not prevent value from being the filtered-out key "b". + return value; +} + +function unrelatedKey(value: string & not "b"): keyof FilteredKeys { + // value is not constrained to keyof T and may name a property T does not have. + return value; +} + +type RemappedKeys = { + [K in keyof T as ("a" | "b") extends K ? K : never]: T[K] +}; + +function remappedKey( + value: keyof T & not "c" +): keyof RemappedKeys { + // For T with just "a" and "b", neither key accepts their union, so no keys survive. + return value; +} + +type DependentKeys = { + [K in keyof T as K extends Omitted ? never : K]: T[K] +}; + +function dependentKey(value: keyof T & not Omitted): keyof DependentKeys { + // For T = { a: number; b: number }, value can be "b", but only "a" survives the per-key filter. + return value; +} + +type Repeated = T extends "skip" ? never : `${T}-${T}`; + +function repeated(value: `${T & not "skip"}-${T & not "skip"}`): Repeated { + // value can mix different union members in its two T positions, unlike Repeated. + return value; +} + +const same: "a-a" | "b-b" = repeated<"a" | "b">("a-b"); + +type Correlated = T extends string ? never : T & { value: T }; + +function correlated(value: T & not string & { value: T & not string }): Correlated { + // The outer T and the value property's T can come from different union members, unlike Correlated. + return value; +} + +function trueFunction(value: () => (string & { value: T })): FilteredFunction { + // The check type always extends string, so the result is never, not a function. + return value; +} + +function unionFunction(value: () => ([T] | string)): FilteredFunction<[T] | string> { + // The string union member is filtered out, so the returned function must return [T], not string. + return value; +} + + +//// [indexMappedTypeWithFilteredKeysWithNegationErrors.js] +"use strict"; +function makeFunction() { + // When T is string, FilteredFunction is never, but this still returns a function. + return () => { throw new Error(); }; +} +const impossibleFunction = makeFunction(); +function makePair(value) { + // The tuple elements can come from different union members, unlike the distributed FilteredPair. + return value; +} +const homogeneousPair = makePair(["a", 1]); +function dependentFilter(value) { + // For T = "a" | "b", Omitted is never, so value can be "b", but DependentFilter is "a". + return value; +} +const onlyA = dependentFilter("b"); +function unfiltered(value) { + // value can still belong to U, whose members are excluded from Filter. + return value; +} +function excludedKey(value) { + // Excluding "c" does not prevent value from being the filtered-out key "b". + return value; +} +function unrelatedKey(value) { + // value is not constrained to keyof T and may name a property T does not have. + return value; +} +function remappedKey(value) { + // For T with just "a" and "b", neither key accepts their union, so no keys survive. + return value; +} +function dependentKey(value) { + // For T = { a: number; b: number }, value can be "b", but only "a" survives the per-key filter. + return value; +} +function repeated(value) { + // value can mix different union members in its two T positions, unlike Repeated. + return value; +} +const same = repeated("a-b"); +function correlated(value) { + // The outer T and the value property's T can come from different union members, unlike Correlated. + return value; +} +function trueFunction(value) { + // The check type always extends string, so the result is never, not a function. + return value; +} +function unionFunction(value) { + // The string union member is filtered out, so the returned function must return [T], not string. + return value; +} diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.symbols b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.symbols new file mode 100644 index 0000000000000..8bb86bc8465a2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.symbols @@ -0,0 +1,283 @@ +//// [tests/cases/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.ts] //// + +=== indexMappedTypeWithFilteredKeysWithNegationErrors.ts === +type FilteredFunction = T extends string ? never : () => T; +>FilteredFunction : Symbol(FilteredFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 0)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 22)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 22)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 22)) + +function makeFunction(): FilteredFunction { +>makeFunction : Symbol(makeFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 62)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 2, 22)) +>FilteredFunction : Symbol(FilteredFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 0)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 2, 22)) + + // When T is string, FilteredFunction is never, but this still returns a function. + return () => { throw new Error(); }; +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) +} + +const impossibleFunction: never = makeFunction(); +>impossibleFunction : Symbol(impossibleFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 7, 5)) +>makeFunction : Symbol(makeFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 62)) + +type FilteredPair = T extends boolean ? never : [T, T]; +>FilteredPair : Symbol(FilteredPair, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 7, 57)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 9, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 9, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 9, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 9, 18)) + +function makePair(value: [T & not boolean, T & not boolean]): FilteredPair { +>makePair : Symbol(makePair, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 9, 58)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 11, 18)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 11, 21)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 11, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 11, 18)) +>FilteredPair : Symbol(FilteredPair, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 7, 57)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 11, 18)) + + // The tuple elements can come from different union members, unlike the distributed FilteredPair. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 11, 21)) +} + +const homogeneousPair: [string, string] | [number, number] = makePair(["a", 1]); +>homogeneousPair : Symbol(homogeneousPair, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 16, 5)) +>makePair : Symbol(makePair, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 9, 58)) + +type Omitted = "a" extends T ? never : "b"; +>Omitted : Symbol(Omitted, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 16, 97)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 18, 13)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 18, 13)) + +type DependentFilter = T extends Omitted ? never : T; +>DependentFilter : Symbol(DependentFilter, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 18, 46)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 19, 21)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 19, 21)) +>Omitted : Symbol(Omitted, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 16, 97)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 19, 21)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 19, 21)) + +function dependentFilter(value: T & not Omitted): DependentFilter { +>dependentFilter : Symbol(dependentFilter, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 19, 59)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 21, 25)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 21, 28)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 21, 25)) +>Omitted : Symbol(Omitted, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 16, 97)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 21, 25)) +>DependentFilter : Symbol(DependentFilter, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 18, 46)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 21, 25)) + + // For T = "a" | "b", Omitted is never, so value can be "b", but DependentFilter is "a". + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 21, 28)) +} + +const onlyA: "a" = dependentFilter<"a" | "b">("b"); +>onlyA : Symbol(onlyA, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 26, 5)) +>dependentFilter : Symbol(dependentFilter, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 19, 59)) + +type Filter = T extends U ? never : T; +>Filter : Symbol(Filter, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 26, 51)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 28, 12)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 28, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 28, 12)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 28, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 28, 12)) + +function unfiltered(value: T): Filter { +>unfiltered : Symbol(unfiltered, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 28, 44)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 20)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 22)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 26)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 20)) +>Filter : Symbol(Filter, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 26, 51)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 20)) +>U : Symbol(U, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 22)) + + // value can still belong to U, whose members are excluded from Filter. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 30, 26)) +} + +type FilteredKeys = { +>FilteredKeys : Symbol(FilteredKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 33, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 35, 18)) + + [K in keyof T as K extends "b" ? never : K]: T[K] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 36, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 35, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 36, 5)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 36, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 35, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 36, 5)) + +}; + +function excludedKey(value: keyof T & not "c"): keyof FilteredKeys { +>excludedKey : Symbol(excludedKey, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 37, 2)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 39, 21)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 39, 24)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 39, 21)) +>FilteredKeys : Symbol(FilteredKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 33, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 39, 21)) + + // Excluding "c" does not prevent value from being the filtered-out key "b". + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 39, 24)) +} + +function unrelatedKey(value: string & not "b"): keyof FilteredKeys { +>unrelatedKey : Symbol(unrelatedKey, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 42, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 44, 22)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 44, 25)) +>FilteredKeys : Symbol(FilteredKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 33, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 44, 22)) + + // value is not constrained to keyof T and may name a property T does not have. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 44, 25)) +} + +type RemappedKeys = { +>RemappedKeys : Symbol(RemappedKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 47, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 49, 18)) + + [K in keyof T as ("a" | "b") extends K ? K : never]: T[K] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 50, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 49, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 50, 5)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 50, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 49, 18)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 50, 5)) + +}; + +function remappedKey( +>remappedKey : Symbol(remappedKey, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 51, 2)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 21)) +>a : Symbol(a, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 32)) +>b : Symbol(b, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 44)) + + value: keyof T & not "c" +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 59)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 21)) + +): keyof RemappedKeys { +>RemappedKeys : Symbol(RemappedKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 47, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 21)) + + // For T with just "a" and "b", neither key accepts their union, so no keys survive. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 53, 59)) +} + +type DependentKeys = { +>DependentKeys : Symbol(DependentKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 58, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 60, 19)) + + [K in keyof T as K extends Omitted ? never : K]: T[K] +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 61, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 60, 19)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 61, 5)) +>Omitted : Symbol(Omitted, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 16, 97)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 61, 5)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 61, 5)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 60, 19)) +>K : Symbol(K, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 61, 5)) + +}; + +function dependentKey(value: keyof T & not Omitted): keyof DependentKeys { +>dependentKey : Symbol(dependentKey, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 62, 2)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 64, 22)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 64, 25)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 64, 22)) +>Omitted : Symbol(Omitted, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 16, 97)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 64, 22)) +>DependentKeys : Symbol(DependentKeys, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 58, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 64, 22)) + + // For T = { a: number; b: number }, value can be "b", but only "a" survives the per-key filter. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 64, 25)) +} + +type Repeated = T extends "skip" ? never : `${T}-${T}`; +>Repeated : Symbol(Repeated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 67, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 69, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 69, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 69, 14)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 69, 14)) + +function repeated(value: `${T & not "skip"}-${T & not "skip"}`): Repeated { +>repeated : Symbol(repeated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 69, 73)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 71, 18)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 71, 36)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 71, 18)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 71, 18)) +>Repeated : Symbol(Repeated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 67, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 71, 18)) + + // value can mix different union members in its two T positions, unlike Repeated. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 71, 36)) +} + +const same: "a-a" | "b-b" = repeated<"a" | "b">("a-b"); +>same : Symbol(same, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 76, 5)) +>repeated : Symbol(repeated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 69, 73)) + +type Correlated = T extends string ? never : T & { value: T }; +>Correlated : Symbol(Correlated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 76, 55)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 78, 16)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 78, 16)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 78, 16)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 78, 53)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 78, 16)) + +function correlated(value: T & not string & { value: T & not string }): Correlated { +>correlated : Symbol(correlated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 78, 65)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 20)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 23)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 20)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 48)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 20)) +>Correlated : Symbol(Correlated, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 76, 55)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 20)) + + // The outer T and the value property's T can come from different union members, unlike Correlated. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 80, 23)) +} + +function trueFunction(value: () => (string & { value: T })): FilteredFunction { +>trueFunction : Symbol(trueFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 83, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 22)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 25)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 49)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 22)) +>FilteredFunction : Symbol(FilteredFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 0)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 91)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 22)) + + // The check type always extends string, so the result is never, not a function. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 85, 25)) +} + +function unionFunction(value: () => ([T] | string)): FilteredFunction<[T] | string> { +>unionFunction : Symbol(unionFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 88, 1)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 90, 23)) +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 90, 26)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 90, 23)) +>FilteredFunction : Symbol(FilteredFunction, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 0, 0)) +>T : Symbol(T, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 90, 23)) + + // The string union member is filtered out, so the returned function must return [T], not string. + return value; +>value : Symbol(value, Decl(indexMappedTypeWithFilteredKeysWithNegationErrors.ts, 90, 26)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.types b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.types new file mode 100644 index 0000000000000..8b7fa85b48acd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.types @@ -0,0 +1,185 @@ +//// [tests/cases/compiler/indexMappedTypeWithFilteredKeysWithNegationErrors.ts] //// + +=== indexMappedTypeWithFilteredKeysWithNegationErrors.ts === +type FilteredFunction = T extends string ? never : () => T; +>FilteredFunction : FilteredFunction + +function makeFunction(): FilteredFunction { +>makeFunction : () => FilteredFunction + + // When T is string, FilteredFunction is never, but this still returns a function. + return () => { throw new Error(); }; +>() => { throw new Error(); } : () => never +>new Error() : Error +>Error : ErrorConstructor +} + +const impossibleFunction: never = makeFunction(); +>impossibleFunction : never +>makeFunction() : never +>makeFunction : () => FilteredFunction + +type FilteredPair = T extends boolean ? never : [T, T]; +>FilteredPair : FilteredPair + +function makePair(value: [T & not boolean, T & not boolean]): FilteredPair { +>makePair : (value: [T & not boolean, T & not boolean]) => FilteredPair +>value : [T & not false & not true, T & not false & not true] + + // The tuple elements can come from different union members, unlike the distributed FilteredPair. + return value; +>value : [T & not false & not true, T & not false & not true] +} + +const homogeneousPair: [string, string] | [number, number] = makePair(["a", 1]); +>homogeneousPair : [string, string] | [number, number] +>makePair(["a", 1]) : [string, string] | [number, number] +>makePair : (value: [T & not boolean, T & not boolean]) => FilteredPair +>["a", 1] : [string, number] +>"a" : "a" +>1 : 1 + +type Omitted = "a" extends T ? never : "b"; +>Omitted : Omitted + +type DependentFilter = T extends Omitted ? never : T; +>DependentFilter : DependentFilter + +function dependentFilter(value: T & not Omitted): DependentFilter { +>dependentFilter : (value: T & not Omitted) => DependentFilter +>value : T & not Omitted + + // For T = "a" | "b", Omitted is never, so value can be "b", but DependentFilter is "a". + return value; +>value : T & not Omitted +} + +const onlyA: "a" = dependentFilter<"a" | "b">("b"); +>onlyA : "a" +>dependentFilter<"a" | "b">("b") : "a" +>dependentFilter : (value: T & not Omitted) => DependentFilter +>"b" : "b" + +type Filter = T extends U ? never : T; +>Filter : Filter + +function unfiltered(value: T): Filter { +>unfiltered : (value: T) => Filter +>value : T + + // value can still belong to U, whose members are excluded from Filter. + return value; +>value : T +} + +type FilteredKeys = { +>FilteredKeys : FilteredKeys + + [K in keyof T as K extends "b" ? never : K]: T[K] +}; + +function excludedKey(value: keyof T & not "c"): keyof FilteredKeys { +>excludedKey : (value: keyof T & not "c") => keyof FilteredKeys +>value : keyof T & not "c" + + // Excluding "c" does not prevent value from being the filtered-out key "b". + return value; +>value : keyof T & not "c" +} + +function unrelatedKey(value: string & not "b"): keyof FilteredKeys { +>unrelatedKey : (value: string & not "b") => keyof FilteredKeys +>value : string & not "b" + + // value is not constrained to keyof T and may name a property T does not have. + return value; +>value : string & not "b" +} + +type RemappedKeys = { +>RemappedKeys : RemappedKeys + + [K in keyof T as ("a" | "b") extends K ? K : never]: T[K] +}; + +function remappedKey( +>remappedKey : (value: keyof T & not "c") => keyof RemappedKeys +>a : unknown +>b : unknown + + value: keyof T & not "c" +>value : keyof T & not "c" + +): keyof RemappedKeys { + // For T with just "a" and "b", neither key accepts their union, so no keys survive. + return value; +>value : keyof T & not "c" +} + +type DependentKeys = { +>DependentKeys : DependentKeys + + [K in keyof T as K extends Omitted ? never : K]: T[K] +}; + +function dependentKey(value: keyof T & not Omitted): keyof DependentKeys { +>dependentKey : (value: keyof T & not Omitted) => keyof DependentKeys +>value : keyof T & not Omitted + + // For T = { a: number; b: number }, value can be "b", but only "a" survives the per-key filter. + return value; +>value : keyof T & not Omitted +} + +type Repeated = T extends "skip" ? never : `${T}-${T}`; +>Repeated : Repeated + +function repeated(value: `${T & not "skip"}-${T & not "skip"}`): Repeated { +>repeated : (value: `${T & not "skip"}-${T & not "skip"}`) => Repeated +>value : `${T & not "skip"}-${T & not "skip"}` + + // value can mix different union members in its two T positions, unlike Repeated. + return value; +>value : `${T & not "skip"}-${T & not "skip"}` +} + +const same: "a-a" | "b-b" = repeated<"a" | "b">("a-b"); +>same : "a-a" | "b-b" +>repeated<"a" | "b">("a-b") : "a-a" | "b-b" +>repeated : (value: `${T & not "skip"}-${T & not "skip"}`) => Repeated +>"a-b" : "a-b" + +type Correlated = T extends string ? never : T & { value: T }; +>Correlated : Correlated +>value : T + +function correlated(value: T & not string & { value: T & not string }): Correlated { +>correlated : (value: T & not string & { value: T & not string; }) => Correlated +>value : T & not string & { value: T & not string; } +>value : T & not string + + // The outer T and the value property's T can come from different union members, unlike Correlated. + return value; +>value : T & not string & { value: T & not string; } +} + +function trueFunction(value: () => (string & { value: T })): FilteredFunction { +>trueFunction : (value: () => (string & { value: T; })) => FilteredFunction +>value : () => (string & { value: T; }) +>value : T +>value : T + + // The check type always extends string, so the result is never, not a function. + return value; +>value : () => (string & { value: T; }) +} + +function unionFunction(value: () => ([T] | string)): FilteredFunction<[T] | string> { +>unionFunction : (value: () => ([T] | string)) => FilteredFunction<[T] | string> +>value : () => ([T] | string) + + // The string union member is filtered out, so the returned function must return [T], not string. + return value; +>value : () => ([T] | string) +} + diff --git a/tsc/testdata/baselines/reference/compiler/inferTypePredicates.types b/tsc/testdata/baselines/reference/compiler/inferTypePredicates.types index 0ffd72e1e0215..279daac6d0577 100644 --- a/tsc/testdata/baselines/reference/compiler/inferTypePredicates.types +++ b/tsc/testdata/baselines/reference/compiler/inferTypePredicates.types @@ -875,7 +875,7 @@ function isNumOrStr(x: unknown) { >"number" : "number" >typeof x === "string" : boolean >typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" ->x : unknown +>x : not number >"string" : "string" } declare let unk: unknown; diff --git a/tsc/testdata/baselines/reference/compiler/intersectionAssignmentReduction.symbols b/tsc/testdata/baselines/reference/compiler/intersectionAssignmentReduction.symbols new file mode 100644 index 0000000000000..914ecaba93788 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/intersectionAssignmentReduction.symbols @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/intersectionAssignmentReduction.ts] //// + +=== intersectionAssignmentReduction.ts === +interface ValueNode { kind: "value"; value: number; } +>ValueNode : Symbol(ValueNode, Decl(intersectionAssignmentReduction.ts, 0, 0)) +>kind : Symbol(ValueNode.kind, Decl(intersectionAssignmentReduction.ts, 0, 21)) +>value : Symbol(ValueNode.value, Decl(intersectionAssignmentReduction.ts, 0, 36)) + +interface TextNode { kind: "text"; text: string; } +>TextNode : Symbol(TextNode, Decl(intersectionAssignmentReduction.ts, 0, 53)) +>kind : Symbol(TextNode.kind, Decl(intersectionAssignmentReduction.ts, 1, 20)) +>text : Symbol(TextNode.text, Decl(intersectionAssignmentReduction.ts, 1, 34)) + +interface OmittedNode { kind: "omitted"; } +>OmittedNode : Symbol(OmittedNode, Decl(intersectionAssignmentReduction.ts, 1, 50)) +>kind : Symbol(OmittedNode.kind, Decl(intersectionAssignmentReduction.ts, 2, 23)) + +type AssignmentNode = ValueNode | TextNode | OmittedNode; +>AssignmentNode : Symbol(AssignmentNode, Decl(intersectionAssignmentReduction.ts, 2, 42)) +>ValueNode : Symbol(ValueNode, Decl(intersectionAssignmentReduction.ts, 0, 0)) +>TextNode : Symbol(TextNode, Decl(intersectionAssignmentReduction.ts, 0, 53)) +>OmittedNode : Symbol(OmittedNode, Decl(intersectionAssignmentReduction.ts, 1, 50)) + +declare function updateNode(node: NodeType): AssignmentNode & Pick; +>updateNode : Symbol(updateNode, Decl(intersectionAssignmentReduction.ts, 3, 57)) +>NodeType : Symbol(NodeType, Decl(intersectionAssignmentReduction.ts, 5, 28)) +>AssignmentNode : Symbol(AssignmentNode, Decl(intersectionAssignmentReduction.ts, 2, 42)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 5, 61)) +>NodeType : Symbol(NodeType, Decl(intersectionAssignmentReduction.ts, 5, 28)) +>AssignmentNode : Symbol(AssignmentNode, Decl(intersectionAssignmentReduction.ts, 2, 42)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>NodeType : Symbol(NodeType, Decl(intersectionAssignmentReduction.ts, 5, 28)) + +function updateExcluded(node: AssignmentNode & not OmittedNode) { +>updateExcluded : Symbol(updateExcluded, Decl(intersectionAssignmentReduction.ts, 5, 118)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 7, 24)) +>AssignmentNode : Symbol(AssignmentNode, Decl(intersectionAssignmentReduction.ts, 2, 42)) +>OmittedNode : Symbol(OmittedNode, Decl(intersectionAssignmentReduction.ts, 1, 50)) + + if (node.kind === "value") { +>node.kind : Symbol(kind, Decl(intersectionAssignmentReduction.ts, 1, 20), Decl(intersectionAssignmentReduction.ts, 0, 21)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 7, 24)) +>kind : Symbol(kind, Decl(intersectionAssignmentReduction.ts, 1, 20), Decl(intersectionAssignmentReduction.ts, 0, 21)) + + node = updateNode(node); +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 7, 24)) +>updateNode : Symbol(updateNode, Decl(intersectionAssignmentReduction.ts, 3, 57)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 7, 24)) + + const value: number = node.value; +>value : Symbol(value, Decl(intersectionAssignmentReduction.ts, 10, 13)) +>node.value : Symbol(ValueNode.value, Decl(intersectionAssignmentReduction.ts, 0, 36)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 7, 24)) +>value : Symbol(ValueNode.value, Decl(intersectionAssignmentReduction.ts, 0, 36)) + + const updated: ValueNode = node; +>updated : Symbol(updated, Decl(intersectionAssignmentReduction.ts, 11, 13)) +>ValueNode : Symbol(ValueNode, Decl(intersectionAssignmentReduction.ts, 0, 0)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 7, 24)) + } +} + +function updateUnion(node: AssignmentNode) { +>updateUnion : Symbol(updateUnion, Decl(intersectionAssignmentReduction.ts, 13, 1)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 15, 21)) +>AssignmentNode : Symbol(AssignmentNode, Decl(intersectionAssignmentReduction.ts, 2, 42)) + + if (node.kind === "value") { +>node.kind : Symbol(kind, Decl(intersectionAssignmentReduction.ts, 2, 23), Decl(intersectionAssignmentReduction.ts, 1, 20), Decl(intersectionAssignmentReduction.ts, 0, 21)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 15, 21)) +>kind : Symbol(kind, Decl(intersectionAssignmentReduction.ts, 2, 23), Decl(intersectionAssignmentReduction.ts, 1, 20), Decl(intersectionAssignmentReduction.ts, 0, 21)) + + node = updateNode(node); +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 15, 21)) +>updateNode : Symbol(updateNode, Decl(intersectionAssignmentReduction.ts, 3, 57)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 15, 21)) + + const value: number = node.value; +>value : Symbol(value, Decl(intersectionAssignmentReduction.ts, 18, 13)) +>node.value : Symbol(ValueNode.value, Decl(intersectionAssignmentReduction.ts, 0, 36)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 15, 21)) +>value : Symbol(ValueNode.value, Decl(intersectionAssignmentReduction.ts, 0, 36)) + + const updated: ValueNode = node; +>updated : Symbol(updated, Decl(intersectionAssignmentReduction.ts, 19, 13)) +>ValueNode : Symbol(ValueNode, Decl(intersectionAssignmentReduction.ts, 0, 0)) +>node : Symbol(node, Decl(intersectionAssignmentReduction.ts, 15, 21)) + } +} diff --git a/tsc/testdata/baselines/reference/compiler/intersectionAssignmentReduction.types b/tsc/testdata/baselines/reference/compiler/intersectionAssignmentReduction.types new file mode 100644 index 0000000000000..3f68e6140c553 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/intersectionAssignmentReduction.types @@ -0,0 +1,80 @@ +//// [tests/cases/compiler/intersectionAssignmentReduction.ts] //// + +=== intersectionAssignmentReduction.ts === +interface ValueNode { kind: "value"; value: number; } +>kind : "value" +>value : number + +interface TextNode { kind: "text"; text: string; } +>kind : "text" +>text : string + +interface OmittedNode { kind: "omitted"; } +>kind : "omitted" + +type AssignmentNode = ValueNode | TextNode | OmittedNode; +>AssignmentNode : AssignmentNode + +declare function updateNode(node: NodeType): AssignmentNode & Pick; +>updateNode : (node: NodeType) => AssignmentNode & Pick +>node : NodeType + +function updateExcluded(node: AssignmentNode & not OmittedNode) { +>updateExcluded : (node: AssignmentNode & not OmittedNode) => void +>node : TextNode | ValueNode + + if (node.kind === "value") { +>node.kind === "value" : boolean +>node.kind : "text" | "value" +>node : TextNode | ValueNode +>kind : "text" | "value" +>"value" : "value" + + node = updateNode(node); +>node = updateNode(node) : ValueNode & Pick +>node : TextNode | ValueNode +>updateNode(node) : ValueNode & Pick +>updateNode : (node: NodeType) => AssignmentNode & Pick +>node : ValueNode + + const value: number = node.value; +>value : number +>node.value : number +>node : ValueNode +>value : number + + const updated: ValueNode = node; +>updated : ValueNode +>node : ValueNode + } +} + +function updateUnion(node: AssignmentNode) { +>updateUnion : (node: AssignmentNode) => void +>node : AssignmentNode + + if (node.kind === "value") { +>node.kind === "value" : boolean +>node.kind : "omitted" | "text" | "value" +>node : AssignmentNode +>kind : "omitted" | "text" | "value" +>"value" : "value" + + node = updateNode(node); +>node = updateNode(node) : ValueNode & Pick +>node : AssignmentNode +>updateNode(node) : ValueNode & Pick +>updateNode : (node: NodeType) => AssignmentNode & Pick +>node : ValueNode + + const value: number = node.value; +>value : number +>node.value : number +>node : ValueNode +>value : number + + const updated: ValueNode = node; +>updated : ValueNode +>node : ValueNode + } +} diff --git a/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types index 4212f993a140d..e525ce85262c5 100644 --- a/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types +++ b/tsc/testdata/baselines/reference/compiler/literalUnionAfterExcludedComparisons.types @@ -15,10 +15,10 @@ function readRuntime(value: string): Runtime { >value : string >"node" : "node" >value !== "deno" : boolean ->value : string +>value : string & not "node" >"deno" : "deno" >value !== "bun" : boolean ->value : string +>value : string & not "node" & not "deno" >"bun" : "bun" throw new Error(); diff --git a/tsc/testdata/baselines/reference/compiler/mappedUnionKeyInference.symbols b/tsc/testdata/baselines/reference/compiler/mappedUnionKeyInference.symbols new file mode 100644 index 0000000000000..742891fb6b2ce --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/mappedUnionKeyInference.symbols @@ -0,0 +1,122 @@ +//// [tests/cases/compiler/mappedUnionKeyInference.ts] //// + +=== mappedUnionKeyInference.ts === +declare function inferMapped(source: { [Key in keyof Value | "fixed"]: Value }): Value; +>inferMapped : Symbol(inferMapped, Decl(mappedUnionKeyInference.ts, 0, 0)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 0, 29)) +>source : Symbol(source, Decl(mappedUnionKeyInference.ts, 0, 36)) +>Key : Symbol(Key, Decl(mappedUnionKeyInference.ts, 0, 47)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 0, 29)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 0, 29)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 0, 29)) + +const mapped = inferMapped({ +>mapped : Symbol(mapped, Decl(mappedUnionKeyInference.ts, 2, 5)) +>inferMapped : Symbol(inferMapped, Decl(mappedUnionKeyInference.ts, 0, 0)) + + fixed: { fixed: 1, other: "text" }, +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 2, 28)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 3, 12)) +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 3, 22)) + + other: { fixed: "text", other: 1 }, +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 3, 39)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 4, 12)) +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 4, 27)) + +}); + +const fixed: unknown = mapped.fixed; +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 7, 5)) +>mapped.fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 2, 28)) +>mapped : Symbol(mapped, Decl(mappedUnionKeyInference.ts, 2, 5)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 2, 28)) + +const other: unknown = mapped.other; +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 8, 5)) +>mapped.other : Symbol(other, Decl(mappedUnionKeyInference.ts, 3, 39)) +>mapped : Symbol(mapped, Decl(mappedUnionKeyInference.ts, 2, 5)) +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 3, 39)) + +declare function inferFixed(source: { +>inferFixed : Symbol(inferFixed, Decl(mappedUnionKeyInference.ts, 8, 36)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 10, 28)) +>Extra : Symbol(Extra, Decl(mappedUnionKeyInference.ts, 10, 34)) +>source : Symbol(source, Decl(mappedUnionKeyInference.ts, 10, 42)) + + [Key in keyof Extra | "fixed"]: Key extends "fixed" ? Value : Extra[Key & keyof Extra]; +>Key : Symbol(Key, Decl(mappedUnionKeyInference.ts, 11, 5)) +>Extra : Symbol(Extra, Decl(mappedUnionKeyInference.ts, 10, 34)) +>Key : Symbol(Key, Decl(mappedUnionKeyInference.ts, 11, 5)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 10, 28)) +>Extra : Symbol(Extra, Decl(mappedUnionKeyInference.ts, 10, 34)) +>Key : Symbol(Key, Decl(mappedUnionKeyInference.ts, 11, 5)) +>Extra : Symbol(Extra, Decl(mappedUnionKeyInference.ts, 10, 34)) + +}): Value; +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 10, 28)) + +const fixedValue = inferFixed({ fixed: { count: 1 }, other: "text" }); +>fixedValue : Symbol(fixedValue, Decl(mappedUnionKeyInference.ts, 14, 5)) +>inferFixed : Symbol(inferFixed, Decl(mappedUnionKeyInference.ts, 8, 36)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 14, 31)) +>count : Symbol(count, Decl(mappedUnionKeyInference.ts, 14, 40)) +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 14, 52)) + +const count: number = fixedValue.count; +>count : Symbol(count, Decl(mappedUnionKeyInference.ts, 15, 5)) +>fixedValue.count : Symbol(count, Decl(mappedUnionKeyInference.ts, 14, 40)) +>fixedValue : Symbol(fixedValue, Decl(mappedUnionKeyInference.ts, 14, 5)) +>count : Symbol(count, Decl(mappedUnionKeyInference.ts, 14, 40)) + +declare function inferWithCallback(source: { +>inferWithCallback : Symbol(inferWithCallback, Decl(mappedUnionKeyInference.ts, 15, 39)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 17, 35)) +>source : Symbol(source, Decl(mappedUnionKeyInference.ts, 17, 42)) + + [Key in keyof Value | "fixed"]: { value: Value; callback?: (value: Value) => void }; +>Key : Symbol(Key, Decl(mappedUnionKeyInference.ts, 18, 5)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 17, 35)) +>value : Symbol(value, Decl(mappedUnionKeyInference.ts, 18, 37)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 17, 35)) +>callback : Symbol(callback, Decl(mappedUnionKeyInference.ts, 18, 51)) +>value : Symbol(value, Decl(mappedUnionKeyInference.ts, 18, 64)) +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 17, 35)) + +}): Value; +>Value : Symbol(Value, Decl(mappedUnionKeyInference.ts, 17, 35)) + +const withCallback = inferWithCallback({ +>withCallback : Symbol(withCallback, Decl(mappedUnionKeyInference.ts, 21, 5)) +>inferWithCallback : Symbol(inferWithCallback, Decl(mappedUnionKeyInference.ts, 15, 39)) + + fixed: { +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 21, 40)) + + value: { fixed: 1, other: "text" }, +>value : Symbol(value, Decl(mappedUnionKeyInference.ts, 22, 12)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 23, 16)) +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 23, 26)) + + callback: value => { const fixed: unknown = value.fixed; }, +>callback : Symbol(callback, Decl(mappedUnionKeyInference.ts, 23, 43)) +>value : Symbol(value, Decl(mappedUnionKeyInference.ts, 24, 17)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 24, 34)) +>value.fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 21, 40)) +>value : Symbol(value, Decl(mappedUnionKeyInference.ts, 24, 17)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 21, 40)) + + }, + other: { value: { fixed: "text", other: 1 } }, +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 25, 6)) +>value : Symbol(value, Decl(mappedUnionKeyInference.ts, 26, 12)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 26, 21)) +>other : Symbol(other, Decl(mappedUnionKeyInference.ts, 26, 36)) + +}); +const callbackFixed: unknown = withCallback.fixed; +>callbackFixed : Symbol(callbackFixed, Decl(mappedUnionKeyInference.ts, 28, 5)) +>withCallback.fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 21, 40)) +>withCallback : Symbol(withCallback, Decl(mappedUnionKeyInference.ts, 21, 5)) +>fixed : Symbol(fixed, Decl(mappedUnionKeyInference.ts, 21, 40)) + diff --git a/tsc/testdata/baselines/reference/compiler/mappedUnionKeyInference.types b/tsc/testdata/baselines/reference/compiler/mappedUnionKeyInference.types new file mode 100644 index 0000000000000..cb05a99adda6b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/mappedUnionKeyInference.types @@ -0,0 +1,124 @@ +//// [tests/cases/compiler/mappedUnionKeyInference.ts] //// + +=== mappedUnionKeyInference.ts === +declare function inferMapped(source: { [Key in keyof Value | "fixed"]: Value }): Value; +>inferMapped : (source: { [Key in keyof Value | "fixed"]: Value; }) => Value +>source : { [Key in "fixed" | keyof Value]: Value; } + +const mapped = inferMapped({ +>mapped : { fixed: unknown; other: unknown; } +>inferMapped({ fixed: { fixed: 1, other: "text" }, other: { fixed: "text", other: 1 },}) : { fixed: unknown; other: unknown; } +>inferMapped : (source: { [Key in keyof Value | "fixed"]: Value; }) => Value +>{ fixed: { fixed: 1, other: "text" }, other: { fixed: "text", other: 1 },} : { fixed: { fixed: number; other: string; }; other: { fixed: string; other: number; }; } + + fixed: { fixed: 1, other: "text" }, +>fixed : { fixed: number; other: string; } +>{ fixed: 1, other: "text" } : { fixed: number; other: string; } +>fixed : number +>1 : 1 +>other : string +>"text" : "text" + + other: { fixed: "text", other: 1 }, +>other : { fixed: string; other: number; } +>{ fixed: "text", other: 1 } : { fixed: string; other: number; } +>fixed : string +>"text" : "text" +>other : number +>1 : 1 + +}); + +const fixed: unknown = mapped.fixed; +>fixed : unknown +>mapped.fixed : unknown +>mapped : { fixed: unknown; other: unknown; } +>fixed : unknown + +const other: unknown = mapped.other; +>other : unknown +>mapped.other : unknown +>mapped : { fixed: unknown; other: unknown; } +>other : unknown + +declare function inferFixed(source: { +>inferFixed : (source: { [Key in keyof Extra | "fixed"]: Key extends "fixed" ? Value : Extra[Key & keyof Extra]; }) => Value +>source : { [Key in "fixed" | keyof Extra]: Key extends "fixed" ? Value : Extra[Key & keyof Extra]; } + + [Key in keyof Extra | "fixed"]: Key extends "fixed" ? Value : Extra[Key & keyof Extra]; +}): Value; + +const fixedValue = inferFixed({ fixed: { count: 1 }, other: "text" }); +>fixedValue : { count: number; } +>inferFixed({ fixed: { count: 1 }, other: "text" }) : { count: number; } +>inferFixed : (source: { [Key in keyof Extra | "fixed"]: Key extends "fixed" ? Value : Extra[Key & keyof Extra]; }) => Value +>{ fixed: { count: 1 }, other: "text" } : { fixed: { count: number; }; other: string; } +>fixed : { count: number; } +>{ count: 1 } : { count: number; } +>count : number +>1 : 1 +>other : string +>"text" : "text" + +const count: number = fixedValue.count; +>count : number +>fixedValue.count : number +>fixedValue : { count: number; } +>count : number + +declare function inferWithCallback(source: { +>inferWithCallback : (source: { [Key in keyof Value | "fixed"]: { value: Value; callback?: (value: Value) => void; }; }) => Value +>source : { [Key in "fixed" | keyof Value]: { value: Value; callback?: (value: Value) => void; }; } + + [Key in keyof Value | "fixed"]: { value: Value; callback?: (value: Value) => void }; +>value : Value +>callback : ((value: Value) => void) | undefined +>value : Value + +}): Value; + +const withCallback = inferWithCallback({ +>withCallback : { fixed: unknown; other: unknown; } +>inferWithCallback({ fixed: { value: { fixed: 1, other: "text" }, callback: value => { const fixed: unknown = value.fixed; }, }, other: { value: { fixed: "text", other: 1 } },}) : { fixed: unknown; other: unknown; } +>inferWithCallback : (source: { [Key in keyof Value | "fixed"]: { value: Value; callback?: (value: Value) => void; }; }) => Value +>{ fixed: { value: { fixed: 1, other: "text" }, callback: value => { const fixed: unknown = value.fixed; }, }, other: { value: { fixed: "text", other: 1 } },} : { fixed: { value: { fixed: number; other: string; }; callback: (value: { fixed: unknown; other: unknown; }) => void; }; other: { value: { fixed: string; other: number; }; }; } + + fixed: { +>fixed : { value: { fixed: number; other: string; }; callback: (value: { fixed: unknown; other: unknown; }) => void; } +>{ value: { fixed: 1, other: "text" }, callback: value => { const fixed: unknown = value.fixed; }, } : { value: { fixed: number; other: string; }; callback: (value: { fixed: unknown; other: unknown; }) => void; } + + value: { fixed: 1, other: "text" }, +>value : { fixed: number; other: string; } +>{ fixed: 1, other: "text" } : { fixed: number; other: string; } +>fixed : number +>1 : 1 +>other : string +>"text" : "text" + + callback: value => { const fixed: unknown = value.fixed; }, +>callback : (value: { fixed: unknown; other: unknown; }) => void +>value => { const fixed: unknown = value.fixed; } : (value: { fixed: unknown; other: unknown; }) => void +>value : { fixed: unknown; other: unknown; } +>fixed : unknown +>value.fixed : unknown +>value : { fixed: unknown; other: unknown; } +>fixed : unknown + + }, + other: { value: { fixed: "text", other: 1 } }, +>other : { value: { fixed: string; other: number; }; } +>{ value: { fixed: "text", other: 1 } } : { value: { fixed: string; other: number; }; } +>value : { fixed: string; other: number; } +>{ fixed: "text", other: 1 } : { fixed: string; other: number; } +>fixed : string +>"text" : "text" +>other : number +>1 : 1 + +}); +const callbackFixed: unknown = withCallback.fixed; +>callbackFixed : unknown +>withCallback.fixed : unknown +>withCallback : { fixed: unknown; other: unknown; } +>fixed : unknown + diff --git a/tsc/testdata/baselines/reference/compiler/narrowByBooleanComparison.types b/tsc/testdata/baselines/reference/compiler/narrowByBooleanComparison.types index 0c0ca36f17f28..af46b0f082c00 100644 --- a/tsc/testdata/baselines/reference/compiler/narrowByBooleanComparison.types +++ b/tsc/testdata/baselines/reference/compiler/narrowByBooleanComparison.types @@ -153,7 +153,7 @@ function test3(foo: unknown) { >Array.isArray : (arg: any) => arg is any[] >Array : ArrayConstructor >isArray : (arg: any) => arg is any[] ->foo : unknown +>foo : not string >false : false throw new Error('Not a string or an array'); diff --git a/tsc/testdata/baselines/reference/compiler/narrowingByTypeofInSwitch.types b/tsc/testdata/baselines/reference/compiler/narrowingByTypeofInSwitch.types index 4a5fcccf8c46a..6ccbbd2f4429c 100644 --- a/tsc/testdata/baselines/reference/compiler/narrowingByTypeofInSwitch.types +++ b/tsc/testdata/baselines/reference/compiler/narrowingByTypeofInSwitch.types @@ -866,7 +866,7 @@ function narrowingNarrows(x: {} | undefined) { default: const _y: {} = x; return; >_y : {} ->x : {} +>x : {} & not number & not false & not true & not symbol & not string } } diff --git a/tsc/testdata/baselines/reference/compiler/narrowingPastLastAssignment.types b/tsc/testdata/baselines/reference/compiler/narrowingPastLastAssignment.types index c690c529a0dca..7b21774f7a438 100644 --- a/tsc/testdata/baselines/reference/compiler/narrowingPastLastAssignment.types +++ b/tsc/testdata/baselines/reference/compiler/narrowingPastLastAssignment.types @@ -252,7 +252,7 @@ function f5b() { >x : number >1 : 1 >x === 2 : boolean ->x : number +>x : number & not 1 >2 : 2 action(() => { x /* 1 | 2 */ }) diff --git a/tsc/testdata/baselines/reference/compiler/narrowingUnionToUnion.types b/tsc/testdata/baselines/reference/compiler/narrowingUnionToUnion.types index c95edf9e1ea81..0f69a12b15042 100644 --- a/tsc/testdata/baselines/reference/compiler/narrowingUnionToUnion.types +++ b/tsc/testdata/baselines/reference/compiler/narrowingUnionToUnion.types @@ -371,9 +371,9 @@ function isEmpty(value: string | EmptyString): value is EmptyString { >value : string | null | undefined >'' : "" >value === null : boolean ->value : string | null | undefined +>value : (string & not "") | null | undefined >value === undefined : boolean ->value : string | undefined +>value : (string & not "") | undefined >undefined : undefined } @@ -421,7 +421,7 @@ function check1(x: unknown): x is (string | 0) { >x : unknown >"string" : "string" >x === 0 : boolean ->x : unknown +>x : not string >0 : 0 } @@ -435,7 +435,7 @@ function check2(x: unknown): x is ("hello" | 0) { >x : unknown >"hello" : "hello" >x === 0 : boolean ->x : unknown +>x : not "hello" >0 : 0 } @@ -450,7 +450,7 @@ function test3(x: unknown) { >x : unknown >"string" : "string" >x === 0 : boolean ->x : unknown +>x : not string >0 : 0 x; // string | 0 @@ -462,7 +462,7 @@ function test3(x: unknown) { >x : string | 0 >"hello" : "hello" >x === 0 : boolean ->x : string | 0 +>x : 0 | (string & not "hello") >0 : 0 x; // 0 | "hello" diff --git a/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.errors.txt new file mode 100644 index 0000000000000..abe5005097e92 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.errors.txt @@ -0,0 +1,53 @@ +negatedCallbackInference.ts(38,54): error TS2345: Argument of type '(value: number) => void' is not assignable to parameter of type '(value: { success: true; } & not Failure) => void'. + Types of parameters 'value' and 'value' are incompatible. + Type '{ success: true; } & not Failure' is not assignable to type 'number'. + + +==== negatedCallbackInference.ts (1 errors) ==== + interface Failure { readonly error: true; } + interface Box { value: Value; } + interface LoaderProps { + readonly load: () => Box; + readonly children: (result: Result & not Failure) => string; + } + class Loader { + constructor(name: string, context: any); + constructor(props: LoaderProps); + constructor(...args: any[]) {} + } + function load(): Box<{ success: true } | Failure> { + return null as any; + } + + const loader = new Loader({ + load, + children: result => result.success as any, + }); + + declare function inferInput(callback: (value: Result & not string) => void): Result; + const input = inferInput((value: number) => {}); + const inputUnion: number | string = input; + const inputNumber: number = input; + + declare function inferFilteredInput(callback: (value: Result & not Failure) => void): Result; + const filteredInput = inferFilteredInput((value: { success: true } & not Failure) => {}); + const filteredUnion: { success: true } | Failure = filteredInput; + const filteredSuccess: { success: true } = filteredInput; + + declare function inferOutput(callback: () => Result & not string): Result; + const output = inferOutput(() => 1); + const outputNumber: number = output; + + declare const response: { success: true } | Failure; + declare function inferFiltered(value: Result, callback: (value: Result & not Failure) => void): Result; + const explicitFiltered = inferFiltered(response, (value: { success: true } & not Failure) => {}); + const incompatibleFiltered = inferFiltered(response, (value: number) => {}); + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(value: number) => void' is not assignable to parameter of type '(value: { success: true; } & not Failure) => void'. +!!! error TS2345: Types of parameters 'value' and 'value' are incompatible. +!!! error TS2345: Type '{ success: true; } & not Failure' is not assignable to type 'number'. + + interface Tagged { tag: true; } + declare const maybeValue: { count: number } | undefined; + declare function inferTagged(value: Result, callback: (value: Result & Tagged) => void): Result; + const tagged = inferTagged(maybeValue, (value: { count: number } & Tagged) => {}); \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.symbols b/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.symbols new file mode 100644 index 0000000000000..455df7d7c7e81 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.symbols @@ -0,0 +1,189 @@ +//// [tests/cases/compiler/negatedCallbackInference.ts] //// + +=== negatedCallbackInference.ts === +interface Failure { readonly error: true; } +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) +>error : Symbol(Failure.error, Decl(negatedCallbackInference.ts, 0, 19)) + +interface Box { value: Value; } +>Box : Symbol(Box, Decl(negatedCallbackInference.ts, 0, 43)) +>Value : Symbol(Value, Decl(negatedCallbackInference.ts, 1, 14)) +>value : Symbol(Box.value, Decl(negatedCallbackInference.ts, 1, 22)) +>Value : Symbol(Value, Decl(negatedCallbackInference.ts, 1, 14)) + +interface LoaderProps { +>LoaderProps : Symbol(LoaderProps, Decl(negatedCallbackInference.ts, 1, 38)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 2, 22)) + + readonly load: () => Box; +>load : Symbol(LoaderProps.load, Decl(negatedCallbackInference.ts, 2, 42)) +>Box : Symbol(Box, Decl(negatedCallbackInference.ts, 0, 43)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 2, 22)) + + readonly children: (result: Result & not Failure) => string; +>children : Symbol(LoaderProps.children, Decl(negatedCallbackInference.ts, 3, 37)) +>result : Symbol(result, Decl(negatedCallbackInference.ts, 4, 24)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 2, 22)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) +} +class Loader { +>Loader : Symbol(Loader, Decl(negatedCallbackInference.ts, 5, 1)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 6, 13)) + + constructor(name: string, context: any); +>name : Symbol(name, Decl(negatedCallbackInference.ts, 7, 16)) +>context : Symbol(context, Decl(negatedCallbackInference.ts, 7, 29)) + + constructor(props: LoaderProps); +>props : Symbol(props, Decl(negatedCallbackInference.ts, 8, 16)) +>LoaderProps : Symbol(LoaderProps, Decl(negatedCallbackInference.ts, 1, 38)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 6, 13)) + + constructor(...args: any[]) {} +>args : Symbol(args, Decl(negatedCallbackInference.ts, 9, 16)) +} +function load(): Box<{ success: true } | Failure> { +>load : Symbol(load, Decl(negatedCallbackInference.ts, 10, 1)) +>Box : Symbol(Box, Decl(negatedCallbackInference.ts, 0, 43)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 11, 22)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) + + return null as any; +} + +const loader = new Loader({ +>loader : Symbol(loader, Decl(negatedCallbackInference.ts, 15, 5)) +>Loader : Symbol(Loader, Decl(negatedCallbackInference.ts, 5, 1)) + + load, +>load : Symbol(load, Decl(negatedCallbackInference.ts, 15, 27)) + + children: result => result.success as any, +>children : Symbol(children, Decl(negatedCallbackInference.ts, 16, 9)) +>result : Symbol(result, Decl(negatedCallbackInference.ts, 17, 13)) +>result.success : Symbol(success, Decl(negatedCallbackInference.ts, 11, 22)) +>result : Symbol(result, Decl(negatedCallbackInference.ts, 17, 13)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 11, 22)) + +}); + +declare function inferInput(callback: (value: Result & not string) => void): Result; +>inferInput : Symbol(inferInput, Decl(negatedCallbackInference.ts, 18, 3)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 20, 28)) +>callback : Symbol(callback, Decl(negatedCallbackInference.ts, 20, 36)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 20, 47)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 20, 28)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 20, 28)) + +const input = inferInput((value: number) => {}); +>input : Symbol(input, Decl(negatedCallbackInference.ts, 21, 5)) +>inferInput : Symbol(inferInput, Decl(negatedCallbackInference.ts, 18, 3)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 21, 26)) + +const inputUnion: number | string = input; +>inputUnion : Symbol(inputUnion, Decl(negatedCallbackInference.ts, 22, 5)) +>input : Symbol(input, Decl(negatedCallbackInference.ts, 21, 5)) + +const inputNumber: number = input; +>inputNumber : Symbol(inputNumber, Decl(negatedCallbackInference.ts, 23, 5)) +>input : Symbol(input, Decl(negatedCallbackInference.ts, 21, 5)) + +declare function inferFilteredInput(callback: (value: Result & not Failure) => void): Result; +>inferFilteredInput : Symbol(inferFilteredInput, Decl(negatedCallbackInference.ts, 23, 34)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 25, 36)) +>callback : Symbol(callback, Decl(negatedCallbackInference.ts, 25, 44)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 25, 55)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 25, 36)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 25, 36)) + +const filteredInput = inferFilteredInput((value: { success: true } & not Failure) => {}); +>filteredInput : Symbol(filteredInput, Decl(negatedCallbackInference.ts, 26, 5)) +>inferFilteredInput : Symbol(inferFilteredInput, Decl(negatedCallbackInference.ts, 23, 34)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 26, 42)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 26, 50)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) + +const filteredUnion: { success: true } | Failure = filteredInput; +>filteredUnion : Symbol(filteredUnion, Decl(negatedCallbackInference.ts, 27, 5)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 27, 22)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) +>filteredInput : Symbol(filteredInput, Decl(negatedCallbackInference.ts, 26, 5)) + +const filteredSuccess: { success: true } = filteredInput; +>filteredSuccess : Symbol(filteredSuccess, Decl(negatedCallbackInference.ts, 28, 5)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 28, 24)) +>filteredInput : Symbol(filteredInput, Decl(negatedCallbackInference.ts, 26, 5)) + +declare function inferOutput(callback: () => Result & not string): Result; +>inferOutput : Symbol(inferOutput, Decl(negatedCallbackInference.ts, 28, 57)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 30, 29)) +>callback : Symbol(callback, Decl(negatedCallbackInference.ts, 30, 37)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 30, 29)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 30, 29)) + +const output = inferOutput(() => 1); +>output : Symbol(output, Decl(negatedCallbackInference.ts, 31, 5)) +>inferOutput : Symbol(inferOutput, Decl(negatedCallbackInference.ts, 28, 57)) + +const outputNumber: number = output; +>outputNumber : Symbol(outputNumber, Decl(negatedCallbackInference.ts, 32, 5)) +>output : Symbol(output, Decl(negatedCallbackInference.ts, 31, 5)) + +declare const response: { success: true } | Failure; +>response : Symbol(response, Decl(negatedCallbackInference.ts, 34, 13)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 34, 25)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) + +declare function inferFiltered(value: Result, callback: (value: Result & not Failure) => void): Result; +>inferFiltered : Symbol(inferFiltered, Decl(negatedCallbackInference.ts, 34, 52)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 35, 31)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 35, 39)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 35, 31)) +>callback : Symbol(callback, Decl(negatedCallbackInference.ts, 35, 53)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 35, 65)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 35, 31)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 35, 31)) + +const explicitFiltered = inferFiltered(response, (value: { success: true } & not Failure) => {}); +>explicitFiltered : Symbol(explicitFiltered, Decl(negatedCallbackInference.ts, 36, 5)) +>inferFiltered : Symbol(inferFiltered, Decl(negatedCallbackInference.ts, 34, 52)) +>response : Symbol(response, Decl(negatedCallbackInference.ts, 34, 13)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 36, 50)) +>success : Symbol(success, Decl(negatedCallbackInference.ts, 36, 58)) +>Failure : Symbol(Failure, Decl(negatedCallbackInference.ts, 0, 0)) + +const incompatibleFiltered = inferFiltered(response, (value: number) => {}); +>incompatibleFiltered : Symbol(incompatibleFiltered, Decl(negatedCallbackInference.ts, 37, 5)) +>inferFiltered : Symbol(inferFiltered, Decl(negatedCallbackInference.ts, 34, 52)) +>response : Symbol(response, Decl(negatedCallbackInference.ts, 34, 13)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 37, 54)) + +interface Tagged { tag: true; } +>Tagged : Symbol(Tagged, Decl(negatedCallbackInference.ts, 37, 76)) +>tag : Symbol(Tagged.tag, Decl(negatedCallbackInference.ts, 39, 18)) + +declare const maybeValue: { count: number } | undefined; +>maybeValue : Symbol(maybeValue, Decl(negatedCallbackInference.ts, 40, 13)) +>count : Symbol(count, Decl(negatedCallbackInference.ts, 40, 27)) + +declare function inferTagged(value: Result, callback: (value: Result & Tagged) => void): Result; +>inferTagged : Symbol(inferTagged, Decl(negatedCallbackInference.ts, 40, 56)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 41, 29)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 41, 37)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 41, 29)) +>callback : Symbol(callback, Decl(negatedCallbackInference.ts, 41, 51)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 41, 63)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 41, 29)) +>Tagged : Symbol(Tagged, Decl(negatedCallbackInference.ts, 37, 76)) +>Result : Symbol(Result, Decl(negatedCallbackInference.ts, 41, 29)) + +const tagged = inferTagged(maybeValue, (value: { count: number } & Tagged) => {}); +>tagged : Symbol(tagged, Decl(negatedCallbackInference.ts, 42, 5)) +>inferTagged : Symbol(inferTagged, Decl(negatedCallbackInference.ts, 40, 56)) +>maybeValue : Symbol(maybeValue, Decl(negatedCallbackInference.ts, 40, 13)) +>value : Symbol(value, Decl(negatedCallbackInference.ts, 42, 40)) +>count : Symbol(count, Decl(negatedCallbackInference.ts, 42, 48)) +>Tagged : Symbol(Tagged, Decl(negatedCallbackInference.ts, 37, 76)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.types b/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.types new file mode 100644 index 0000000000000..41df73aaec06a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedCallbackInference.types @@ -0,0 +1,173 @@ +//// [tests/cases/compiler/negatedCallbackInference.ts] //// + +=== negatedCallbackInference.ts === +interface Failure { readonly error: true; } +>error : true +>true : true + +interface Box { value: Value; } +>value : Value + +interface LoaderProps { + readonly load: () => Box; +>load : () => Box + + readonly children: (result: Result & not Failure) => string; +>children : (result: Result & not Failure) => string +>result : Result & not Failure +} +class Loader { +>Loader : Loader + + constructor(name: string, context: any); +>name : string +>context : any + + constructor(props: LoaderProps); +>props : LoaderProps + + constructor(...args: any[]) {} +>args : any[] +} +function load(): Box<{ success: true } | Failure> { +>load : () => Box<{ success: true; } | Failure> +>success : true +>true : true + + return null as any; +>null as any : any +} + +const loader = new Loader({ +>loader : Loader +>new Loader({ load, children: result => result.success as any,}) : Loader +>Loader : typeof Loader +>{ load, children: result => result.success as any,} : { load: () => Box<{ success: true; } | Failure>; children: (result: { success: true; } & not Failure) => any; } + + load, +>load : () => Box<{ success: true; } | Failure> + + children: result => result.success as any, +>children : (result: { success: true; } & not Failure) => any +>result => result.success as any : (result: { success: true; } & not Failure) => any +>result : { success: true; } & not Failure +>result.success as any : any +>result.success : true +>result : { success: true; } & not Failure +>success : true + +}); + +declare function inferInput(callback: (value: Result & not string) => void): Result; +>inferInput : (callback: (value: Result & not string) => void) => Result +>callback : (value: Result & not string) => void +>value : Result & not string + +const input = inferInput((value: number) => {}); +>input : number +>inferInput((value: number) => {}) : number +>inferInput : (callback: (value: Result & not string) => void) => Result +>(value: number) => {} : (value: number) => void +>value : number + +const inputUnion: number | string = input; +>inputUnion : string | number +>input : number + +const inputNumber: number = input; +>inputNumber : number +>input : number + +declare function inferFilteredInput(callback: (value: Result & not Failure) => void): Result; +>inferFilteredInput : (callback: (value: Result & not Failure) => void) => Result +>callback : (value: Result & not Failure) => void +>value : Result & not Failure + +const filteredInput = inferFilteredInput((value: { success: true } & not Failure) => {}); +>filteredInput : { success: true; } +>inferFilteredInput((value: { success: true } & not Failure) => {}) : { success: true; } +>inferFilteredInput : (callback: (value: Result & not Failure) => void) => Result +>(value: { success: true } & not Failure) => {} : (value: { success: true; } & not Failure) => void +>value : { success: true; } & not Failure +>success : true +>true : true + +const filteredUnion: { success: true } | Failure = filteredInput; +>filteredUnion : Failure | { success: true; } +>success : true +>true : true +>filteredInput : { success: true; } + +const filteredSuccess: { success: true } = filteredInput; +>filteredSuccess : { success: true; } +>success : true +>true : true +>filteredInput : { success: true; } + +declare function inferOutput(callback: () => Result & not string): Result; +>inferOutput : (callback: () => Result & not string) => Result +>callback : () => Result & not string + +const output = inferOutput(() => 1); +>output : number +>inferOutput(() => 1) : number +>inferOutput : (callback: () => Result & not string) => Result +>() => 1 : () => number +>1 : 1 + +const outputNumber: number = output; +>outputNumber : number +>output : number + +declare const response: { success: true } | Failure; +>response : Failure | { success: true; } +>success : true +>true : true + +declare function inferFiltered(value: Result, callback: (value: Result & not Failure) => void): Result; +>inferFiltered : (value: Result, callback: (value: Result & not Failure) => void) => Result +>value : Result +>callback : (value: Result & not Failure) => void +>value : Result & not Failure + +const explicitFiltered = inferFiltered(response, (value: { success: true } & not Failure) => {}); +>explicitFiltered : Failure | { success: true; } +>inferFiltered(response, (value: { success: true } & not Failure) => {}) : Failure | { success: true; } +>inferFiltered : (value: Result, callback: (value: Result & not Failure) => void) => Result +>response : Failure | { success: true; } +>(value: { success: true } & not Failure) => {} : (value: { success: true; } & not Failure) => void +>value : { success: true; } & not Failure +>success : true +>true : true + +const incompatibleFiltered = inferFiltered(response, (value: number) => {}); +>incompatibleFiltered : Failure | { success: true; } +>inferFiltered(response, (value: number) => {}) : Failure | { success: true; } +>inferFiltered : (value: Result, callback: (value: Result & not Failure) => void) => Result +>response : Failure | { success: true; } +>(value: number) => {} : (value: number) => void +>value : number + +interface Tagged { tag: true; } +>tag : true +>true : true + +declare const maybeValue: { count: number } | undefined; +>maybeValue : { count: number; } | undefined +>count : number + +declare function inferTagged(value: Result, callback: (value: Result & Tagged) => void): Result; +>inferTagged : (value: Result, callback: (value: Result & Tagged) => void) => Result +>value : Result +>callback : (value: Result & Tagged) => void +>value : Result & Tagged + +const tagged = inferTagged(maybeValue, (value: { count: number } & Tagged) => {}); +>tagged : { count: number; } | undefined +>inferTagged(maybeValue, (value: { count: number } & Tagged) => {}) : { count: number; } | undefined +>inferTagged : (value: Result, callback: (value: Result & Tagged) => void) => Result +>maybeValue : { count: number; } | undefined +>(value: { count: number } & Tagged) => {} : (value: { count: number; } & Tagged) => void +>value : { count: number; } & Tagged +>count : number + diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementCircularReduction.symbols b/tsc/testdata/baselines/reference/compiler/negatedComplementCircularReduction.symbols new file mode 100644 index 0000000000000..84444496db947 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementCircularReduction.symbols @@ -0,0 +1,66 @@ +//// [tests/cases/compiler/negatedComplementCircularReduction.ts] //// + +=== negatedComplementCircularReduction.ts === +type Keys = Value extends unknown ? keyof Value : never; +>Keys : Symbol(Keys, Decl(negatedComplementCircularReduction.ts, 0, 0)) +>Value : Symbol(Value, Decl(negatedComplementCircularReduction.ts, 0, 10)) +>Value : Symbol(Value, Decl(negatedComplementCircularReduction.ts, 0, 10)) +>Value : Symbol(Value, Decl(negatedComplementCircularReduction.ts, 0, 10)) + +type Recursive = +>Recursive : Symbol(Recursive, Decl(negatedComplementCircularReduction.ts, 0, 63)) + + | { next: Recursive; value: string } +>next : Symbol(next, Decl(negatedComplementCircularReduction.ts, 2, 7)) +>Recursive : Symbol(Recursive, Decl(negatedComplementCircularReduction.ts, 0, 63)) +>value : Symbol(value, Decl(negatedComplementCircularReduction.ts, 2, 24)) + + | ({ next: unknown } & not { value: string }) +>next : Symbol(next, Decl(negatedComplementCircularReduction.ts, 3, 8)) +>value : Symbol(value, Decl(negatedComplementCircularReduction.ts, 3, 32)) + + | { next: unknown; value: string }; +>next : Symbol(next, Decl(negatedComplementCircularReduction.ts, 4, 7)) +>value : Symbol(value, Decl(negatedComplementCircularReduction.ts, 4, 22)) + +// The first query encounters a reduction cycle and distributes over the unreduced union. +type Early = Keys; +>Early : Symbol(Early, Decl(negatedComplementCircularReduction.ts, 4, 39)) +>Keys : Symbol(Keys, Decl(negatedComplementCircularReduction.ts, 0, 0)) +>Recursive : Symbol(Recursive, Decl(negatedComplementCircularReduction.ts, 0, 63)) + +// Use a separate conditional alias so the later query does not reuse the first instantiation. +type LaterKeys = Value extends unknown ? keyof Value : never; +>LaterKeys : Symbol(LaterKeys, Decl(negatedComplementCircularReduction.ts, 7, 29)) +>Value : Symbol(Value, Decl(negatedComplementCircularReduction.ts, 9, 15)) +>Value : Symbol(Value, Decl(negatedComplementCircularReduction.ts, 9, 15)) +>Value : Symbol(Value, Decl(negatedComplementCircularReduction.ts, 9, 15)) + +declare const early: Early; +>early : Symbol(early, Decl(negatedComplementCircularReduction.ts, 11, 13)) +>Early : Symbol(Early, Decl(negatedComplementCircularReduction.ts, 4, 39)) + +declare const later: LaterKeys; +>later : Symbol(later, Decl(negatedComplementCircularReduction.ts, 12, 13)) +>LaterKeys : Symbol(LaterKeys, Decl(negatedComplementCircularReduction.ts, 7, 29)) +>Recursive : Symbol(Recursive, Decl(negatedComplementCircularReduction.ts, 0, 63)) + +const consistent: typeof early = later; +>consistent : Symbol(consistent, Decl(negatedComplementCircularReduction.ts, 13, 5)) +>early : Symbol(early, Decl(negatedComplementCircularReduction.ts, 11, 13)) +>later : Symbol(later, Decl(negatedComplementCircularReduction.ts, 12, 13)) + +const reverseConsistent: typeof later = early; +>reverseConsistent : Symbol(reverseConsistent, Decl(negatedComplementCircularReduction.ts, 14, 5)) +>later : Symbol(later, Decl(negatedComplementCircularReduction.ts, 12, 13)) +>early : Symbol(early, Decl(negatedComplementCircularReduction.ts, 11, 13)) + +// Retrying reduction used to remove "value" from only the later query. +const earlyValue: typeof early = "value"; +>earlyValue : Symbol(earlyValue, Decl(negatedComplementCircularReduction.ts, 17, 5)) +>early : Symbol(early, Decl(negatedComplementCircularReduction.ts, 11, 13)) + +const laterValue: typeof later = "value"; +>laterValue : Symbol(laterValue, Decl(negatedComplementCircularReduction.ts, 18, 5)) +>later : Symbol(later, Decl(negatedComplementCircularReduction.ts, 12, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementCircularReduction.types b/tsc/testdata/baselines/reference/compiler/negatedComplementCircularReduction.types new file mode 100644 index 0000000000000..a14004fe8ee1b --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementCircularReduction.types @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/negatedComplementCircularReduction.ts] //// + +=== negatedComplementCircularReduction.ts === +type Keys = Value extends unknown ? keyof Value : never; +>Keys : Keys + +type Recursive = +>Recursive : Recursive + + | { next: Recursive; value: string } +>next : Recursive +>value : string + + | ({ next: unknown } & not { value: string }) +>next : unknown +>value : string + + | { next: unknown; value: string }; +>next : unknown +>value : string + +// The first query encounters a reduction cycle and distributes over the unreduced union. +type Early = Keys; +>Early : Early + +// Use a separate conditional alias so the later query does not reuse the first instantiation. +type LaterKeys = Value extends unknown ? keyof Value : never; +>LaterKeys : LaterKeys + +declare const early: Early; +>early : Early + +declare const later: LaterKeys; +>later : "next" | "value" + +const consistent: typeof early = later; +>consistent : Early +>early : Early +>later : "next" | "value" + +const reverseConsistent: typeof later = early; +>reverseConsistent : "next" | "value" +>later : "next" | "value" +>early : Early + +// Retrying reduction used to remove "value" from only the later query. +const earlyValue: typeof early = "value"; +>earlyValue : Early +>early : Early +>"value" : "value" + +const laterValue: typeof later = "value"; +>laterValue : "next" | "value" +>later : "next" | "value" +>"value" : "value" + diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.errors.txt new file mode 100644 index 0000000000000..a2c432974a131 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.errors.txt @@ -0,0 +1,80 @@ +negatedComplementEqualityNarrowing.ts(7,15): error TS2322: Type 'string' is not assignable to type 'never'. +negatedComplementEqualityNarrowing.ts(13,15): error TS2322: Type 'string' is not assignable to type 'never'. +negatedComplementEqualityNarrowing.ts(27,15): error TS2322: Type 'string' is not assignable to type 'never'. +negatedComplementEqualityNarrowing.ts(33,15): error TS2322: Type 'string' is not assignable to type 'never'. +negatedComplementEqualityNarrowing.ts(47,15): error TS2322: Type 'string' is not assignable to type 'never'. +negatedComplementEqualityNarrowing.ts(53,15): error TS2322: Type 'string' is not assignable to type 'never'. + + +==== negatedComplementEqualityNarrowing.ts (6 errors) ==== + type Full = string | not string; + + function complementEquality(value: Full) { + if (value == 42 && typeof value === "string") { + const text: string = value; + // Error: "42" reaches this branch through coercion. + const impossible: never = value; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + if (42 != value) { + } else if (typeof value === "string") { + const text: string = value; + // Error: Reversing the operands and negating the comparison still allows strings. + const impossible: never = value; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + if (value === 42) { + const literal: 42 = value; + } + if (value !== 42) { + const excluded: not 42 = value; + } + } + + function unknownEquality(value: unknown) { + if (value == 42 && typeof value === "string") { + const text: string = value; + // Error: "42" reaches this branch through coercion. + const impossible: never = value; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + if (42 != value) { + } else if (typeof value === "string") { + const text: string = value; + // Error: Reversing the operands and negating the comparison still allows strings. + const impossible: never = value; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + if (value === 42) { + const literal: 42 = value; + } + if (value !== 42) { + const excluded: not 42 = value; + } + } + + function complementPropertyEquality(value: { full: Full }) { + if (value.full == 42 && typeof value.full === "string") { + const text: string = value.full; + // Error: A property can also contain the coerced string. + const impossible: never = value.full; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + if (42 != value.full) { + } else if (typeof value.full === "string") { + const text: string = value.full; + // Error: The false inequality branch still allows strings. + const impossible: never = value.full; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + } + + complementEquality("42"); + unknownEquality("42"); + complementPropertyEquality({ full: "42" }); \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.symbols b/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.symbols new file mode 100644 index 0000000000000..93e38edacb059 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.symbols @@ -0,0 +1,165 @@ +//// [tests/cases/compiler/negatedComplementEqualityNarrowing.ts] //// + +=== negatedComplementEqualityNarrowing.ts === +type Full = string | not string; +>Full : Symbol(Full, Decl(negatedComplementEqualityNarrowing.ts, 0, 0)) + +function complementEquality(value: Full) { +>complementEquality : Symbol(complementEquality, Decl(negatedComplementEqualityNarrowing.ts, 0, 32)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) +>Full : Symbol(Full, Decl(negatedComplementEqualityNarrowing.ts, 0, 0)) + + if (value == 42 && typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementEqualityNarrowing.ts, 4, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + // Error: "42" reaches this branch through coercion. + const impossible: never = value; +>impossible : Symbol(impossible, Decl(negatedComplementEqualityNarrowing.ts, 6, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + } + if (42 != value) { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + } else if (typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementEqualityNarrowing.ts, 10, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + // Error: Reversing the operands and negating the comparison still allows strings. + const impossible: never = value; +>impossible : Symbol(impossible, Decl(negatedComplementEqualityNarrowing.ts, 12, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + } + if (value === 42) { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + const literal: 42 = value; +>literal : Symbol(literal, Decl(negatedComplementEqualityNarrowing.ts, 15, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + } + if (value !== 42) { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + + const excluded: not 42 = value; +>excluded : Symbol(excluded, Decl(negatedComplementEqualityNarrowing.ts, 18, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 2, 28)) + } +} + +function unknownEquality(value: unknown) { +>unknownEquality : Symbol(unknownEquality, Decl(negatedComplementEqualityNarrowing.ts, 20, 1)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + if (value == 42 && typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementEqualityNarrowing.ts, 24, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + // Error: "42" reaches this branch through coercion. + const impossible: never = value; +>impossible : Symbol(impossible, Decl(negatedComplementEqualityNarrowing.ts, 26, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + } + if (42 != value) { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + } else if (typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementEqualityNarrowing.ts, 30, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + // Error: Reversing the operands and negating the comparison still allows strings. + const impossible: never = value; +>impossible : Symbol(impossible, Decl(negatedComplementEqualityNarrowing.ts, 32, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + } + if (value === 42) { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + const literal: 42 = value; +>literal : Symbol(literal, Decl(negatedComplementEqualityNarrowing.ts, 35, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + } + if (value !== 42) { +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + + const excluded: not 42 = value; +>excluded : Symbol(excluded, Decl(negatedComplementEqualityNarrowing.ts, 38, 13)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 22, 25)) + } +} + +function complementPropertyEquality(value: { full: Full }) { +>complementPropertyEquality : Symbol(complementPropertyEquality, Decl(negatedComplementEqualityNarrowing.ts, 40, 1)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>Full : Symbol(Full, Decl(negatedComplementEqualityNarrowing.ts, 0, 0)) + + if (value.full == 42 && typeof value.full === "string") { +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + + const text: string = value.full; +>text : Symbol(text, Decl(negatedComplementEqualityNarrowing.ts, 44, 13)) +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + + // Error: A property can also contain the coerced string. + const impossible: never = value.full; +>impossible : Symbol(impossible, Decl(negatedComplementEqualityNarrowing.ts, 46, 13)) +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + } + if (42 != value.full) { +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + + } else if (typeof value.full === "string") { +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + + const text: string = value.full; +>text : Symbol(text, Decl(negatedComplementEqualityNarrowing.ts, 50, 13)) +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + + // Error: The false inequality branch still allows strings. + const impossible: never = value.full; +>impossible : Symbol(impossible, Decl(negatedComplementEqualityNarrowing.ts, 52, 13)) +>value.full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) +>value : Symbol(value, Decl(negatedComplementEqualityNarrowing.ts, 42, 36)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 42, 44)) + } +} + +complementEquality("42"); +>complementEquality : Symbol(complementEquality, Decl(negatedComplementEqualityNarrowing.ts, 0, 32)) + +unknownEquality("42"); +>unknownEquality : Symbol(unknownEquality, Decl(negatedComplementEqualityNarrowing.ts, 20, 1)) + +complementPropertyEquality({ full: "42" }); +>complementPropertyEquality : Symbol(complementPropertyEquality, Decl(negatedComplementEqualityNarrowing.ts, 40, 1)) +>full : Symbol(full, Decl(negatedComplementEqualityNarrowing.ts, 58, 28)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.types b/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.types new file mode 100644 index 0000000000000..935640c97e492 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementEqualityNarrowing.types @@ -0,0 +1,211 @@ +//// [tests/cases/compiler/negatedComplementEqualityNarrowing.ts] //// + +=== negatedComplementEqualityNarrowing.ts === +type Full = string | not string; +>Full : unknown + +function complementEquality(value: Full) { +>complementEquality : (value: Full) => void +>value : unknown + + if (value == 42 && typeof value === "string") { +>value == 42 && typeof value === "string" : boolean +>value == 42 : boolean +>value : unknown +>42 : 42 +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + + // Error: "42" reaches this branch through coercion. + const impossible: never = value; +>impossible : never +>value : string + } + if (42 != value) { +>42 != value : boolean +>42 : 42 +>value : unknown + + } else if (typeof value === "string") { +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + + // Error: Reversing the operands and negating the comparison still allows strings. + const impossible: never = value; +>impossible : never +>value : string + } + if (value === 42) { +>value === 42 : boolean +>value : unknown +>42 : 42 + + const literal: 42 = value; +>literal : 42 +>value : 42 + } + if (value !== 42) { +>value !== 42 : boolean +>value : unknown +>42 : 42 + + const excluded: not 42 = value; +>excluded : not 42 +>value : not 42 + } +} + +function unknownEquality(value: unknown) { +>unknownEquality : (value: unknown) => void +>value : unknown + + if (value == 42 && typeof value === "string") { +>value == 42 && typeof value === "string" : boolean +>value == 42 : boolean +>value : unknown +>42 : 42 +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + + // Error: "42" reaches this branch through coercion. + const impossible: never = value; +>impossible : never +>value : string + } + if (42 != value) { +>42 != value : boolean +>42 : 42 +>value : unknown + + } else if (typeof value === "string") { +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + + // Error: Reversing the operands and negating the comparison still allows strings. + const impossible: never = value; +>impossible : never +>value : string + } + if (value === 42) { +>value === 42 : boolean +>value : unknown +>42 : 42 + + const literal: 42 = value; +>literal : 42 +>value : 42 + } + if (value !== 42) { +>value !== 42 : boolean +>value : unknown +>42 : 42 + + const excluded: not 42 = value; +>excluded : not 42 +>value : not 42 + } +} + +function complementPropertyEquality(value: { full: Full }) { +>complementPropertyEquality : (value: { full: Full; }) => void +>value : { full: Full; } +>full : unknown + + if (value.full == 42 && typeof value.full === "string") { +>value.full == 42 && typeof value.full === "string" : boolean +>value.full == 42 : boolean +>value.full : unknown +>value : { full: Full; } +>full : unknown +>42 : 42 +>typeof value.full === "string" : boolean +>typeof value.full : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value.full : unknown +>value : { full: Full; } +>full : unknown +>"string" : "string" + + const text: string = value.full; +>text : string +>value.full : string +>value : { full: Full; } +>full : string + + // Error: A property can also contain the coerced string. + const impossible: never = value.full; +>impossible : never +>value.full : string +>value : { full: Full; } +>full : string + } + if (42 != value.full) { +>42 != value.full : boolean +>42 : 42 +>value.full : unknown +>value : { full: Full; } +>full : unknown + + } else if (typeof value.full === "string") { +>typeof value.full === "string" : boolean +>typeof value.full : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value.full : unknown +>value : { full: Full; } +>full : unknown +>"string" : "string" + + const text: string = value.full; +>text : string +>value.full : string +>value : { full: Full; } +>full : string + + // Error: The false inequality branch still allows strings. + const impossible: never = value.full; +>impossible : never +>value.full : string +>value : { full: Full; } +>full : string + } +} + +complementEquality("42"); +>complementEquality("42") : void +>complementEquality : (value: Full) => void +>"42" : "42" + +unknownEquality("42"); +>unknownEquality("42") : void +>unknownEquality : (value: unknown) => void +>"42" : "42" + +complementPropertyEquality({ full: "42" }); +>complementPropertyEquality({ full: "42" }) : void +>complementPropertyEquality : (value: { full: Full; }) => void +>{ full: "42" } : { full: string; } +>full : string +>"42" : "42" + diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.errors.txt new file mode 100644 index 0000000000000..c32f085944802 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.errors.txt @@ -0,0 +1,143 @@ +negatedComplementFlowNormalization.ts(28,11): error TS2322: Type 'unknown' is not assignable to type 'number'. +negatedComplementFlowNormalization.ts(33,11): error TS2322: Type 'unknown' is not assignable to type 'string | number'. +negatedComplementFlowNormalization.ts(39,11): error TS2322: Type 'unknown' is not assignable to type 'string | number'. +negatedComplementFlowNormalization.ts(62,11): error TS2322: Type 'unknown' is not assignable to type 'number'. +negatedComplementFlowNormalization.ts(67,11): error TS2322: Type 'unknown' is not assignable to type 'string | number'. +negatedComplementFlowNormalization.ts(73,11): error TS2322: Type 'unknown' is not assignable to type 'string | number'. +negatedComplementFlowNormalization.ts(96,15): error TS2322: Type 'string' is not assignable to type 'never'. +negatedComplementFlowNormalization.ts(104,11): error TS2322: Type 'string' is not assignable to type 'never'. + + +==== negatedComplementFlowNormalization.ts (8 errors) ==== + type Full = string | not string; + declare const numericCase: number; + declare const objectCase: { value: string }; + declare function isFull(value: unknown): value is Full; + declare function assertFull(value: unknown): asserts value is Full; + declare function assertCondition(value: unknown): asserts value; + + function complementFlow(value: Full, condition: boolean) { + switch (value) { + case numericCase: + const numeric: number = value; + break; + case objectCase: + const objectValue: object = value; + break; + } + if (value) { + const nonNull: {} = value; + } + if (typeof value === "string") { + const text: string = value; + } + if (typeof value === "object" && value !== null && "value" in value) { + const member: unknown = value.value; + } + value = 42; + // Error: An exhaustive complement behaves like unknown after assignment. + const assigned: number = value; + ~~~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + if (condition) { + value = "42"; + } + // Error: Joining assignments must retain unknown. + const joined: string | number = value; + ~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'string | number'. + while (condition) { + value = condition ? "42" : 42; + condition = false; + } + // Error: The loop result must also retain unknown. + const looped: string | number = value; + ~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'string | number'. + } + + function unknownFlow(value: unknown, condition: boolean) { + switch (value) { + case numericCase: + const numeric: number = value; + break; + case objectCase: + const objectValue: object = value; + break; + } + if (value) { + const nonNull: {} = value; + } + if (typeof value === "string") { + const text: string = value; + } + if (typeof value === "object" && value !== null && "value" in value) { + const member: unknown = value.value; + } + value = 42; + // Error: Unknown is not assignment-narrowed. + const assigned: number = value; + ~~~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + if (condition) { + value = "42"; + } + // Error: Joining assignments must retain unknown. + const joined: string | number = value; + ~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'string | number'. + while (condition) { + value = condition ? "42" : 42; + condition = false; + } + // Error: The loop result must also retain unknown. + const looped: string | number = value; + ~~~~~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'string | number'. + } + + function predicateFlow(value: unknown) { + if (isFull(value)) { + switch (value) { + case objectCase: + const objectValue: object = value; + break; + } + } + } + + function assertionFlow(value: unknown) { + assertFull(value); + switch (value) { + case objectCase: + const objectValue: object = value; + break; + } + assertCondition(value == 42); + if (typeof value === "string") { + // Error: Assertion narrowing must preserve the reachable string branch. + const impossible: never = value; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + } + + function compoundAssertionFlow(value: unknown) { + assertCondition(isFull(value) && value == 42 && typeof value === "string"); + const text: string = value; + // Error: Narrowing steps within one assertion must also preserve strings. + const impossible: never = value; + ~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'never'. + } + + function evolvingArray(condition: boolean) { + const values = []; + if (condition) { + values.push(42); + } else { + values.push("42"); + } + const result: (string | number)[] = values; + return result; + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.symbols b/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.symbols new file mode 100644 index 0000000000000..cc12efbeb075f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.symbols @@ -0,0 +1,307 @@ +//// [tests/cases/compiler/negatedComplementFlowNormalization.ts] //// + +=== negatedComplementFlowNormalization.ts === +type Full = string | not string; +>Full : Symbol(Full, Decl(negatedComplementFlowNormalization.ts, 0, 0)) + +declare const numericCase: number; +>numericCase : Symbol(numericCase, Decl(negatedComplementFlowNormalization.ts, 1, 13)) + +declare const objectCase: { value: string }; +>objectCase : Symbol(objectCase, Decl(negatedComplementFlowNormalization.ts, 2, 13)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 2, 27)) + +declare function isFull(value: unknown): value is Full; +>isFull : Symbol(isFull, Decl(negatedComplementFlowNormalization.ts, 2, 44)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 3, 24)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 3, 24)) +>Full : Symbol(Full, Decl(negatedComplementFlowNormalization.ts, 0, 0)) + +declare function assertFull(value: unknown): asserts value is Full; +>assertFull : Symbol(assertFull, Decl(negatedComplementFlowNormalization.ts, 3, 55)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 4, 28)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 4, 28)) +>Full : Symbol(Full, Decl(negatedComplementFlowNormalization.ts, 0, 0)) + +declare function assertCondition(value: unknown): asserts value; +>assertCondition : Symbol(assertCondition, Decl(negatedComplementFlowNormalization.ts, 4, 67)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 5, 33)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 5, 33)) + +function complementFlow(value: Full, condition: boolean) { +>complementFlow : Symbol(complementFlow, Decl(negatedComplementFlowNormalization.ts, 5, 64)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) +>Full : Symbol(Full, Decl(negatedComplementFlowNormalization.ts, 0, 0)) +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 7, 36)) + + switch (value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + case numericCase: +>numericCase : Symbol(numericCase, Decl(negatedComplementFlowNormalization.ts, 1, 13)) + + const numeric: number = value; +>numeric : Symbol(numeric, Decl(negatedComplementFlowNormalization.ts, 10, 17)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + break; + case objectCase: +>objectCase : Symbol(objectCase, Decl(negatedComplementFlowNormalization.ts, 2, 13)) + + const objectValue: object = value; +>objectValue : Symbol(objectValue, Decl(negatedComplementFlowNormalization.ts, 13, 17)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + break; + } + if (value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + const nonNull: {} = value; +>nonNull : Symbol(nonNull, Decl(negatedComplementFlowNormalization.ts, 17, 13)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + } + if (typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementFlowNormalization.ts, 20, 13)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + } + if (typeof value === "object" && value !== null && "value" in value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + const member: unknown = value.value; +>member : Symbol(member, Decl(negatedComplementFlowNormalization.ts, 23, 13)) +>value.value : Symbol(value) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) +>value : Symbol(value) + } + value = 42; +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + // Error: An exhaustive complement behaves like unknown after assignment. + const assigned: number = value; +>assigned : Symbol(assigned, Decl(negatedComplementFlowNormalization.ts, 27, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + if (condition) { +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 7, 36)) + + value = "42"; +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + } + // Error: Joining assignments must retain unknown. + const joined: string | number = value; +>joined : Symbol(joined, Decl(negatedComplementFlowNormalization.ts, 32, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) + + while (condition) { +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 7, 36)) + + value = condition ? "42" : 42; +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 7, 36)) + + condition = false; +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 7, 36)) + } + // Error: The loop result must also retain unknown. + const looped: string | number = value; +>looped : Symbol(looped, Decl(negatedComplementFlowNormalization.ts, 38, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 7, 24)) +} + +function unknownFlow(value: unknown, condition: boolean) { +>unknownFlow : Symbol(unknownFlow, Decl(negatedComplementFlowNormalization.ts, 39, 1)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 41, 36)) + + switch (value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + case numericCase: +>numericCase : Symbol(numericCase, Decl(negatedComplementFlowNormalization.ts, 1, 13)) + + const numeric: number = value; +>numeric : Symbol(numeric, Decl(negatedComplementFlowNormalization.ts, 44, 17)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + break; + case objectCase: +>objectCase : Symbol(objectCase, Decl(negatedComplementFlowNormalization.ts, 2, 13)) + + const objectValue: object = value; +>objectValue : Symbol(objectValue, Decl(negatedComplementFlowNormalization.ts, 47, 17)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + break; + } + if (value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + const nonNull: {} = value; +>nonNull : Symbol(nonNull, Decl(negatedComplementFlowNormalization.ts, 51, 13)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + } + if (typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementFlowNormalization.ts, 54, 13)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + } + if (typeof value === "object" && value !== null && "value" in value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + const member: unknown = value.value; +>member : Symbol(member, Decl(negatedComplementFlowNormalization.ts, 57, 13)) +>value.value : Symbol(value) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) +>value : Symbol(value) + } + value = 42; +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + // Error: Unknown is not assignment-narrowed. + const assigned: number = value; +>assigned : Symbol(assigned, Decl(negatedComplementFlowNormalization.ts, 61, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + if (condition) { +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 41, 36)) + + value = "42"; +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + } + // Error: Joining assignments must retain unknown. + const joined: string | number = value; +>joined : Symbol(joined, Decl(negatedComplementFlowNormalization.ts, 66, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) + + while (condition) { +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 41, 36)) + + value = condition ? "42" : 42; +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 41, 36)) + + condition = false; +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 41, 36)) + } + // Error: The loop result must also retain unknown. + const looped: string | number = value; +>looped : Symbol(looped, Decl(negatedComplementFlowNormalization.ts, 72, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 41, 21)) +} + +function predicateFlow(value: unknown) { +>predicateFlow : Symbol(predicateFlow, Decl(negatedComplementFlowNormalization.ts, 73, 1)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 75, 23)) + + if (isFull(value)) { +>isFull : Symbol(isFull, Decl(negatedComplementFlowNormalization.ts, 2, 44)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 75, 23)) + + switch (value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 75, 23)) + + case objectCase: +>objectCase : Symbol(objectCase, Decl(negatedComplementFlowNormalization.ts, 2, 13)) + + const objectValue: object = value; +>objectValue : Symbol(objectValue, Decl(negatedComplementFlowNormalization.ts, 79, 21)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 75, 23)) + + break; + } + } +} + +function assertionFlow(value: unknown) { +>assertionFlow : Symbol(assertionFlow, Decl(negatedComplementFlowNormalization.ts, 83, 1)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + + assertFull(value); +>assertFull : Symbol(assertFull, Decl(negatedComplementFlowNormalization.ts, 3, 55)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + + switch (value) { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + + case objectCase: +>objectCase : Symbol(objectCase, Decl(negatedComplementFlowNormalization.ts, 2, 13)) + + const objectValue: object = value; +>objectValue : Symbol(objectValue, Decl(negatedComplementFlowNormalization.ts, 89, 17)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + + break; + } + assertCondition(value == 42); +>assertCondition : Symbol(assertCondition, Decl(negatedComplementFlowNormalization.ts, 4, 67)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + + if (typeof value === "string") { +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + + // Error: Assertion narrowing must preserve the reachable string branch. + const impossible: never = value; +>impossible : Symbol(impossible, Decl(negatedComplementFlowNormalization.ts, 95, 13)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 85, 23)) + } +} + +function compoundAssertionFlow(value: unknown) { +>compoundAssertionFlow : Symbol(compoundAssertionFlow, Decl(negatedComplementFlowNormalization.ts, 97, 1)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 99, 31)) + + assertCondition(isFull(value) && value == 42 && typeof value === "string"); +>assertCondition : Symbol(assertCondition, Decl(negatedComplementFlowNormalization.ts, 4, 67)) +>isFull : Symbol(isFull, Decl(negatedComplementFlowNormalization.ts, 2, 44)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 99, 31)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 99, 31)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 99, 31)) + + const text: string = value; +>text : Symbol(text, Decl(negatedComplementFlowNormalization.ts, 101, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 99, 31)) + + // Error: Narrowing steps within one assertion must also preserve strings. + const impossible: never = value; +>impossible : Symbol(impossible, Decl(negatedComplementFlowNormalization.ts, 103, 9)) +>value : Symbol(value, Decl(negatedComplementFlowNormalization.ts, 99, 31)) +} + +function evolvingArray(condition: boolean) { +>evolvingArray : Symbol(evolvingArray, Decl(negatedComplementFlowNormalization.ts, 104, 1)) +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 106, 23)) + + const values = []; +>values : Symbol(values, Decl(negatedComplementFlowNormalization.ts, 107, 9)) + + if (condition) { +>condition : Symbol(condition, Decl(negatedComplementFlowNormalization.ts, 106, 23)) + + values.push(42); +>values.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>values : Symbol(values, Decl(negatedComplementFlowNormalization.ts, 107, 9)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + + } else { + values.push("42"); +>values.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>values : Symbol(values, Decl(negatedComplementFlowNormalization.ts, 107, 9)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + } + const result: (string | number)[] = values; +>result : Symbol(result, Decl(negatedComplementFlowNormalization.ts, 113, 9)) +>values : Symbol(values, Decl(negatedComplementFlowNormalization.ts, 107, 9)) + + return result; +>result : Symbol(result, Decl(negatedComplementFlowNormalization.ts, 113, 9)) +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.types b/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.types new file mode 100644 index 0000000000000..eb829eabdc887 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedComplementFlowNormalization.types @@ -0,0 +1,365 @@ +//// [tests/cases/compiler/negatedComplementFlowNormalization.ts] //// + +=== negatedComplementFlowNormalization.ts === +type Full = string | not string; +>Full : unknown + +declare const numericCase: number; +>numericCase : number + +declare const objectCase: { value: string }; +>objectCase : { value: string; } +>value : string + +declare function isFull(value: unknown): value is Full; +>isFull : (value: unknown) => value is Full +>value : unknown + +declare function assertFull(value: unknown): asserts value is Full; +>assertFull : (value: unknown) => asserts value is Full +>value : unknown + +declare function assertCondition(value: unknown): asserts value; +>assertCondition : (value: unknown) => asserts value +>value : unknown + +function complementFlow(value: Full, condition: boolean) { +>complementFlow : (value: Full, condition: boolean) => void +>value : unknown +>condition : boolean + + switch (value) { +>value : unknown + + case numericCase: +>numericCase : number + + const numeric: number = value; +>numeric : number +>value : number + + break; + case objectCase: +>objectCase : { value: string; } + + const objectValue: object = value; +>objectValue : object +>value : object + + break; + } + if (value) { +>value : unknown + + const nonNull: {} = value; +>nonNull : {} +>value : {} + } + if (typeof value === "string") { +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + } + if (typeof value === "object" && value !== null && "value" in value) { +>typeof value === "object" && value !== null && "value" in value : boolean +>typeof value === "object" && value !== null : boolean +>typeof value === "object" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"object" : "object" +>value !== null : boolean +>value : object | null +>"value" in value : boolean +>"value" : "value" +>value : object + + const member: unknown = value.value; +>member : unknown +>value.value : unknown +>value : object & Record<"value", unknown> +>value : unknown + } + value = 42; +>value = 42 : 42 +>value : unknown +>42 : 42 + + // Error: An exhaustive complement behaves like unknown after assignment. + const assigned: number = value; +>assigned : number +>value : unknown + + if (condition) { +>condition : boolean + + value = "42"; +>value = "42" : "42" +>value : unknown +>"42" : "42" + } + // Error: Joining assignments must retain unknown. + const joined: string | number = value; +>joined : string | number +>value : unknown + + while (condition) { +>condition : boolean + + value = condition ? "42" : 42; +>value = condition ? "42" : 42 : "42" | 42 +>value : unknown +>condition ? "42" : 42 : "42" | 42 +>condition : true +>"42" : "42" +>42 : 42 + + condition = false; +>condition = false : false +>condition : boolean +>false : false + } + // Error: The loop result must also retain unknown. + const looped: string | number = value; +>looped : string | number +>value : unknown +} + +function unknownFlow(value: unknown, condition: boolean) { +>unknownFlow : (value: unknown, condition: boolean) => void +>value : unknown +>condition : boolean + + switch (value) { +>value : unknown + + case numericCase: +>numericCase : number + + const numeric: number = value; +>numeric : number +>value : number + + break; + case objectCase: +>objectCase : { value: string; } + + const objectValue: object = value; +>objectValue : object +>value : object + + break; + } + if (value) { +>value : unknown + + const nonNull: {} = value; +>nonNull : {} +>value : {} + } + if (typeof value === "string") { +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + } + if (typeof value === "object" && value !== null && "value" in value) { +>typeof value === "object" && value !== null && "value" in value : boolean +>typeof value === "object" && value !== null : boolean +>typeof value === "object" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"object" : "object" +>value !== null : boolean +>value : object | null +>"value" in value : boolean +>"value" : "value" +>value : object + + const member: unknown = value.value; +>member : unknown +>value.value : unknown +>value : object & Record<"value", unknown> +>value : unknown + } + value = 42; +>value = 42 : 42 +>value : unknown +>42 : 42 + + // Error: Unknown is not assignment-narrowed. + const assigned: number = value; +>assigned : number +>value : unknown + + if (condition) { +>condition : boolean + + value = "42"; +>value = "42" : "42" +>value : unknown +>"42" : "42" + } + // Error: Joining assignments must retain unknown. + const joined: string | number = value; +>joined : string | number +>value : unknown + + while (condition) { +>condition : boolean + + value = condition ? "42" : 42; +>value = condition ? "42" : 42 : "42" | 42 +>value : unknown +>condition ? "42" : 42 : "42" | 42 +>condition : true +>"42" : "42" +>42 : 42 + + condition = false; +>condition = false : false +>condition : boolean +>false : false + } + // Error: The loop result must also retain unknown. + const looped: string | number = value; +>looped : string | number +>value : unknown +} + +function predicateFlow(value: unknown) { +>predicateFlow : (value: unknown) => void +>value : unknown + + if (isFull(value)) { +>isFull(value) : boolean +>isFull : (value: unknown) => value is Full +>value : unknown + + switch (value) { +>value : unknown + + case objectCase: +>objectCase : { value: string; } + + const objectValue: object = value; +>objectValue : object +>value : object + + break; + } + } +} + +function assertionFlow(value: unknown) { +>assertionFlow : (value: unknown) => void +>value : unknown + + assertFull(value); +>assertFull(value) : void +>assertFull : (value: unknown) => asserts value is Full +>value : unknown + + switch (value) { +>value : unknown + + case objectCase: +>objectCase : { value: string; } + + const objectValue: object = value; +>objectValue : object +>value : object + + break; + } + assertCondition(value == 42); +>assertCondition(value == 42) : void +>assertCondition : (value: unknown) => asserts value +>value == 42 : boolean +>value : unknown +>42 : 42 + + if (typeof value === "string") { +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + // Error: Assertion narrowing must preserve the reachable string branch. + const impossible: never = value; +>impossible : never +>value : string + } +} + +function compoundAssertionFlow(value: unknown) { +>compoundAssertionFlow : (value: unknown) => void +>value : unknown + + assertCondition(isFull(value) && value == 42 && typeof value === "string"); +>assertCondition(isFull(value) && value == 42 && typeof value === "string") : void +>assertCondition : (value: unknown) => asserts value +>isFull(value) && value == 42 && typeof value === "string" : boolean +>isFull(value) && value == 42 : boolean +>isFull(value) : boolean +>isFull : (value: unknown) => value is Full +>value : unknown +>value == 42 : boolean +>value : unknown +>42 : 42 +>typeof value === "string" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"string" : "string" + + const text: string = value; +>text : string +>value : string + + // Error: Narrowing steps within one assertion must also preserve strings. + const impossible: never = value; +>impossible : never +>value : string +} + +function evolvingArray(condition: boolean) { +>evolvingArray : (condition: boolean) => (string | number)[] +>condition : boolean + + const values = []; +>values : any[] +>[] : never[] + + if (condition) { +>condition : boolean + + values.push(42); +>values.push(42) : number +>values.push : (...items: any[]) => number +>values : any[] +>push : (...items: any[]) => number +>42 : 42 + + } else { + values.push("42"); +>values.push("42") : number +>values.push : (...items: any[]) => number +>values : any[] +>push : (...items: any[]) => number +>"42" : "42" + } + const result: (string | number)[] = values; +>result : (string | number)[] +>values : (string | number)[] + + return result; +>result : (string | number)[] +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.errors.txt new file mode 100644 index 0000000000000..817a69e655b4d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.errors.txt @@ -0,0 +1,91 @@ +negatedCompoundAssignmentFlow.ts(22,5): error TS2322: Type 'number' is not assignable to type 'number & not 0'. + Type 'number' is not assignable to type 'not 0'. +negatedCompoundAssignmentFlow.ts(48,5): error TS2322: Type 'number' is not assignable to type 'number & not 0'. + Type 'number' is not assignable to type 'not 0'. +negatedCompoundAssignmentFlow.ts(49,5): error TS2322: Type 'number' is not assignable to type 'number & not 0'. + Type 'number' is not assignable to type 'not 0'. +negatedCompoundAssignmentFlow.ts(50,5): error TS2322: Type 'number' is not assignable to type 'number & not 0'. + Type 'number' is not assignable to type 'not 0'. +negatedCompoundAssignmentFlow.ts(62,5): error TS2322: Type 'number' is not assignable to type 'number & not 0'. + Type 'number' is not assignable to type 'not 0'. + + +==== negatedCompoundAssignmentFlow.ts (5 errors) ==== + function compoundFlow(value: number | string) { + if (typeof value === "number" && value !== 0) { + value -= 1; + value; + if (value === 0) { + value; + } + } + } + + function compoundLikeFlow(value: number | string) { + if (typeof value === "number" && value !== 0) { + value = value - 1; + value; + if (value === 0) { + value; + } + } + } + + function constrainedCompoundLikeFlow(value: number & not 0) { + value = value - 1; + ~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'number & not 0'. +!!! error TS2322: Type 'number' is not assignable to type 'not 0'. + value; + } + + function parenthesizedCompound(value: number | undefined) { + if (value !== undefined && value !== 0) { + (value) -= 1; + value! *= 2; + } + } + + function stringCompound(value: string, holder: { value: string }) { + if (value !== "") { + value += "suffix"; + } + if (holder.value !== "") { + holder.value += "suffix"; + holder["value"] += "suffix"; + } + } + + function accessorCompound(holder: { get value(): number & not 0; set value(value: number) }) { + holder.value -= 1; + } + + function constrainedCompound(holder: { value: number & not 0 }, value: number & not 0) { + holder.value -= 1; + ~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'number & not 0'. +!!! error TS2322: Type 'number' is not assignable to type 'not 0'. + holder["value"] -= 1; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'number & not 0'. +!!! error TS2322: Type 'number' is not assignable to type 'not 0'. + (value) -= 1; + ~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'number & not 0'. +!!! error TS2322: Type 'number' is not assignable to type 'not 0'. + } + + function logicalAssignments(value: number | undefined) { + if (value !== 0) { + value ??= 0; + value ||= 1; + value &&= 0; + } + } + + function constrainedLogicalAssignment(value: number & not 0) { + value &&= 0; + ~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'number & not 0'. +!!! error TS2322: Type 'number' is not assignable to type 'not 0'. + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.symbols b/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.symbols new file mode 100644 index 0000000000000..b12740c2fa445 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.symbols @@ -0,0 +1,164 @@ +//// [tests/cases/compiler/negatedCompoundAssignmentFlow.ts] //// + +=== negatedCompoundAssignmentFlow.ts === +function compoundFlow(value: number | string) { +>compoundFlow : Symbol(compoundFlow, Decl(negatedCompoundAssignmentFlow.ts, 0, 0)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) + + if (typeof value === "number" && value !== 0) { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) + + value -= 1; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) + + value; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) + + if (value === 0) { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) + + value; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 0, 22)) + } + } +} + +function compoundLikeFlow(value: number | string) { +>compoundLikeFlow : Symbol(compoundLikeFlow, Decl(negatedCompoundAssignmentFlow.ts, 8, 1)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) + + if (typeof value === "number" && value !== 0) { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) + + value = value - 1; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) + + value; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) + + if (value === 0) { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) + + value; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 10, 26)) + } + } +} + +function constrainedCompoundLikeFlow(value: number & not 0) { +>constrainedCompoundLikeFlow : Symbol(constrainedCompoundLikeFlow, Decl(negatedCompoundAssignmentFlow.ts, 18, 1)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 20, 37)) + + value = value - 1; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 20, 37)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 20, 37)) + + value; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 20, 37)) +} + +function parenthesizedCompound(value: number | undefined) { +>parenthesizedCompound : Symbol(parenthesizedCompound, Decl(negatedCompoundAssignmentFlow.ts, 23, 1)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 25, 31)) + + if (value !== undefined && value !== 0) { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 25, 31)) +>undefined : Symbol(undefined) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 25, 31)) + + (value) -= 1; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 25, 31)) + + value! *= 2; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 25, 31)) + } +} + +function stringCompound(value: string, holder: { value: string }) { +>stringCompound : Symbol(stringCompound, Decl(negatedCompoundAssignmentFlow.ts, 30, 1)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 24)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 32, 38)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 48)) + + if (value !== "") { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 24)) + + value += "suffix"; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 24)) + } + if (holder.value !== "") { +>holder.value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 48)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 32, 38)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 48)) + + holder.value += "suffix"; +>holder.value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 48)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 32, 38)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 48)) + + holder["value"] += "suffix"; +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 32, 38)) +>"value" : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 32, 48)) + } +} + +function accessorCompound(holder: { get value(): number & not 0; set value(value: number) }) { +>accessorCompound : Symbol(accessorCompound, Decl(negatedCompoundAssignmentFlow.ts, 40, 1)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 42, 26)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 42, 35), Decl(negatedCompoundAssignmentFlow.ts, 42, 64)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 42, 35), Decl(negatedCompoundAssignmentFlow.ts, 42, 64)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 42, 75)) + + holder.value -= 1; +>holder.value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 42, 35), Decl(negatedCompoundAssignmentFlow.ts, 42, 64)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 42, 26)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 42, 35), Decl(negatedCompoundAssignmentFlow.ts, 42, 64)) +} + +function constrainedCompound(holder: { value: number & not 0 }, value: number & not 0) { +>constrainedCompound : Symbol(constrainedCompound, Decl(negatedCompoundAssignmentFlow.ts, 44, 1)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 46, 29)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 46, 38)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 46, 63)) + + holder.value -= 1; +>holder.value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 46, 38)) +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 46, 29)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 46, 38)) + + holder["value"] -= 1; +>holder : Symbol(holder, Decl(negatedCompoundAssignmentFlow.ts, 46, 29)) +>"value" : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 46, 38)) + + (value) -= 1; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 46, 63)) +} + +function logicalAssignments(value: number | undefined) { +>logicalAssignments : Symbol(logicalAssignments, Decl(negatedCompoundAssignmentFlow.ts, 50, 1)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 52, 28)) + + if (value !== 0) { +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 52, 28)) + + value ??= 0; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 52, 28)) + + value ||= 1; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 52, 28)) + + value &&= 0; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 52, 28)) + } +} + +function constrainedLogicalAssignment(value: number & not 0) { +>constrainedLogicalAssignment : Symbol(constrainedLogicalAssignment, Decl(negatedCompoundAssignmentFlow.ts, 58, 1)) +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 60, 38)) + + value &&= 0; +>value : Symbol(value, Decl(negatedCompoundAssignmentFlow.ts, 60, 38)) +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.types b/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.types new file mode 100644 index 0000000000000..bed067e237194 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedCompoundAssignmentFlow.types @@ -0,0 +1,229 @@ +//// [tests/cases/compiler/negatedCompoundAssignmentFlow.ts] //// + +=== negatedCompoundAssignmentFlow.ts === +function compoundFlow(value: number | string) { +>compoundFlow : (value: number | string) => void +>value : string | number + + if (typeof value === "number" && value !== 0) { +>typeof value === "number" && value !== 0 : boolean +>typeof value === "number" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : string | number +>"number" : "number" +>value !== 0 : boolean +>value : number +>0 : 0 + + value -= 1; +>value -= 1 : number +>value : number & not 0 +>1 : 1 + + value; +>value : number + + if (value === 0) { +>value === 0 : boolean +>value : number +>0 : 0 + + value; +>value : 0 + } + } +} + +function compoundLikeFlow(value: number | string) { +>compoundLikeFlow : (value: number | string) => void +>value : string | number + + if (typeof value === "number" && value !== 0) { +>typeof value === "number" && value !== 0 : boolean +>typeof value === "number" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : string | number +>"number" : "number" +>value !== 0 : boolean +>value : number +>0 : 0 + + value = value - 1; +>value = value - 1 : number +>value : string | number +>value - 1 : number +>value : number & not 0 +>1 : 1 + + value; +>value : number + + if (value === 0) { +>value === 0 : boolean +>value : number +>0 : 0 + + value; +>value : 0 + } + } +} + +function constrainedCompoundLikeFlow(value: number & not 0) { +>constrainedCompoundLikeFlow : (value: number & not 0) => void +>value : number & not 0 + + value = value - 1; +>value = value - 1 : number +>value : number & not 0 +>value - 1 : number +>value : number & not 0 +>1 : 1 + + value; +>value : number & not 0 +} + +function parenthesizedCompound(value: number | undefined) { +>parenthesizedCompound : (value: number | undefined) => void +>value : number | undefined + + if (value !== undefined && value !== 0) { +>value !== undefined && value !== 0 : boolean +>value !== undefined : boolean +>value : number | undefined +>undefined : undefined +>value !== 0 : boolean +>value : number +>0 : 0 + + (value) -= 1; +>(value) -= 1 : number +>(value) : number & not 0 +>value : number & not 0 +>1 : 1 + + value! *= 2; +>value! *= 2 : number +>value! : number +>value : number +>2 : 2 + } +} + +function stringCompound(value: string, holder: { value: string }) { +>stringCompound : (value: string, holder: { value: string; }) => void +>value : string +>holder : { value: string; } +>value : string + + if (value !== "") { +>value !== "" : boolean +>value : string +>"" : "" + + value += "suffix"; +>value += "suffix" : string +>value : string & not "" +>"suffix" : "suffix" + } + if (holder.value !== "") { +>holder.value !== "" : boolean +>holder.value : string +>holder : { value: string; } +>value : string +>"" : "" + + holder.value += "suffix"; +>holder.value += "suffix" : string +>holder.value : string +>holder : { value: string; } +>value : string +>"suffix" : "suffix" + + holder["value"] += "suffix"; +>holder["value"] += "suffix" : string +>holder["value"] : string +>holder : { value: string; } +>"value" : "value" +>"suffix" : "suffix" + } +} + +function accessorCompound(holder: { get value(): number & not 0; set value(value: number) }) { +>accessorCompound : (holder: { get value(): number & not 0; set value(value: number); }) => void +>holder : { get value(): number & not 0; set value(value: number); } +>value : number & not 0 +>value : number & not 0 +>value : number + + holder.value -= 1; +>holder.value -= 1 : number +>holder.value : number & not 0 +>holder : { get value(): number & not 0; set value(value: number); } +>value : number & not 0 +>1 : 1 +} + +function constrainedCompound(holder: { value: number & not 0 }, value: number & not 0) { +>constrainedCompound : (holder: { value: number & not 0; }, value: number & not 0) => void +>holder : { value: number & not 0; } +>value : number & not 0 +>value : number & not 0 + + holder.value -= 1; +>holder.value -= 1 : number +>holder.value : number & not 0 +>holder : { value: number & not 0; } +>value : number & not 0 +>1 : 1 + + holder["value"] -= 1; +>holder["value"] -= 1 : number +>holder["value"] : number & not 0 +>holder : { value: number & not 0; } +>"value" : "value" +>1 : 1 + + (value) -= 1; +>(value) -= 1 : number +>(value) : number & not 0 +>value : number & not 0 +>1 : 1 +} + +function logicalAssignments(value: number | undefined) { +>logicalAssignments : (value: number | undefined) => void +>value : number | undefined + + if (value !== 0) { +>value !== 0 : boolean +>value : number | undefined +>0 : 0 + + value ??= 0; +>value ??= 0 : number +>value : number | undefined +>0 : 0 + + value ||= 1; +>value ||= 1 : number +>value : number | undefined +>1 : 1 + + value &&= 0; +>value &&= 0 : 0 | undefined +>value : number | undefined +>0 : 0 + } +} + +function constrainedLogicalAssignment(value: number & not 0) { +>constrainedLogicalAssignment : (value: number & not 0) => void +>value : number & not 0 + + value &&= 0; +>value &&= 0 : 0 +>value : number & not 0 +>0 : 0 +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.errors.txt new file mode 100644 index 0000000000000..5f282675034a1 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.errors.txt @@ -0,0 +1,82 @@ +negatedDoubleExclusion.ts(9,42): error TS2322: Type '"b"' is not assignable to type '"a"'. +negatedDoubleExclusion.ts(9,53): error TS2322: Type '1' is not assignable to type '0'. +negatedDoubleExclusion.ts(10,54): error TS2322: Type '0' is not assignable to type '1'. +negatedDoubleExclusion.ts(21,7): error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type 'Allowed'. + Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; } & not Blocked'. + Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; }'. + Types of property 'kind' are incompatible. + Type '"a" | "b"' is not assignable to type '"b"'. + Type '"a"' is not assignable to type '"b"'. +negatedDoubleExclusion.ts(28,7): error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "a"; } | ({ kind: "b"; } & not Blocked)'. + Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; } & not Blocked'. + Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; }'. + Types of property 'kind' are incompatible. + Type '"a" | "b"' is not assignable to type '"b"'. + Type '"a"' is not assignable to type '"b"'. +negatedDoubleExclusion.ts(33,11): error TS2322: Type '{ kind: "a"; value: 0; }' is not assignable to type 'Difference'. + Type '{ kind: "a"; value: 0; }' is not assignable to type '{ kind: "a"; value: 0; } & not { kind: Kind; }'. + Type '{ kind: "a"; value: 0; }' is not assignable to type 'not { kind: Kind; }'. + + +==== negatedDoubleExclusion.ts (6 errors) ==== + type Difference = T & not U; + type Product = { kind: "a"; value: 0 } | { kind: "b"; value: 1 }; + type DoubleExcluded = { + [Kind in Product["kind"]]: Difference>; + }; + const productA: DoubleExcluded["a"] = { kind: "a", value: 0 }; + const productB: DoubleExcluded["b"] = { kind: "b", value: 1 }; + + const wrongKind: DoubleExcluded["a"] = { kind: "b", value: 1 }; + ~~~~ +!!! error TS2322: Type '"b"' is not assignable to type '"a"'. +!!! related TS6500 negatedDoubleExclusion.ts:2:18: The expected type comes from property 'kind' which is declared here on type '{ kind: "a"; value: 0; }' + ~~~~~ +!!! error TS2322: Type '1' is not assignable to type '0'. +!!! related TS6500 negatedDoubleExclusion.ts:2:29: The expected type comes from property 'value' which is declared here on type '{ kind: "a"; value: 0; }' + const wrongValue: DoubleExcluded["b"] = { kind: "b", value: 0 }; + ~~~~~ +!!! error TS2322: Type '0' is not assignable to type '1'. +!!! related TS6500 negatedDoubleExclusion.ts:2:55: The expected type comes from property 'value' which is declared here on type '{ kind: "b"; value: 1; }' + + type Selected = Difference>; + const selectedA: Selected<"a"> = productA; + const selectedB: Selected<"b"> = productB; + const selectedBoth: Selected<"a" | "b"> = productA; + + type Tagged = { kind: "a" } | { kind: "b" }; + interface Blocked { blocked: true; } + type Allowed = Difference; + declare const excluded: { kind: "a" | "b"; blocked: true }; + const rejected: Allowed = excluded; + ~~~~~~~~ +!!! error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type 'Allowed'. +!!! error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; } & not Blocked'. +!!! error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; }'. +!!! error TS2322: Types of property 'kind' are incompatible. +!!! error TS2322: Type '"a" | "b"' is not assignable to type '"b"'. +!!! error TS2322: Type '"a"' is not assignable to type '"b"'. + + declare const allowed: { kind: "a" | "b" } & not Blocked; + const accepted: Allowed = allowed; + + declare const ordinary: { kind: "a" | "b" }; + const plain: Tagged = ordinary; + const partiallyExcluded: (Tagged & not Blocked) | { kind: "a" } = excluded; + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "a"; } | ({ kind: "b"; } & not Blocked)'. +!!! error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; } & not Blocked'. +!!! error TS2322: Type '{ kind: "a" | "b"; blocked: true; }' is not assignable to type '{ kind: "b"; }'. +!!! error TS2322: Types of property 'kind' are incompatible. +!!! error TS2322: Type '"a" | "b"' is not assignable to type '"b"'. +!!! error TS2322: Type '"a"' is not assignable to type '"b"'. + declare const alternative: { kind: "a"; blocked: true }; + const acceptedAlternative: (Tagged & not Blocked) | { kind: "a" } = alternative; + + function generic(value: { kind: "a"; value: 0 }) { + const rejected: Difference = value; + ~~~~~~~~ +!!! error TS2322: Type '{ kind: "a"; value: 0; }' is not assignable to type 'Difference'. +!!! error TS2322: Type '{ kind: "a"; value: 0; }' is not assignable to type '{ kind: "a"; value: 0; } & not { kind: Kind; }'. +!!! error TS2322: Type '{ kind: "a"; value: 0; }' is not assignable to type 'not { kind: Kind; }'. + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.symbols b/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.symbols new file mode 100644 index 0000000000000..5babc4f8eaf1f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.symbols @@ -0,0 +1,159 @@ +//// [tests/cases/compiler/negatedDoubleExclusion.ts] //// + +=== negatedDoubleExclusion.ts === +type Difference = T & not U; +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>T : Symbol(T, Decl(negatedDoubleExclusion.ts, 0, 16)) +>U : Symbol(U, Decl(negatedDoubleExclusion.ts, 0, 18)) +>T : Symbol(T, Decl(negatedDoubleExclusion.ts, 0, 16)) +>U : Symbol(U, Decl(negatedDoubleExclusion.ts, 0, 18)) + +type Product = { kind: "a"; value: 0 } | { kind: "b"; value: 1 }; +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 1, 16)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 1, 27)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 1, 42)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 1, 53)) + +type DoubleExcluded = { +>DoubleExcluded : Symbol(DoubleExcluded, Decl(negatedDoubleExclusion.ts, 1, 65)) + + [Kind in Product["kind"]]: Difference>; +>Kind : Symbol(Kind, Decl(negatedDoubleExclusion.ts, 3, 5)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 3, 72)) +>Kind : Symbol(Kind, Decl(negatedDoubleExclusion.ts, 3, 5)) + +}; +const productA: DoubleExcluded["a"] = { kind: "a", value: 0 }; +>productA : Symbol(productA, Decl(negatedDoubleExclusion.ts, 5, 5)) +>DoubleExcluded : Symbol(DoubleExcluded, Decl(negatedDoubleExclusion.ts, 1, 65)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 5, 39)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 5, 50)) + +const productB: DoubleExcluded["b"] = { kind: "b", value: 1 }; +>productB : Symbol(productB, Decl(negatedDoubleExclusion.ts, 6, 5)) +>DoubleExcluded : Symbol(DoubleExcluded, Decl(negatedDoubleExclusion.ts, 1, 65)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 6, 39)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 6, 50)) + +const wrongKind: DoubleExcluded["a"] = { kind: "b", value: 1 }; +>wrongKind : Symbol(wrongKind, Decl(negatedDoubleExclusion.ts, 8, 5)) +>DoubleExcluded : Symbol(DoubleExcluded, Decl(negatedDoubleExclusion.ts, 1, 65)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 8, 40)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 8, 51)) + +const wrongValue: DoubleExcluded["b"] = { kind: "b", value: 0 }; +>wrongValue : Symbol(wrongValue, Decl(negatedDoubleExclusion.ts, 9, 5)) +>DoubleExcluded : Symbol(DoubleExcluded, Decl(negatedDoubleExclusion.ts, 1, 65)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 9, 41)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 9, 52)) + +type Selected = Difference>; +>Selected : Symbol(Selected, Decl(negatedDoubleExclusion.ts, 9, 64)) +>Kind : Symbol(Kind, Decl(negatedDoubleExclusion.ts, 11, 14)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 11, 87)) +>Kind : Symbol(Kind, Decl(negatedDoubleExclusion.ts, 11, 14)) + +const selectedA: Selected<"a"> = productA; +>selectedA : Symbol(selectedA, Decl(negatedDoubleExclusion.ts, 12, 5)) +>Selected : Symbol(Selected, Decl(negatedDoubleExclusion.ts, 9, 64)) +>productA : Symbol(productA, Decl(negatedDoubleExclusion.ts, 5, 5)) + +const selectedB: Selected<"b"> = productB; +>selectedB : Symbol(selectedB, Decl(negatedDoubleExclusion.ts, 13, 5)) +>Selected : Symbol(Selected, Decl(negatedDoubleExclusion.ts, 9, 64)) +>productB : Symbol(productB, Decl(negatedDoubleExclusion.ts, 6, 5)) + +const selectedBoth: Selected<"a" | "b"> = productA; +>selectedBoth : Symbol(selectedBoth, Decl(negatedDoubleExclusion.ts, 14, 5)) +>Selected : Symbol(Selected, Decl(negatedDoubleExclusion.ts, 9, 64)) +>productA : Symbol(productA, Decl(negatedDoubleExclusion.ts, 5, 5)) + +type Tagged = { kind: "a" } | { kind: "b" }; +>Tagged : Symbol(Tagged, Decl(negatedDoubleExclusion.ts, 14, 51)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 16, 15)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 16, 31)) + +interface Blocked { blocked: true; } +>Blocked : Symbol(Blocked, Decl(negatedDoubleExclusion.ts, 16, 44)) +>blocked : Symbol(Blocked.blocked, Decl(negatedDoubleExclusion.ts, 17, 19)) + +type Allowed = Difference; +>Allowed : Symbol(Allowed, Decl(negatedDoubleExclusion.ts, 17, 36)) +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>Tagged : Symbol(Tagged, Decl(negatedDoubleExclusion.ts, 14, 51)) +>Blocked : Symbol(Blocked, Decl(negatedDoubleExclusion.ts, 16, 44)) + +declare const excluded: { kind: "a" | "b"; blocked: true }; +>excluded : Symbol(excluded, Decl(negatedDoubleExclusion.ts, 19, 13)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 19, 25)) +>blocked : Symbol(blocked, Decl(negatedDoubleExclusion.ts, 19, 42)) + +const rejected: Allowed = excluded; +>rejected : Symbol(rejected, Decl(negatedDoubleExclusion.ts, 20, 5)) +>Allowed : Symbol(Allowed, Decl(negatedDoubleExclusion.ts, 17, 36)) +>excluded : Symbol(excluded, Decl(negatedDoubleExclusion.ts, 19, 13)) + +declare const allowed: { kind: "a" | "b" } & not Blocked; +>allowed : Symbol(allowed, Decl(negatedDoubleExclusion.ts, 22, 13)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 22, 24)) +>Blocked : Symbol(Blocked, Decl(negatedDoubleExclusion.ts, 16, 44)) + +const accepted: Allowed = allowed; +>accepted : Symbol(accepted, Decl(negatedDoubleExclusion.ts, 23, 5)) +>Allowed : Symbol(Allowed, Decl(negatedDoubleExclusion.ts, 17, 36)) +>allowed : Symbol(allowed, Decl(negatedDoubleExclusion.ts, 22, 13)) + +declare const ordinary: { kind: "a" | "b" }; +>ordinary : Symbol(ordinary, Decl(negatedDoubleExclusion.ts, 25, 13)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 25, 25)) + +const plain: Tagged = ordinary; +>plain : Symbol(plain, Decl(negatedDoubleExclusion.ts, 26, 5)) +>Tagged : Symbol(Tagged, Decl(negatedDoubleExclusion.ts, 14, 51)) +>ordinary : Symbol(ordinary, Decl(negatedDoubleExclusion.ts, 25, 13)) + +const partiallyExcluded: (Tagged & not Blocked) | { kind: "a" } = excluded; +>partiallyExcluded : Symbol(partiallyExcluded, Decl(negatedDoubleExclusion.ts, 27, 5)) +>Tagged : Symbol(Tagged, Decl(negatedDoubleExclusion.ts, 14, 51)) +>Blocked : Symbol(Blocked, Decl(negatedDoubleExclusion.ts, 16, 44)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 27, 51)) +>excluded : Symbol(excluded, Decl(negatedDoubleExclusion.ts, 19, 13)) + +declare const alternative: { kind: "a"; blocked: true }; +>alternative : Symbol(alternative, Decl(negatedDoubleExclusion.ts, 28, 13)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 28, 28)) +>blocked : Symbol(blocked, Decl(negatedDoubleExclusion.ts, 28, 39)) + +const acceptedAlternative: (Tagged & not Blocked) | { kind: "a" } = alternative; +>acceptedAlternative : Symbol(acceptedAlternative, Decl(negatedDoubleExclusion.ts, 29, 5)) +>Tagged : Symbol(Tagged, Decl(negatedDoubleExclusion.ts, 14, 51)) +>Blocked : Symbol(Blocked, Decl(negatedDoubleExclusion.ts, 16, 44)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 29, 53)) +>alternative : Symbol(alternative, Decl(negatedDoubleExclusion.ts, 28, 13)) + +function generic(value: { kind: "a"; value: 0 }) { +>generic : Symbol(generic, Decl(negatedDoubleExclusion.ts, 29, 80)) +>Kind : Symbol(Kind, Decl(negatedDoubleExclusion.ts, 31, 17)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 31, 41)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 31, 49)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 31, 60)) + + const rejected: Difference = value; +>rejected : Symbol(rejected, Decl(negatedDoubleExclusion.ts, 32, 9)) +>Difference : Symbol(Difference, Decl(negatedDoubleExclusion.ts, 0, 0)) +>Product : Symbol(Product, Decl(negatedDoubleExclusion.ts, 0, 34)) +>kind : Symbol(kind, Decl(negatedDoubleExclusion.ts, 32, 41)) +>Kind : Symbol(Kind, Decl(negatedDoubleExclusion.ts, 31, 17)) +>value : Symbol(value, Decl(negatedDoubleExclusion.ts, 31, 41)) +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.types b/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.types new file mode 100644 index 0000000000000..1f5046712c3c0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedDoubleExclusion.types @@ -0,0 +1,133 @@ +//// [tests/cases/compiler/negatedDoubleExclusion.ts] //// + +=== negatedDoubleExclusion.ts === +type Difference = T & not U; +>Difference : Difference + +type Product = { kind: "a"; value: 0 } | { kind: "b"; value: 1 }; +>Product : Product +>kind : "a" +>value : 0 +>kind : "b" +>value : 1 + +type DoubleExcluded = { +>DoubleExcluded : DoubleExcluded + + [Kind in Product["kind"]]: Difference>; +>kind : Kind + +}; +const productA: DoubleExcluded["a"] = { kind: "a", value: 0 }; +>productA : { kind: "a"; value: 0; } +>{ kind: "a", value: 0 } : { kind: "a"; value: 0; } +>kind : "a" +>"a" : "a" +>value : 0 +>0 : 0 + +const productB: DoubleExcluded["b"] = { kind: "b", value: 1 }; +>productB : { kind: "b"; value: 1; } +>{ kind: "b", value: 1 } : { kind: "b"; value: 1; } +>kind : "b" +>"b" : "b" +>value : 1 +>1 : 1 + +const wrongKind: DoubleExcluded["a"] = { kind: "b", value: 1 }; +>wrongKind : { kind: "a"; value: 0; } +>{ kind: "b", value: 1 } : { kind: "b"; value: 1; } +>kind : "b" +>"b" : "b" +>value : 1 +>1 : 1 + +const wrongValue: DoubleExcluded["b"] = { kind: "b", value: 0 }; +>wrongValue : { kind: "b"; value: 1; } +>{ kind: "b", value: 0 } : { kind: "b"; value: 0; } +>kind : "b" +>"b" : "b" +>value : 0 +>0 : 0 + +type Selected = Difference>; +>Selected : Selected +>kind : Kind + +const selectedA: Selected<"a"> = productA; +>selectedA : { kind: "a"; value: 0; } +>productA : { kind: "a"; value: 0; } + +const selectedB: Selected<"b"> = productB; +>selectedB : { kind: "b"; value: 1; } +>productB : { kind: "b"; value: 1; } + +const selectedBoth: Selected<"a" | "b"> = productA; +>selectedBoth : Product +>productA : { kind: "a"; value: 0; } + +type Tagged = { kind: "a" } | { kind: "b" }; +>Tagged : Tagged +>kind : "a" +>kind : "b" + +interface Blocked { blocked: true; } +>blocked : true +>true : true + +type Allowed = Difference; +>Allowed : Allowed + +declare const excluded: { kind: "a" | "b"; blocked: true }; +>excluded : { kind: "a" | "b"; blocked: true; } +>kind : "a" | "b" +>blocked : true +>true : true + +const rejected: Allowed = excluded; +>rejected : Allowed +>excluded : { kind: "a" | "b"; blocked: true; } + +declare const allowed: { kind: "a" | "b" } & not Blocked; +>allowed : { kind: "a" | "b"; } & not Blocked +>kind : "a" | "b" + +const accepted: Allowed = allowed; +>accepted : Allowed +>allowed : { kind: "a" | "b"; } & not Blocked + +declare const ordinary: { kind: "a" | "b" }; +>ordinary : { kind: "a" | "b"; } +>kind : "a" | "b" + +const plain: Tagged = ordinary; +>plain : Tagged +>ordinary : { kind: "a" | "b"; } + +const partiallyExcluded: (Tagged & not Blocked) | { kind: "a" } = excluded; +>partiallyExcluded : { kind: "a"; } | ({ kind: "b"; } & not Blocked) +>kind : "a" +>excluded : { kind: "a" | "b"; blocked: true; } + +declare const alternative: { kind: "a"; blocked: true }; +>alternative : { kind: "a"; blocked: true; } +>kind : "a" +>blocked : true +>true : true + +const acceptedAlternative: (Tagged & not Blocked) | { kind: "a" } = alternative; +>acceptedAlternative : { kind: "a"; } | ({ kind: "b"; } & not Blocked) +>kind : "a" +>alternative : { kind: "a"; blocked: true; } + +function generic(value: { kind: "a"; value: 0 }) { +>generic : (value: { kind: "a"; value: 0; }) => void +>value : { kind: "a"; value: 0; } +>kind : "a" +>value : 0 + + const rejected: Difference = value; +>rejected : Difference +>kind : Kind +>value : { kind: "a"; value: 0; } +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedGenericForIn.symbols b/tsc/testdata/baselines/reference/compiler/negatedGenericForIn.symbols new file mode 100644 index 0000000000000..8ce8aa8f98767 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedGenericForIn.symbols @@ -0,0 +1,77 @@ +//// [tests/cases/compiler/negatedGenericForIn.ts] //// + +=== negatedGenericForIn.ts === +interface NodeBase { +>NodeBase : Symbol(NodeBase, Decl(negatedGenericForIn.ts, 0, 0)) + + kind: number; +>kind : Symbol(NodeBase.kind, Decl(negatedGenericForIn.ts, 0, 20)) +} + +interface NamedNode extends NodeBase { +>NamedNode : Symbol(NamedNode, Decl(negatedGenericForIn.ts, 2, 1)) +>NodeBase : Symbol(NodeBase, Decl(negatedGenericForIn.ts, 0, 0)) + + name: string; +>name : Symbol(NamedNode.name, Decl(negatedGenericForIn.ts, 4, 38)) +} + +declare function isNamedNode(node: NodeBase): node is NamedNode; +>isNamedNode : Symbol(isNamedNode, Decl(negatedGenericForIn.ts, 6, 1)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 8, 29)) +>NodeBase : Symbol(NodeBase, Decl(negatedGenericForIn.ts, 0, 0)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 8, 29)) +>NamedNode : Symbol(NamedNode, Decl(negatedGenericForIn.ts, 2, 1)) + +function copyNodeProperties(node: NodeType, clone: NodeType) { +>copyNodeProperties : Symbol(copyNodeProperties, Decl(negatedGenericForIn.ts, 8, 64)) +>NodeType : Symbol(NodeType, Decl(negatedGenericForIn.ts, 10, 28)) +>NodeBase : Symbol(NodeBase, Decl(negatedGenericForIn.ts, 0, 0)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 10, 55)) +>NodeType : Symbol(NodeType, Decl(negatedGenericForIn.ts, 10, 28)) +>clone : Symbol(clone, Decl(negatedGenericForIn.ts, 10, 70)) +>NodeType : Symbol(NodeType, Decl(negatedGenericForIn.ts, 10, 28)) + + if (isNamedNode(node)) { +>isNamedNode : Symbol(isNamedNode, Decl(negatedGenericForIn.ts, 6, 1)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 10, 55)) + + return; + } + for (const key in node) { +>key : Symbol(key, Decl(negatedGenericForIn.ts, 14, 14)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 10, 55)) + + clone[key] = node[key]; +>clone : Symbol(clone, Decl(negatedGenericForIn.ts, 10, 70)) +>key : Symbol(key, Decl(negatedGenericForIn.ts, 14, 14)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 10, 55)) +>key : Symbol(key, Decl(negatedGenericForIn.ts, 14, 14)) + } +} + +function copyNonCallableProperties(node: NodeType, clone: NodeType) { +>copyNonCallableProperties : Symbol(copyNonCallableProperties, Decl(negatedGenericForIn.ts, 17, 1)) +>NodeType : Symbol(NodeType, Decl(negatedGenericForIn.ts, 19, 35)) +>NodeBase : Symbol(NodeBase, Decl(negatedGenericForIn.ts, 0, 0)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 19, 62)) +>NodeType : Symbol(NodeType, Decl(negatedGenericForIn.ts, 19, 35)) +>clone : Symbol(clone, Decl(negatedGenericForIn.ts, 19, 77)) +>NodeType : Symbol(NodeType, Decl(negatedGenericForIn.ts, 19, 35)) + + if (typeof node === "function") { +>node : Symbol(node, Decl(negatedGenericForIn.ts, 19, 62)) + + return; + } + for (const key in node) { +>key : Symbol(key, Decl(negatedGenericForIn.ts, 23, 14)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 19, 62)) + + clone[key] = node[key]; +>clone : Symbol(clone, Decl(negatedGenericForIn.ts, 19, 77)) +>key : Symbol(key, Decl(negatedGenericForIn.ts, 23, 14)) +>node : Symbol(node, Decl(negatedGenericForIn.ts, 19, 62)) +>key : Symbol(key, Decl(negatedGenericForIn.ts, 23, 14)) + } +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedGenericForIn.types b/tsc/testdata/baselines/reference/compiler/negatedGenericForIn.types new file mode 100644 index 0000000000000..e9231b3a10966 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedGenericForIn.types @@ -0,0 +1,71 @@ +//// [tests/cases/compiler/negatedGenericForIn.ts] //// + +=== negatedGenericForIn.ts === +interface NodeBase { + kind: number; +>kind : number +} + +interface NamedNode extends NodeBase { + name: string; +>name : string +} + +declare function isNamedNode(node: NodeBase): node is NamedNode; +>isNamedNode : (node: NodeBase) => node is NamedNode +>node : NodeBase + +function copyNodeProperties(node: NodeType, clone: NodeType) { +>copyNodeProperties : (node: NodeType, clone: NodeType) => void +>node : NodeType +>clone : NodeType + + if (isNamedNode(node)) { +>isNamedNode(node) : boolean +>isNamedNode : (node: NodeBase) => node is NamedNode +>node : NodeType + + return; + } + for (const key in node) { +>key : Extract +>node : NodeType + + clone[key] = node[key]; +>clone[key] = node[key] : NodeType[Extract] +>clone[key] : NodeType[Extract] +>clone : NodeType +>key : Extract +>node[key] : NodeType[Extract] +>node : NodeType +>key : Extract + } +} + +function copyNonCallableProperties(node: NodeType, clone: NodeType) { +>copyNonCallableProperties : (node: NodeType, clone: NodeType) => void +>node : NodeType +>clone : NodeType + + if (typeof node === "function") { +>typeof node === "function" : boolean +>typeof node : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>node : NodeType +>"function" : "function" + + return; + } + for (const key in node) { +>key : Extract +>node : NodeType + + clone[key] = node[key]; +>clone[key] = node[key] : NodeType[Extract] +>clone[key] : NodeType[Extract] +>clone : NodeType +>key : Extract +>node[key] : NodeType[Extract] +>node : NodeType +>key : Extract + } +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.errors.txt new file mode 100644 index 0000000000000..8deab7006876d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.errors.txt @@ -0,0 +1,39 @@ +negatedKeyConstraintIndexing.ts(33,32): error TS2345: Argument of type 'unique symbol' is not assignable to parameter of type 'never'. + + +==== negatedKeyConstraintIndexing.ts (1 errors) ==== + type StringNumberKeys = keyof T & not symbol; + type MyExclude = T & not U; + + function readAlias(key: MyExclude, values: { [key: string]: boolean }, stringKey: string, numberKey: number) { + const stringResult = values[stringKey]; + const numberResult = values[numberKey]; + const result = values[key]; + return result; + } + + function readAliasConstrained>(key: Key, values: { [key: string]: boolean }) { + const result: boolean = values[key]; + return result; + } + + function read(key: StringNumberKeys, values: { [key: string]: boolean }) { + const result: boolean = values[key]; + return result; + } + + function readConstrained>(key: Key, values: { [key: string]: boolean }) { + const result: boolean = values[key]; + return result; + } + + function readStringOnly(key: keyof T & not number & not symbol, values: { [key: string]: boolean }) { + const result: boolean = values[key]; + return result; + } + + declare const symbolKey: unique symbol; + // Error: Symbol keys are excluded. + read<{ [symbolKey]: boolean }>(symbolKey, {}); + ~~~~~~~~~ +!!! error TS2345: Argument of type 'unique symbol' is not assignable to parameter of type 'never'. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.symbols b/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.symbols new file mode 100644 index 0000000000000..3e0c0d922c1b6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.symbols @@ -0,0 +1,130 @@ +//// [tests/cases/compiler/negatedKeyConstraintIndexing.ts] //// + +=== negatedKeyConstraintIndexing.ts === +type StringNumberKeys = keyof T & not symbol; +>StringNumberKeys : Symbol(StringNumberKeys, Decl(negatedKeyConstraintIndexing.ts, 0, 0)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 0, 22)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 0, 22)) + +type MyExclude = T & not U; +>MyExclude : Symbol(MyExclude, Decl(negatedKeyConstraintIndexing.ts, 0, 48)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 1, 15)) +>U : Symbol(U, Decl(negatedKeyConstraintIndexing.ts, 1, 17)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 1, 15)) +>U : Symbol(U, Decl(negatedKeyConstraintIndexing.ts, 1, 17)) + +function readAlias(key: MyExclude, values: { [key: string]: boolean }, stringKey: string, numberKey: number) { +>readAlias : Symbol(readAlias, Decl(negatedKeyConstraintIndexing.ts, 1, 33)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 3, 19)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 3, 22)) +>MyExclude : Symbol(MyExclude, Decl(negatedKeyConstraintIndexing.ts, 0, 48)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 3, 19)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 3, 54)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 3, 66)) +>stringKey : Symbol(stringKey, Decl(negatedKeyConstraintIndexing.ts, 3, 90)) +>numberKey : Symbol(numberKey, Decl(negatedKeyConstraintIndexing.ts, 3, 109)) + + const stringResult = values[stringKey]; +>stringResult : Symbol(stringResult, Decl(negatedKeyConstraintIndexing.ts, 4, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 3, 54)) +>stringKey : Symbol(stringKey, Decl(negatedKeyConstraintIndexing.ts, 3, 90)) + + const numberResult = values[numberKey]; +>numberResult : Symbol(numberResult, Decl(negatedKeyConstraintIndexing.ts, 5, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 3, 54)) +>numberKey : Symbol(numberKey, Decl(negatedKeyConstraintIndexing.ts, 3, 109)) + + const result = values[key]; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 6, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 3, 54)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 3, 22)) + + return result; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 6, 9)) +} + +function readAliasConstrained>(key: Key, values: { [key: string]: boolean }) { +>readAliasConstrained : Symbol(readAliasConstrained, Decl(negatedKeyConstraintIndexing.ts, 8, 1)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 10, 30)) +>Key : Symbol(Key, Decl(negatedKeyConstraintIndexing.ts, 10, 32)) +>MyExclude : Symbol(MyExclude, Decl(negatedKeyConstraintIndexing.ts, 0, 48)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 10, 30)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 10, 73)) +>Key : Symbol(Key, Decl(negatedKeyConstraintIndexing.ts, 10, 32)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 10, 82)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 10, 94)) + + const result: boolean = values[key]; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 11, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 10, 82)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 10, 73)) + + return result; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 11, 9)) +} + +function read(key: StringNumberKeys, values: { [key: string]: boolean }) { +>read : Symbol(read, Decl(negatedKeyConstraintIndexing.ts, 13, 1)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 15, 14)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 15, 17)) +>StringNumberKeys : Symbol(StringNumberKeys, Decl(negatedKeyConstraintIndexing.ts, 0, 0)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 15, 14)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 15, 42)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 15, 54)) + + const result: boolean = values[key]; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 16, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 15, 42)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 15, 17)) + + return result; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 16, 9)) +} + +function readConstrained>(key: Key, values: { [key: string]: boolean }) { +>readConstrained : Symbol(readConstrained, Decl(negatedKeyConstraintIndexing.ts, 18, 1)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 20, 25)) +>Key : Symbol(Key, Decl(negatedKeyConstraintIndexing.ts, 20, 27)) +>StringNumberKeys : Symbol(StringNumberKeys, Decl(negatedKeyConstraintIndexing.ts, 0, 0)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 20, 25)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 20, 61)) +>Key : Symbol(Key, Decl(negatedKeyConstraintIndexing.ts, 20, 27)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 20, 70)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 20, 82)) + + const result: boolean = values[key]; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 21, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 20, 70)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 20, 61)) + + return result; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 21, 9)) +} + +function readStringOnly(key: keyof T & not number & not symbol, values: { [key: string]: boolean }) { +>readStringOnly : Symbol(readStringOnly, Decl(negatedKeyConstraintIndexing.ts, 23, 1)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 25, 24)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 25, 27)) +>T : Symbol(T, Decl(negatedKeyConstraintIndexing.ts, 25, 24)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 25, 66)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 25, 78)) + + const result: boolean = values[key]; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 26, 9)) +>values : Symbol(values, Decl(negatedKeyConstraintIndexing.ts, 25, 66)) +>key : Symbol(key, Decl(negatedKeyConstraintIndexing.ts, 25, 27)) + + return result; +>result : Symbol(result, Decl(negatedKeyConstraintIndexing.ts, 26, 9)) +} + +declare const symbolKey: unique symbol; +>symbolKey : Symbol(symbolKey, Decl(negatedKeyConstraintIndexing.ts, 30, 13)) + +// Error: Symbol keys are excluded. +read<{ [symbolKey]: boolean }>(symbolKey, {}); +>read : Symbol(read, Decl(negatedKeyConstraintIndexing.ts, 13, 1)) +>[symbolKey] : Symbol([symbolKey], Decl(negatedKeyConstraintIndexing.ts, 32, 6)) +>symbolKey : Symbol(symbolKey, Decl(negatedKeyConstraintIndexing.ts, 30, 13)) +>symbolKey : Symbol(symbolKey, Decl(negatedKeyConstraintIndexing.ts, 30, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.types b/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.types new file mode 100644 index 0000000000000..13ba01a63d45f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedKeyConstraintIndexing.types @@ -0,0 +1,115 @@ +//// [tests/cases/compiler/negatedKeyConstraintIndexing.ts] //// + +=== negatedKeyConstraintIndexing.ts === +type StringNumberKeys = keyof T & not symbol; +>StringNumberKeys : StringNumberKeys + +type MyExclude = T & not U; +>MyExclude : MyExclude + +function readAlias(key: MyExclude, values: { [key: string]: boolean }, stringKey: string, numberKey: number) { +>readAlias : (key: MyExclude, values: { [key: string]: boolean; }, stringKey: string, numberKey: number) => { [key: string]: boolean; }[MyExclude] +>key : MyExclude +>values : { [key: string]: boolean; } +>key : string +>stringKey : string +>numberKey : number + + const stringResult = values[stringKey]; +>stringResult : boolean +>values[stringKey] : boolean +>values : { [key: string]: boolean; } +>stringKey : string + + const numberResult = values[numberKey]; +>numberResult : boolean +>values[numberKey] : boolean +>values : { [key: string]: boolean; } +>numberKey : number + + const result = values[key]; +>result : { [key: string]: boolean; }[MyExclude] +>values[key] : { [key: string]: boolean; }[MyExclude] +>values : { [key: string]: boolean; } +>key : MyExclude + + return result; +>result : { [key: string]: boolean; }[MyExclude] +} + +function readAliasConstrained>(key: Key, values: { [key: string]: boolean }) { +>readAliasConstrained : >(key: Key, values: { [key: string]: boolean; }) => boolean +>key : Key +>values : { [key: string]: boolean; } +>key : string + + const result: boolean = values[key]; +>result : boolean +>values[key] : boolean +>values : { [key: string]: boolean; } +>key : Key + + return result; +>result : boolean +} + +function read(key: StringNumberKeys, values: { [key: string]: boolean }) { +>read : (key: StringNumberKeys, values: { [key: string]: boolean; }) => boolean +>key : StringNumberKeys +>values : { [key: string]: boolean; } +>key : string + + const result: boolean = values[key]; +>result : boolean +>values[key] : boolean +>values : { [key: string]: boolean; } +>key : StringNumberKeys + + return result; +>result : boolean +} + +function readConstrained>(key: Key, values: { [key: string]: boolean }) { +>readConstrained : >(key: Key, values: { [key: string]: boolean; }) => boolean +>key : Key +>values : { [key: string]: boolean; } +>key : string + + const result: boolean = values[key]; +>result : boolean +>values[key] : boolean +>values : { [key: string]: boolean; } +>key : Key + + return result; +>result : boolean +} + +function readStringOnly(key: keyof T & not number & not symbol, values: { [key: string]: boolean }) { +>readStringOnly : (key: keyof T & not number & not symbol, values: { [key: string]: boolean; }) => boolean +>key : keyof T & not number & not symbol +>values : { [key: string]: boolean; } +>key : string + + const result: boolean = values[key]; +>result : boolean +>values[key] : boolean +>values : { [key: string]: boolean; } +>key : keyof T & not number & not symbol + + return result; +>result : boolean +} + +declare const symbolKey: unique symbol; +>symbolKey : unique symbol + +// Error: Symbol keys are excluded. +read<{ [symbolKey]: boolean }>(symbolKey, {}); +>read<{ [symbolKey]: boolean }>(symbolKey, {}) : boolean +>read : (key: StringNumberKeys, values: { [key: string]: boolean; }) => boolean +>[symbolKey] : boolean +>symbolKey : unique symbol +>symbolKey : unique symbol +>{} : {} + diff --git a/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.errors.txt new file mode 100644 index 0000000000000..af0f7697c5869 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.errors.txt @@ -0,0 +1,47 @@ +negatedMappedConstraintContextualTypes.ts(23,5): error TS2322: Type '() => number' is not assignable to type 'never'. + + +==== negatedMappedConstraintContextualTypes.ts (1 errors) ==== + type MyExtract = T & U; + type MyExclude = T & not U; + type MyOmit = Pick>; + type Tags = Value extends { tag: infer Tag } ? Tag : never; + + declare function cases(): < + Handlers extends { + [Tag in Tags & string]: (value: MyExtract) => unknown; + } & { [Tag in MyExclude>]: never } + >(handlers: Handlers) => void; + + type Value = { tag: "a"; count: number } | { tag: "b"; text: string }; + const match = cases(); + match({ + a: value => value.count, + b: value => value.text, + }); + + match({ + a: value => value.count, + b: value => value.text, + // Error: Additional handlers are excluded. + extra: () => 0, + ~~~~~ +!!! error TS2322: Type '() => number' is not assignable to type 'never'. + }); + + type Elements = { + div: { onChange: (event: Event) => void }; + span: { onChange: (event: Event) => void }; + }; + type Props = MyOmit & { + onChange: (index: number) => void; + }; + declare function component(props: Props): void; + component({ onChange: index => { const numeric: number = index; } }); + + type RemappedOmit = { [Key in keyof T as MyExclude]: T[Key] }; + type RemappedProps = RemappedOmit & { + onChange: (index: number) => void; + }; + declare function remappedComponent(props: RemappedProps): void; + remappedComponent({ onChange: index => { const numeric: number = index; } }); \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.symbols b/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.symbols new file mode 100644 index 0000000000000..13d880492175a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.symbols @@ -0,0 +1,201 @@ +//// [tests/cases/compiler/negatedMappedConstraintContextualTypes.ts] //// + +=== negatedMappedConstraintContextualTypes.ts === +type MyExtract = T & U; +>MyExtract : Symbol(MyExtract, Decl(negatedMappedConstraintContextualTypes.ts, 0, 0)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 0, 15)) +>U : Symbol(U, Decl(negatedMappedConstraintContextualTypes.ts, 0, 17)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 0, 15)) +>U : Symbol(U, Decl(negatedMappedConstraintContextualTypes.ts, 0, 17)) + +type MyExclude = T & not U; +>MyExclude : Symbol(MyExclude, Decl(negatedMappedConstraintContextualTypes.ts, 0, 29)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 1, 15)) +>U : Symbol(U, Decl(negatedMappedConstraintContextualTypes.ts, 1, 17)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 1, 15)) +>U : Symbol(U, Decl(negatedMappedConstraintContextualTypes.ts, 1, 17)) + +type MyOmit = Pick>; +>MyOmit : Symbol(MyOmit, Decl(negatedMappedConstraintContextualTypes.ts, 1, 33)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 2, 12)) +>K : Symbol(K, Decl(negatedMappedConstraintContextualTypes.ts, 2, 14)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 2, 12)) +>MyExclude : Symbol(MyExclude, Decl(negatedMappedConstraintContextualTypes.ts, 0, 29)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 2, 12)) +>K : Symbol(K, Decl(negatedMappedConstraintContextualTypes.ts, 2, 14)) + +type Tags = Value extends { tag: infer Tag } ? Tag : never; +>Tags : Symbol(Tags, Decl(negatedMappedConstraintContextualTypes.ts, 2, 69)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 3, 10)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 3, 10)) +>tag : Symbol(tag, Decl(negatedMappedConstraintContextualTypes.ts, 3, 34)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 3, 45)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 3, 45)) + +declare function cases(): < +>cases : Symbol(cases, Decl(negatedMappedConstraintContextualTypes.ts, 3, 66)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 5, 23)) + + Handlers extends { +>Handlers : Symbol(Handlers, Decl(negatedMappedConstraintContextualTypes.ts, 5, 34)) + + [Tag in Tags & string]: (value: MyExtract) => unknown; +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 7, 9)) +>Tags : Symbol(Tags, Decl(negatedMappedConstraintContextualTypes.ts, 2, 69)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 5, 23)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 7, 40)) +>MyExtract : Symbol(MyExtract, Decl(negatedMappedConstraintContextualTypes.ts, 0, 0)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 5, 23)) +>tag : Symbol(tag, Decl(negatedMappedConstraintContextualTypes.ts, 7, 65)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 7, 9)) + + } & { [Tag in MyExclude>]: never } +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 8, 11)) +>MyExclude : Symbol(MyExclude, Decl(negatedMappedConstraintContextualTypes.ts, 0, 29)) +>Handlers : Symbol(Handlers, Decl(negatedMappedConstraintContextualTypes.ts, 5, 34)) +>Tags : Symbol(Tags, Decl(negatedMappedConstraintContextualTypes.ts, 2, 69)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 5, 23)) + +>(handlers: Handlers) => void; +>handlers : Symbol(handlers, Decl(negatedMappedConstraintContextualTypes.ts, 9, 2)) +>Handlers : Symbol(Handlers, Decl(negatedMappedConstraintContextualTypes.ts, 5, 34)) + +type Value = { tag: "a"; count: number } | { tag: "b"; text: string }; +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 9, 30)) +>tag : Symbol(tag, Decl(negatedMappedConstraintContextualTypes.ts, 11, 14)) +>count : Symbol(count, Decl(negatedMappedConstraintContextualTypes.ts, 11, 24)) +>tag : Symbol(tag, Decl(negatedMappedConstraintContextualTypes.ts, 11, 44)) +>text : Symbol(text, Decl(negatedMappedConstraintContextualTypes.ts, 11, 54)) + +const match = cases(); +>match : Symbol(match, Decl(negatedMappedConstraintContextualTypes.ts, 12, 5)) +>cases : Symbol(cases, Decl(negatedMappedConstraintContextualTypes.ts, 3, 66)) +>Value : Symbol(Value, Decl(negatedMappedConstraintContextualTypes.ts, 9, 30)) + +match({ +>match : Symbol(match, Decl(negatedMappedConstraintContextualTypes.ts, 12, 5)) + + a: value => value.count, +>a : Symbol(a, Decl(negatedMappedConstraintContextualTypes.ts, 13, 7)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 14, 6)) +>value.count : Symbol(count, Decl(negatedMappedConstraintContextualTypes.ts, 11, 24)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 14, 6)) +>count : Symbol(count, Decl(negatedMappedConstraintContextualTypes.ts, 11, 24)) + + b: value => value.text, +>b : Symbol(b, Decl(negatedMappedConstraintContextualTypes.ts, 14, 28)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 15, 6)) +>value.text : Symbol(text, Decl(negatedMappedConstraintContextualTypes.ts, 11, 54)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 15, 6)) +>text : Symbol(text, Decl(negatedMappedConstraintContextualTypes.ts, 11, 54)) + +}); + +match({ +>match : Symbol(match, Decl(negatedMappedConstraintContextualTypes.ts, 12, 5)) + + a: value => value.count, +>a : Symbol(a, Decl(negatedMappedConstraintContextualTypes.ts, 18, 7)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 19, 6)) +>value.count : Symbol(count, Decl(negatedMappedConstraintContextualTypes.ts, 11, 24)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 19, 6)) +>count : Symbol(count, Decl(negatedMappedConstraintContextualTypes.ts, 11, 24)) + + b: value => value.text, +>b : Symbol(b, Decl(negatedMappedConstraintContextualTypes.ts, 19, 28)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 20, 6)) +>value.text : Symbol(text, Decl(negatedMappedConstraintContextualTypes.ts, 11, 54)) +>value : Symbol(value, Decl(negatedMappedConstraintContextualTypes.ts, 20, 6)) +>text : Symbol(text, Decl(negatedMappedConstraintContextualTypes.ts, 11, 54)) + + // Error: Additional handlers are excluded. + extra: () => 0, +>extra : Symbol(extra, Decl(negatedMappedConstraintContextualTypes.ts, 20, 27)) + +}); + +type Elements = { +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) + + div: { onChange: (event: Event) => void }; +>div : Symbol(div, Decl(negatedMappedConstraintContextualTypes.ts, 25, 17)) +>onChange : Symbol(onChange, Decl(negatedMappedConstraintContextualTypes.ts, 26, 10)) +>event : Symbol(event, Decl(negatedMappedConstraintContextualTypes.ts, 26, 22)) +>Event : Symbol(Event, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + span: { onChange: (event: Event) => void }; +>span : Symbol(span, Decl(negatedMappedConstraintContextualTypes.ts, 26, 46)) +>onChange : Symbol(onChange, Decl(negatedMappedConstraintContextualTypes.ts, 27, 11)) +>event : Symbol(event, Decl(negatedMappedConstraintContextualTypes.ts, 27, 23)) +>Event : Symbol(Event, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +}; +type Props = MyOmit & { +>Props : Symbol(Props, Decl(negatedMappedConstraintContextualTypes.ts, 28, 2)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 29, 11)) +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) +>MyOmit : Symbol(MyOmit, Decl(negatedMappedConstraintContextualTypes.ts, 1, 33)) +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 29, 11)) + + onChange: (index: number) => void; +>onChange : Symbol(onChange, Decl(negatedMappedConstraintContextualTypes.ts, 29, 78)) +>index : Symbol(index, Decl(negatedMappedConstraintContextualTypes.ts, 30, 15)) + +}; +declare function component(props: Props): void; +>component : Symbol(component, Decl(negatedMappedConstraintContextualTypes.ts, 31, 2)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 32, 27)) +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) +>props : Symbol(props, Decl(negatedMappedConstraintContextualTypes.ts, 32, 63)) +>Props : Symbol(Props, Decl(negatedMappedConstraintContextualTypes.ts, 28, 2)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 32, 27)) + +component({ onChange: index => { const numeric: number = index; } }); +>component : Symbol(component, Decl(negatedMappedConstraintContextualTypes.ts, 31, 2)) +>onChange : Symbol(onChange, Decl(negatedMappedConstraintContextualTypes.ts, 33, 11)) +>index : Symbol(index, Decl(negatedMappedConstraintContextualTypes.ts, 33, 21)) +>numeric : Symbol(numeric, Decl(negatedMappedConstraintContextualTypes.ts, 33, 38)) +>index : Symbol(index, Decl(negatedMappedConstraintContextualTypes.ts, 33, 21)) + +type RemappedOmit = { [Key in keyof T as MyExclude]: T[Key] }; +>RemappedOmit : Symbol(RemappedOmit, Decl(negatedMappedConstraintContextualTypes.ts, 33, 69)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 35, 18)) +>Keys : Symbol(Keys, Decl(negatedMappedConstraintContextualTypes.ts, 35, 20)) +>Key : Symbol(Key, Decl(negatedMappedConstraintContextualTypes.ts, 35, 32)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 35, 18)) +>MyExclude : Symbol(MyExclude, Decl(negatedMappedConstraintContextualTypes.ts, 0, 29)) +>Key : Symbol(Key, Decl(negatedMappedConstraintContextualTypes.ts, 35, 32)) +>Keys : Symbol(Keys, Decl(negatedMappedConstraintContextualTypes.ts, 35, 20)) +>T : Symbol(T, Decl(negatedMappedConstraintContextualTypes.ts, 35, 18)) +>Key : Symbol(Key, Decl(negatedMappedConstraintContextualTypes.ts, 35, 32)) + +type RemappedProps = RemappedOmit & { +>RemappedProps : Symbol(RemappedProps, Decl(negatedMappedConstraintContextualTypes.ts, 35, 82)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 36, 19)) +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) +>RemappedOmit : Symbol(RemappedOmit, Decl(negatedMappedConstraintContextualTypes.ts, 33, 69)) +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 36, 19)) + + onChange: (index: number) => void; +>onChange : Symbol(onChange, Decl(negatedMappedConstraintContextualTypes.ts, 36, 92)) +>index : Symbol(index, Decl(negatedMappedConstraintContextualTypes.ts, 37, 15)) + +}; +declare function remappedComponent(props: RemappedProps): void; +>remappedComponent : Symbol(remappedComponent, Decl(negatedMappedConstraintContextualTypes.ts, 38, 2)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 39, 35)) +>Elements : Symbol(Elements, Decl(negatedMappedConstraintContextualTypes.ts, 23, 3)) +>props : Symbol(props, Decl(negatedMappedConstraintContextualTypes.ts, 39, 71)) +>RemappedProps : Symbol(RemappedProps, Decl(negatedMappedConstraintContextualTypes.ts, 35, 82)) +>Tag : Symbol(Tag, Decl(negatedMappedConstraintContextualTypes.ts, 39, 35)) + +remappedComponent({ onChange: index => { const numeric: number = index; } }); +>remappedComponent : Symbol(remappedComponent, Decl(negatedMappedConstraintContextualTypes.ts, 38, 2)) +>onChange : Symbol(onChange, Decl(negatedMappedConstraintContextualTypes.ts, 40, 19)) +>index : Symbol(index, Decl(negatedMappedConstraintContextualTypes.ts, 40, 29)) +>numeric : Symbol(numeric, Decl(negatedMappedConstraintContextualTypes.ts, 40, 46)) +>index : Symbol(index, Decl(negatedMappedConstraintContextualTypes.ts, 40, 29)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.types b/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.types new file mode 100644 index 0000000000000..d34a2e6c38b6e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedMappedConstraintContextualTypes.types @@ -0,0 +1,153 @@ +//// [tests/cases/compiler/negatedMappedConstraintContextualTypes.ts] //// + +=== negatedMappedConstraintContextualTypes.ts === +type MyExtract = T & U; +>MyExtract : MyExtract + +type MyExclude = T & not U; +>MyExclude : MyExclude + +type MyOmit = Pick>; +>MyOmit : MyOmit + +type Tags = Value extends { tag: infer Tag } ? Tag : never; +>Tags : Tags +>tag : Tag + +declare function cases(): < +>cases : () => & string]: (value: MyExtract) => unknown; } & { [Tag in MyExclude>]: never; }>(handlers: Handlers) => void + + Handlers extends { + [Tag in Tags & string]: (value: MyExtract) => unknown; +>value : MyExtract +>tag : Tag + + } & { [Tag in MyExclude>]: never } +>(handlers: Handlers) => void; +>handlers : Handlers + +type Value = { tag: "a"; count: number } | { tag: "b"; text: string }; +>Value : Value +>tag : "a" +>count : number +>tag : "b" +>text : string + +const match = cases(); +>match : & string]: (value: MyExtract) => unknown; } & { [Tag in MyExclude>]: never; }>(handlers: Handlers) => void +>cases() : & string]: (value: MyExtract) => unknown; } & { [Tag in MyExclude>]: never; }>(handlers: Handlers) => void +>cases : () => & string]: (value: MyExtract) => unknown; } & { [Tag in MyExclude>]: never; }>(handlers: Handlers) => void + +match({ +>match({ a: value => value.count, b: value => value.text,}) : void +>match : & string]: (value: MyExtract) => unknown; } & { [Tag in MyExclude>]: never; }>(handlers: Handlers) => void +>{ a: value => value.count, b: value => value.text,} : { a: (value: { tag: "a"; count: number; } & { tag: "a"; }) => number; b: (value: { tag: "b"; text: string; } & { tag: "b"; }) => string; } + + a: value => value.count, +>a : (value: { tag: "a"; count: number; } & { tag: "a"; }) => number +>value => value.count : (value: { tag: "a"; count: number; } & { tag: "a"; }) => number +>value : { tag: "a"; count: number; } & { tag: "a"; } +>value.count : number +>value : { tag: "a"; count: number; } & { tag: "a"; } +>count : number + + b: value => value.text, +>b : (value: { tag: "b"; text: string; } & { tag: "b"; }) => string +>value => value.text : (value: { tag: "b"; text: string; } & { tag: "b"; }) => string +>value : { tag: "b"; text: string; } & { tag: "b"; } +>value.text : string +>value : { tag: "b"; text: string; } & { tag: "b"; } +>text : string + +}); + +match({ +>match({ a: value => value.count, b: value => value.text, // Error: Additional handlers are excluded. extra: () => 0,}) : void +>match : & string]: (value: MyExtract) => unknown; } & { [Tag in MyExclude>]: never; }>(handlers: Handlers) => void +>{ a: value => value.count, b: value => value.text, // Error: Additional handlers are excluded. extra: () => 0,} : { a: (value: { tag: "a"; count: number; } & { tag: "a"; }) => number; b: (value: { tag: "b"; text: string; } & { tag: "b"; }) => string; extra: () => number; } + + a: value => value.count, +>a : (value: { tag: "a"; count: number; } & { tag: "a"; }) => number +>value => value.count : (value: { tag: "a"; count: number; } & { tag: "a"; }) => number +>value : { tag: "a"; count: number; } & { tag: "a"; } +>value.count : number +>value : { tag: "a"; count: number; } & { tag: "a"; } +>count : number + + b: value => value.text, +>b : (value: { tag: "b"; text: string; } & { tag: "b"; }) => string +>value => value.text : (value: { tag: "b"; text: string; } & { tag: "b"; }) => string +>value : { tag: "b"; text: string; } & { tag: "b"; } +>value.text : string +>value : { tag: "b"; text: string; } & { tag: "b"; } +>text : string + + // Error: Additional handlers are excluded. + extra: () => 0, +>extra : () => number +>() => 0 : () => number +>0 : 0 + +}); + +type Elements = { +>Elements : Elements + + div: { onChange: (event: Event) => void }; +>div : { onChange: (event: Event) => void; } +>onChange : (event: Event) => void +>event : Event + + span: { onChange: (event: Event) => void }; +>span : { onChange: (event: Event) => void; } +>onChange : (event: Event) => void +>event : Event + +}; +type Props = MyOmit & { +>Props : Props + + onChange: (index: number) => void; +>onChange : (index: number) => void +>index : number + +}; +declare function component(props: Props): void; +>component : (props: Props) => void +>props : Props + +component({ onChange: index => { const numeric: number = index; } }); +>component({ onChange: index => { const numeric: number = index; } }) : void +>component : (props: Props) => void +>{ onChange: index => { const numeric: number = index; } } : { onChange: (index: number) => void; } +>onChange : (index: number) => void +>index => { const numeric: number = index; } : (index: number) => void +>index : number +>numeric : number +>index : number + +type RemappedOmit = { [Key in keyof T as MyExclude]: T[Key] }; +>RemappedOmit : RemappedOmit + +type RemappedProps = RemappedOmit & { +>RemappedProps : RemappedProps + + onChange: (index: number) => void; +>onChange : (index: number) => void +>index : number + +}; +declare function remappedComponent(props: RemappedProps): void; +>remappedComponent : (props: RemappedProps) => void +>props : RemappedProps + +remappedComponent({ onChange: index => { const numeric: number = index; } }); +>remappedComponent({ onChange: index => { const numeric: number = index; } }) : void +>remappedComponent : (props: RemappedProps) => void +>{ onChange: index => { const numeric: number = index; } } : { onChange: (index: number) => void; } +>onChange : (index: number) => void +>index => { const numeric: number = index; } : (index: number) => void +>index : number +>numeric : number +>index : number + diff --git a/tsc/testdata/baselines/reference/compiler/negatedMappedIntersectionInference.symbols b/tsc/testdata/baselines/reference/compiler/negatedMappedIntersectionInference.symbols new file mode 100644 index 0000000000000..57f9acf15acb6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedMappedIntersectionInference.symbols @@ -0,0 +1,97 @@ +//// [tests/cases/compiler/negatedMappedIntersectionInference.ts] //// + +=== negatedMappedIntersectionInference.ts === +type MyExclude = T & not U; +>MyExclude : Symbol(MyExclude, Decl(negatedMappedIntersectionInference.ts, 0, 0)) +>T : Symbol(T, Decl(negatedMappedIntersectionInference.ts, 0, 15)) +>U : Symbol(U, Decl(negatedMappedIntersectionInference.ts, 0, 17)) +>T : Symbol(T, Decl(negatedMappedIntersectionInference.ts, 0, 15)) +>U : Symbol(U, Decl(negatedMappedIntersectionInference.ts, 0, 17)) + +type MyExtract = T & U; +>MyExtract : Symbol(MyExtract, Decl(negatedMappedIntersectionInference.ts, 0, 33)) +>T : Symbol(T, Decl(negatedMappedIntersectionInference.ts, 1, 15)) +>U : Symbol(U, Decl(negatedMappedIntersectionInference.ts, 1, 17)) +>T : Symbol(T, Decl(negatedMappedIntersectionInference.ts, 1, 15)) +>U : Symbol(U, Decl(negatedMappedIntersectionInference.ts, 1, 17)) + +interface Config { +>Config : Symbol(Config, Decl(negatedMappedIntersectionInference.ts, 1, 29)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 3, 17)) + + initialValues: Values; +>initialValues : Symbol(Config.initialValues, Decl(negatedMappedIntersectionInference.ts, 3, 26)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 3, 17)) + + validate?: (values: Values) => void; +>validate : Symbol(Config.validate, Decl(negatedMappedIntersectionInference.ts, 4, 26)) +>values : Symbol(values, Decl(negatedMappedIntersectionInference.ts, 5, 16)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 3, 17)) + + validateOnChange?: boolean; +>validateOnChange : Symbol(Config.validateOnChange, Decl(negatedMappedIntersectionInference.ts, 5, 40)) +} + +declare function configure(options: +>configure : Symbol(configure, Decl(negatedMappedIntersectionInference.ts, 7, 1)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 9, 27)) +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) +>options : Symbol(options, Decl(negatedMappedIntersectionInference.ts, 9, 56)) + + string extends "validate" | "initialValues" | keyof Extra +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) + + ? Readonly & Extra> +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Config : Symbol(Config, Decl(negatedMappedIntersectionInference.ts, 1, 29)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 9, 27)) +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) + + : Pick & Extra>, "validate" | "initialValues" | MyExclude> +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Config : Symbol(Config, Decl(negatedMappedIntersectionInference.ts, 1, 29)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 9, 27)) +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) +>MyExclude : Symbol(MyExclude, Decl(negatedMappedIntersectionInference.ts, 0, 0)) +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) + + & Partial & Extra>, "validateOnChange" | MyExtract>> +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Config : Symbol(Config, Decl(negatedMappedIntersectionInference.ts, 1, 29)) +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 9, 27)) +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) +>MyExtract : Symbol(MyExtract, Decl(negatedMappedIntersectionInference.ts, 0, 33)) +>Extra : Symbol(Extra, Decl(negatedMappedIntersectionInference.ts, 9, 43)) + +): Values; +>Values : Symbol(Values, Decl(negatedMappedIntersectionInference.ts, 9, 27)) + +const inferred = configure({ +>inferred : Symbol(inferred, Decl(negatedMappedIntersectionInference.ts, 16, 5)) +>configure : Symbol(configure, Decl(negatedMappedIntersectionInference.ts, 7, 1)) + + initialValues: { count: 1 }, +>initialValues : Symbol(initialValues, Decl(negatedMappedIntersectionInference.ts, 16, 28)) +>count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 17, 20)) + + validate: values => { +>validate : Symbol(validate, Decl(negatedMappedIntersectionInference.ts, 17, 32)) +>values : Symbol(values, Decl(negatedMappedIntersectionInference.ts, 18, 13)) + + const count: number = values.count; +>count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 19, 13)) +>values.count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 17, 20)) +>values : Symbol(values, Decl(negatedMappedIntersectionInference.ts, 18, 13)) +>count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 17, 20)) + + }, +}); +const count: number = inferred.count; +>count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 22, 5)) +>inferred.count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 17, 20)) +>inferred : Symbol(inferred, Decl(negatedMappedIntersectionInference.ts, 16, 5)) +>count : Symbol(count, Decl(negatedMappedIntersectionInference.ts, 17, 20)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedMappedIntersectionInference.types b/tsc/testdata/baselines/reference/compiler/negatedMappedIntersectionInference.types new file mode 100644 index 0000000000000..a2addd4dee4b3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedMappedIntersectionInference.types @@ -0,0 +1,62 @@ +//// [tests/cases/compiler/negatedMappedIntersectionInference.ts] //// + +=== negatedMappedIntersectionInference.ts === +type MyExclude = T & not U; +>MyExclude : MyExclude + +type MyExtract = T & U; +>MyExtract : MyExtract + +interface Config { + initialValues: Values; +>initialValues : Values + + validate?: (values: Values) => void; +>validate : ((values: Values) => void) | undefined +>values : Values + + validateOnChange?: boolean; +>validateOnChange : boolean | undefined +} + +declare function configure(options: +>configure : (options: string extends "validate" | "initialValues" | keyof Extra ? Readonly & Extra> : Pick & Extra>, "validate" | "initialValues" | MyExclude> & Partial & Extra>, "validateOnChange" | MyExtract>>) => Values +>options : string extends "initialValues" | "validate" | keyof Extra ? Readonly & Extra> : Pick & Extra>, "initialValues" | "validate" | MyExclude> & Partial & Extra>, "validateOnChange" | MyExtract>> + + string extends "validate" | "initialValues" | keyof Extra + ? Readonly & Extra> + : Pick & Extra>, "validate" | "initialValues" | MyExclude> + & Partial & Extra>, "validateOnChange" | MyExtract>> +): Values; + +const inferred = configure({ +>inferred : { count: number; } +>configure({ initialValues: { count: 1 }, validate: values => { const count: number = values.count; },}) : { count: number; } +>configure : (options: string extends "validate" | "initialValues" | keyof Extra ? Readonly & Extra> : Pick & Extra>, "validate" | "initialValues" | MyExclude> & Partial & Extra>, "validateOnChange" | MyExtract>>) => Values +>{ initialValues: { count: 1 }, validate: values => { const count: number = values.count; },} : { initialValues: { count: number; }; validate: (values: { count: number; }) => void; } + + initialValues: { count: 1 }, +>initialValues : { count: number; } +>{ count: 1 } : { count: number; } +>count : number +>1 : 1 + + validate: values => { +>validate : (values: { count: number; }) => void +>values => { const count: number = values.count; } : (values: { count: number; }) => void +>values : { count: number; } + + const count: number = values.count; +>count : number +>values.count : number +>values : { count: number; } +>count : number + + }, +}); +const count: number = inferred.count; +>count : number +>inferred.count : number +>inferred : { count: number; } +>count : number + diff --git a/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.errors.txt new file mode 100644 index 0000000000000..9eca6447e7e37 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.errors.txt @@ -0,0 +1,27 @@ +negatedNumericEnumComparability.ts(10,9): error TS2367: This comparison appears to be unintentional because the types 'number & not Position.Invalid' and 'Position.Invalid' have no overlap. +negatedNumericEnumComparability.ts(18,1): error TS2367: This comparison appears to be unintentional because the types 'number & not Position.Invalid' and 'Position.Invalid' have no overlap. + + +==== negatedNumericEnumComparability.ts (2 errors) ==== + enum Position { + Invalid = -1, + Start = 0, + } + + function comparePositions(position: number, other: number) { + if (position !== Position.Invalid) { + position === other; + other === position; + position === Position.Invalid; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2367: This comparison appears to be unintentional because the types 'number & not Position.Invalid' and 'Position.Invalid' have no overlap. + } + } + + declare const position: number & not Position.Invalid; + declare const other: number; + position === other; + other === position; + position === Position.Invalid; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2367: This comparison appears to be unintentional because the types 'number & not Position.Invalid' and 'Position.Invalid' have no overlap. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.symbols b/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.symbols new file mode 100644 index 0000000000000..1e424e6a05b85 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.symbols @@ -0,0 +1,62 @@ +//// [tests/cases/compiler/negatedNumericEnumComparability.ts] //// + +=== negatedNumericEnumComparability.ts === +enum Position { +>Position : Symbol(Position, Decl(negatedNumericEnumComparability.ts, 0, 0)) + + Invalid = -1, +>Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) + + Start = 0, +>Start : Symbol(Position.Start, Decl(negatedNumericEnumComparability.ts, 1, 17)) +} + +function comparePositions(position: number, other: number) { +>comparePositions : Symbol(comparePositions, Decl(negatedNumericEnumComparability.ts, 3, 1)) +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 5, 26)) +>other : Symbol(other, Decl(negatedNumericEnumComparability.ts, 5, 43)) + + if (position !== Position.Invalid) { +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 5, 26)) +>Position.Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) +>Position : Symbol(Position, Decl(negatedNumericEnumComparability.ts, 0, 0)) +>Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) + + position === other; +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 5, 26)) +>other : Symbol(other, Decl(negatedNumericEnumComparability.ts, 5, 43)) + + other === position; +>other : Symbol(other, Decl(negatedNumericEnumComparability.ts, 5, 43)) +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 5, 26)) + + position === Position.Invalid; +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 5, 26)) +>Position.Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) +>Position : Symbol(Position, Decl(negatedNumericEnumComparability.ts, 0, 0)) +>Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) + } +} + +declare const position: number & not Position.Invalid; +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 13, 13)) +>Position : Symbol(Position, Decl(negatedNumericEnumComparability.ts, 0, 0)) +>Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) + +declare const other: number; +>other : Symbol(other, Decl(negatedNumericEnumComparability.ts, 14, 13)) + +position === other; +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 13, 13)) +>other : Symbol(other, Decl(negatedNumericEnumComparability.ts, 14, 13)) + +other === position; +>other : Symbol(other, Decl(negatedNumericEnumComparability.ts, 14, 13)) +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 13, 13)) + +position === Position.Invalid; +>position : Symbol(position, Decl(negatedNumericEnumComparability.ts, 13, 13)) +>Position.Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) +>Position : Symbol(Position, Decl(negatedNumericEnumComparability.ts, 0, 0)) +>Invalid : Symbol(Position.Invalid, Decl(negatedNumericEnumComparability.ts, 0, 15)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.types b/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.types new file mode 100644 index 0000000000000..d2e4ba21ff2d4 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedNumericEnumComparability.types @@ -0,0 +1,71 @@ +//// [tests/cases/compiler/negatedNumericEnumComparability.ts] //// + +=== negatedNumericEnumComparability.ts === +enum Position { +>Position : Position + + Invalid = -1, +>Invalid : Position.Invalid +>-1 : -1 +>1 : 1 + + Start = 0, +>Start : Position.Start +>0 : 0 +} + +function comparePositions(position: number, other: number) { +>comparePositions : (position: number, other: number) => void +>position : number +>other : number + + if (position !== Position.Invalid) { +>position !== Position.Invalid : boolean +>position : number +>Position.Invalid : Position.Invalid +>Position : typeof Position +>Invalid : Position.Invalid + + position === other; +>position === other : boolean +>position : number & not Position.Invalid +>other : number + + other === position; +>other === position : boolean +>other : number +>position : number & not Position.Invalid + + position === Position.Invalid; +>position === Position.Invalid : boolean +>position : number & not Position.Invalid +>Position.Invalid : Position.Invalid +>Position : typeof Position +>Invalid : Position.Invalid + } +} + +declare const position: number & not Position.Invalid; +>position : number & not Position.Invalid +>Position : any + +declare const other: number; +>other : number + +position === other; +>position === other : boolean +>position : number & not Position.Invalid +>other : number + +other === position; +>other === position : boolean +>other : number +>position : number & not Position.Invalid + +position === Position.Invalid; +>position === Position.Invalid : boolean +>position : number & not Position.Invalid +>Position.Invalid : Position.Invalid +>Position : typeof Position +>Invalid : Position.Invalid + diff --git a/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.errors.txt new file mode 100644 index 0000000000000..7662f8642c360 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.errors.txt @@ -0,0 +1,40 @@ +negatedPartialTypeGuards.ts(17,25): error TS2345: Argument of type 'object' is not assignable to parameter of type 'not Reference'. + + +==== negatedPartialTypeGuards.ts (1 errors) ==== + interface Reference { + target: object; + } + + interface TupleReference extends Reference { + target: { elements: number[] }; + } + + declare function isArrayReference(value: object): value is Reference; + declare function isTupleReference(value: object): value is TupleReference; + declare function acceptsNotReference(value: not Reference): void; + + function checkReference(value: object) { + if (isArrayReference(value)) { + return; + } + acceptsNotReference(value); + ~~~~~ +!!! error TS2345: Argument of type 'object' is not assignable to parameter of type 'not Reference'. + if (isTupleReference(value)) { + value.target.elements; + } + } + + function checkProperty(container: { value: object }) { + if (!isArrayReference(container.value) && isTupleReference(container.value)) { + container.value.target.elements; + } + } + + declare function isSmallNumber(value: unknown): value is number; + function checkUnknown(value: unknown) { + if (!isSmallNumber(value) && typeof value === "number") { + value.toFixed(); + } + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.symbols b/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.symbols new file mode 100644 index 0000000000000..1edb1e6f0d104 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.symbols @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/negatedPartialTypeGuards.ts] //// + +=== negatedPartialTypeGuards.ts === +interface Reference { +>Reference : Symbol(Reference, Decl(negatedPartialTypeGuards.ts, 0, 0)) + + target: object; +>target : Symbol(Reference.target, Decl(negatedPartialTypeGuards.ts, 0, 21)) +} + +interface TupleReference extends Reference { +>TupleReference : Symbol(TupleReference, Decl(negatedPartialTypeGuards.ts, 2, 1)) +>Reference : Symbol(Reference, Decl(negatedPartialTypeGuards.ts, 0, 0)) + + target: { elements: number[] }; +>target : Symbol(TupleReference.target, Decl(negatedPartialTypeGuards.ts, 4, 44)) +>elements : Symbol(elements, Decl(negatedPartialTypeGuards.ts, 5, 13)) +} + +declare function isArrayReference(value: object): value is Reference; +>isArrayReference : Symbol(isArrayReference, Decl(negatedPartialTypeGuards.ts, 6, 1)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 8, 34)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 8, 34)) +>Reference : Symbol(Reference, Decl(negatedPartialTypeGuards.ts, 0, 0)) + +declare function isTupleReference(value: object): value is TupleReference; +>isTupleReference : Symbol(isTupleReference, Decl(negatedPartialTypeGuards.ts, 8, 69)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 9, 34)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 9, 34)) +>TupleReference : Symbol(TupleReference, Decl(negatedPartialTypeGuards.ts, 2, 1)) + +declare function acceptsNotReference(value: not Reference): void; +>acceptsNotReference : Symbol(acceptsNotReference, Decl(negatedPartialTypeGuards.ts, 9, 74)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 10, 37)) +>Reference : Symbol(Reference, Decl(negatedPartialTypeGuards.ts, 0, 0)) + +function checkReference(value: object) { +>checkReference : Symbol(checkReference, Decl(negatedPartialTypeGuards.ts, 10, 65)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 12, 24)) + + if (isArrayReference(value)) { +>isArrayReference : Symbol(isArrayReference, Decl(negatedPartialTypeGuards.ts, 6, 1)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 12, 24)) + + return; + } + acceptsNotReference(value); +>acceptsNotReference : Symbol(acceptsNotReference, Decl(negatedPartialTypeGuards.ts, 9, 74)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 12, 24)) + + if (isTupleReference(value)) { +>isTupleReference : Symbol(isTupleReference, Decl(negatedPartialTypeGuards.ts, 8, 69)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 12, 24)) + + value.target.elements; +>value.target.elements : Symbol(elements, Decl(negatedPartialTypeGuards.ts, 5, 13)) +>value.target : Symbol(TupleReference.target, Decl(negatedPartialTypeGuards.ts, 4, 44)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 12, 24)) +>target : Symbol(TupleReference.target, Decl(negatedPartialTypeGuards.ts, 4, 44)) +>elements : Symbol(elements, Decl(negatedPartialTypeGuards.ts, 5, 13)) + } +} + +function checkProperty(container: { value: object }) { +>checkProperty : Symbol(checkProperty, Decl(negatedPartialTypeGuards.ts, 20, 1)) +>container : Symbol(container, Decl(negatedPartialTypeGuards.ts, 22, 23)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) + + if (!isArrayReference(container.value) && isTupleReference(container.value)) { +>isArrayReference : Symbol(isArrayReference, Decl(negatedPartialTypeGuards.ts, 6, 1)) +>container.value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) +>container : Symbol(container, Decl(negatedPartialTypeGuards.ts, 22, 23)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) +>isTupleReference : Symbol(isTupleReference, Decl(negatedPartialTypeGuards.ts, 8, 69)) +>container.value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) +>container : Symbol(container, Decl(negatedPartialTypeGuards.ts, 22, 23)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) + + container.value.target.elements; +>container.value.target.elements : Symbol(elements, Decl(negatedPartialTypeGuards.ts, 5, 13)) +>container.value.target : Symbol(TupleReference.target, Decl(negatedPartialTypeGuards.ts, 4, 44)) +>container.value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) +>container : Symbol(container, Decl(negatedPartialTypeGuards.ts, 22, 23)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 22, 35)) +>target : Symbol(TupleReference.target, Decl(negatedPartialTypeGuards.ts, 4, 44)) +>elements : Symbol(elements, Decl(negatedPartialTypeGuards.ts, 5, 13)) + } +} + +declare function isSmallNumber(value: unknown): value is number; +>isSmallNumber : Symbol(isSmallNumber, Decl(negatedPartialTypeGuards.ts, 26, 1)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 28, 31)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 28, 31)) + +function checkUnknown(value: unknown) { +>checkUnknown : Symbol(checkUnknown, Decl(negatedPartialTypeGuards.ts, 28, 64)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 29, 22)) + + if (!isSmallNumber(value) && typeof value === "number") { +>isSmallNumber : Symbol(isSmallNumber, Decl(negatedPartialTypeGuards.ts, 26, 1)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 29, 22)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 29, 22)) + + value.toFixed(); +>value.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(negatedPartialTypeGuards.ts, 29, 22)) +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) + } +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.types b/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.types new file mode 100644 index 0000000000000..6347bb2203250 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedPartialTypeGuards.types @@ -0,0 +1,112 @@ +//// [tests/cases/compiler/negatedPartialTypeGuards.ts] //// + +=== negatedPartialTypeGuards.ts === +interface Reference { + target: object; +>target : object +} + +interface TupleReference extends Reference { + target: { elements: number[] }; +>target : { elements: number[]; } +>elements : number[] +} + +declare function isArrayReference(value: object): value is Reference; +>isArrayReference : (value: object) => value is Reference +>value : object + +declare function isTupleReference(value: object): value is TupleReference; +>isTupleReference : (value: object) => value is TupleReference +>value : object + +declare function acceptsNotReference(value: not Reference): void; +>acceptsNotReference : (value: not Reference) => void +>value : not Reference + +function checkReference(value: object) { +>checkReference : (value: object) => void +>value : object + + if (isArrayReference(value)) { +>isArrayReference(value) : boolean +>isArrayReference : (value: object) => value is Reference +>value : object + + return; + } + acceptsNotReference(value); +>acceptsNotReference(value) : void +>acceptsNotReference : (value: not Reference) => void +>value : object + + if (isTupleReference(value)) { +>isTupleReference(value) : boolean +>isTupleReference : (value: object) => value is TupleReference +>value : object + + value.target.elements; +>value.target.elements : number[] +>value.target : { elements: number[]; } +>value : TupleReference +>target : { elements: number[]; } +>elements : number[] + } +} + +function checkProperty(container: { value: object }) { +>checkProperty : (container: { value: object; }) => void +>container : { value: object; } +>value : object + + if (!isArrayReference(container.value) && isTupleReference(container.value)) { +>!isArrayReference(container.value) && isTupleReference(container.value) : boolean +>!isArrayReference(container.value) : boolean +>isArrayReference(container.value) : boolean +>isArrayReference : (value: object) => value is Reference +>container.value : object +>container : { value: object; } +>value : object +>isTupleReference(container.value) : boolean +>isTupleReference : (value: object) => value is TupleReference +>container.value : object +>container : { value: object; } +>value : object + + container.value.target.elements; +>container.value.target.elements : number[] +>container.value.target : { elements: number[]; } +>container.value : TupleReference +>container : { value: object; } +>value : TupleReference +>target : { elements: number[]; } +>elements : number[] + } +} + +declare function isSmallNumber(value: unknown): value is number; +>isSmallNumber : (value: unknown) => value is number +>value : unknown + +function checkUnknown(value: unknown) { +>checkUnknown : (value: unknown) => void +>value : unknown + + if (!isSmallNumber(value) && typeof value === "number") { +>!isSmallNumber(value) && typeof value === "number" : boolean +>!isSmallNumber(value) : boolean +>isSmallNumber(value) : boolean +>isSmallNumber : (value: unknown) => value is number +>value : unknown +>typeof value === "number" : boolean +>typeof value : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>value : unknown +>"number" : "number" + + value.toFixed(); +>value.toFixed() : string +>value.toFixed : (fractionDigits?: number) => string +>value : number +>toFixed : (fractionDigits?: number) => string + } +} diff --git a/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.errors.txt new file mode 100644 index 0000000000000..bf15e6426924e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.errors.txt @@ -0,0 +1,65 @@ +negatedRealWorldControlFlowRegressions.ts(36,1): error TS2322: Type 'number' is not assignable to type 'number & not 0'. + Type 'number' is not assignable to type 'not 0'. + + +==== negatedRealWorldControlFlowRegressions.ts (1 errors) ==== + function parseCommand(command: string): "start" | "stop" { + if (command !== "start" && command !== "stop") { + throw new Error("Invalid command"); + } + return command; + } + + interface HandlerOptions { + message?: string; + } + + declare const handler: string | HandlerOptions | ((value: number) => void) | undefined; + if (typeof handler !== "string" && handler !== undefined && typeof handler === "function") { + handler(0); + } + + let count = 1 as number; + if (count !== 0) { + count--; + if (count === 0) { + count; + } + } + + let offset = 1 as number; + if (offset !== 0) { + offset = 0; + } + + let total = 1 as number; + if (total !== 0) { + total -= 1; + } + + declare let constrainedTotal: number & not 0; + constrainedTotal -= 1; + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'number & not 0'. +!!! error TS2322: Type 'number' is not assignable to type 'not 0'. + + declare const values: Map; + if (values.size !== 0) { + values.delete("key"); + if (values.size === 0) { + values; + } + } + + interface Options { + enabled?: boolean; + threshold?: number; + } + + declare const rawOptions: boolean | Options; + const options = typeof rawOptions === "boolean" ? { enabled: rawOptions } : rawOptions; + options.threshold; + + declare const input: unknown; + const normalized = typeof input === "bigint" ? Number(input) : input; + normalized; \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.symbols b/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.symbols new file mode 100644 index 0000000000000..58c022cbda1c2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.symbols @@ -0,0 +1,146 @@ +//// [tests/cases/compiler/negatedRealWorldControlFlowRegressions.ts] //// + +=== negatedRealWorldControlFlowRegressions.ts === +function parseCommand(command: string): "start" | "stop" { +>parseCommand : Symbol(parseCommand, Decl(negatedRealWorldControlFlowRegressions.ts, 0, 0)) +>command : Symbol(command, Decl(negatedRealWorldControlFlowRegressions.ts, 0, 22)) + + if (command !== "start" && command !== "stop") { +>command : Symbol(command, Decl(negatedRealWorldControlFlowRegressions.ts, 0, 22)) +>command : Symbol(command, Decl(negatedRealWorldControlFlowRegressions.ts, 0, 22)) + + throw new Error("Invalid command"); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + } + return command; +>command : Symbol(command, Decl(negatedRealWorldControlFlowRegressions.ts, 0, 22)) +} + +interface HandlerOptions { +>HandlerOptions : Symbol(HandlerOptions, Decl(negatedRealWorldControlFlowRegressions.ts, 5, 1)) + + message?: string; +>message : Symbol(HandlerOptions.message, Decl(negatedRealWorldControlFlowRegressions.ts, 7, 26)) +} + +declare const handler: string | HandlerOptions | ((value: number) => void) | undefined; +>handler : Symbol(handler, Decl(negatedRealWorldControlFlowRegressions.ts, 11, 13)) +>HandlerOptions : Symbol(HandlerOptions, Decl(negatedRealWorldControlFlowRegressions.ts, 5, 1)) +>value : Symbol(value, Decl(negatedRealWorldControlFlowRegressions.ts, 11, 51)) + +if (typeof handler !== "string" && handler !== undefined && typeof handler === "function") { +>handler : Symbol(handler, Decl(negatedRealWorldControlFlowRegressions.ts, 11, 13)) +>handler : Symbol(handler, Decl(negatedRealWorldControlFlowRegressions.ts, 11, 13)) +>undefined : Symbol(undefined) +>handler : Symbol(handler, Decl(negatedRealWorldControlFlowRegressions.ts, 11, 13)) + + handler(0); +>handler : Symbol(handler, Decl(negatedRealWorldControlFlowRegressions.ts, 11, 13)) +} + +let count = 1 as number; +>count : Symbol(count, Decl(negatedRealWorldControlFlowRegressions.ts, 16, 3)) + +if (count !== 0) { +>count : Symbol(count, Decl(negatedRealWorldControlFlowRegressions.ts, 16, 3)) + + count--; +>count : Symbol(count, Decl(negatedRealWorldControlFlowRegressions.ts, 16, 3)) + + if (count === 0) { +>count : Symbol(count, Decl(negatedRealWorldControlFlowRegressions.ts, 16, 3)) + + count; +>count : Symbol(count, Decl(negatedRealWorldControlFlowRegressions.ts, 16, 3)) + } +} + +let offset = 1 as number; +>offset : Symbol(offset, Decl(negatedRealWorldControlFlowRegressions.ts, 24, 3)) + +if (offset !== 0) { +>offset : Symbol(offset, Decl(negatedRealWorldControlFlowRegressions.ts, 24, 3)) + + offset = 0; +>offset : Symbol(offset, Decl(negatedRealWorldControlFlowRegressions.ts, 24, 3)) +} + +let total = 1 as number; +>total : Symbol(total, Decl(negatedRealWorldControlFlowRegressions.ts, 29, 3)) + +if (total !== 0) { +>total : Symbol(total, Decl(negatedRealWorldControlFlowRegressions.ts, 29, 3)) + + total -= 1; +>total : Symbol(total, Decl(negatedRealWorldControlFlowRegressions.ts, 29, 3)) +} + +declare let constrainedTotal: number & not 0; +>constrainedTotal : Symbol(constrainedTotal, Decl(negatedRealWorldControlFlowRegressions.ts, 34, 11)) + +constrainedTotal -= 1; +>constrainedTotal : Symbol(constrainedTotal, Decl(negatedRealWorldControlFlowRegressions.ts, 34, 11)) + +declare const values: Map; +>values : Symbol(values, Decl(negatedRealWorldControlFlowRegressions.ts, 37, 13)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2026.collection.d.ts, --, --)) + +if (values.size !== 0) { +>values.size : Symbol(Map.size, Decl(lib.es2015.collection.d.ts, --, --)) +>values : Symbol(values, Decl(negatedRealWorldControlFlowRegressions.ts, 37, 13)) +>size : Symbol(Map.size, Decl(lib.es2015.collection.d.ts, --, --)) + + values.delete("key"); +>values.delete : Symbol(Map.delete, Decl(lib.es2015.collection.d.ts, --, --)) +>values : Symbol(values, Decl(negatedRealWorldControlFlowRegressions.ts, 37, 13)) +>delete : Symbol(Map.delete, Decl(lib.es2015.collection.d.ts, --, --)) + + if (values.size === 0) { +>values.size : Symbol(Map.size, Decl(lib.es2015.collection.d.ts, --, --)) +>values : Symbol(values, Decl(negatedRealWorldControlFlowRegressions.ts, 37, 13)) +>size : Symbol(Map.size, Decl(lib.es2015.collection.d.ts, --, --)) + + values; +>values : Symbol(values, Decl(negatedRealWorldControlFlowRegressions.ts, 37, 13)) + } +} + +interface Options { +>Options : Symbol(Options, Decl(negatedRealWorldControlFlowRegressions.ts, 43, 1)) + + enabled?: boolean; +>enabled : Symbol(Options.enabled, Decl(negatedRealWorldControlFlowRegressions.ts, 45, 19)) + + threshold?: number; +>threshold : Symbol(Options.threshold, Decl(negatedRealWorldControlFlowRegressions.ts, 46, 22)) +} + +declare const rawOptions: boolean | Options; +>rawOptions : Symbol(rawOptions, Decl(negatedRealWorldControlFlowRegressions.ts, 50, 13)) +>Options : Symbol(Options, Decl(negatedRealWorldControlFlowRegressions.ts, 43, 1)) + +const options = typeof rawOptions === "boolean" ? { enabled: rawOptions } : rawOptions; +>options : Symbol(options, Decl(negatedRealWorldControlFlowRegressions.ts, 51, 5)) +>rawOptions : Symbol(rawOptions, Decl(negatedRealWorldControlFlowRegressions.ts, 50, 13)) +>enabled : Symbol(enabled, Decl(negatedRealWorldControlFlowRegressions.ts, 51, 51)) +>rawOptions : Symbol(rawOptions, Decl(negatedRealWorldControlFlowRegressions.ts, 50, 13)) +>rawOptions : Symbol(rawOptions, Decl(negatedRealWorldControlFlowRegressions.ts, 50, 13)) + +options.threshold; +>options.threshold : Symbol(Options.threshold, Decl(negatedRealWorldControlFlowRegressions.ts, 46, 22)) +>options : Symbol(options, Decl(negatedRealWorldControlFlowRegressions.ts, 51, 5)) +>threshold : Symbol(Options.threshold, Decl(negatedRealWorldControlFlowRegressions.ts, 46, 22)) + +declare const input: unknown; +>input : Symbol(input, Decl(negatedRealWorldControlFlowRegressions.ts, 54, 13)) + +const normalized = typeof input === "bigint" ? Number(input) : input; +>normalized : Symbol(normalized, Decl(negatedRealWorldControlFlowRegressions.ts, 55, 5)) +>input : Symbol(input, Decl(negatedRealWorldControlFlowRegressions.ts, 54, 13)) +>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2020.number.d.ts, --, --)) +>input : Symbol(input, Decl(negatedRealWorldControlFlowRegressions.ts, 54, 13)) +>input : Symbol(input, Decl(negatedRealWorldControlFlowRegressions.ts, 54, 13)) + +normalized; +>normalized : Symbol(normalized, Decl(negatedRealWorldControlFlowRegressions.ts, 55, 5)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.types b/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.types new file mode 100644 index 0000000000000..4dc4fe01a0fac --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRealWorldControlFlowRegressions.types @@ -0,0 +1,194 @@ +//// [tests/cases/compiler/negatedRealWorldControlFlowRegressions.ts] //// + +=== negatedRealWorldControlFlowRegressions.ts === +function parseCommand(command: string): "start" | "stop" { +>parseCommand : (command: string) => "start" | "stop" +>command : string + + if (command !== "start" && command !== "stop") { +>command !== "start" && command !== "stop" : boolean +>command !== "start" : boolean +>command : string +>"start" : "start" +>command !== "stop" : boolean +>command : string & not "start" +>"stop" : "stop" + + throw new Error("Invalid command"); +>new Error("Invalid command") : Error +>Error : ErrorConstructor +>"Invalid command" : "Invalid command" + } + return command; +>command : "start" | "stop" +} + +interface HandlerOptions { + message?: string; +>message : string | undefined +} + +declare const handler: string | HandlerOptions | ((value: number) => void) | undefined; +>handler : string | HandlerOptions | ((value: number) => void) | undefined +>value : number + +if (typeof handler !== "string" && handler !== undefined && typeof handler === "function") { +>typeof handler !== "string" && handler !== undefined && typeof handler === "function" : boolean +>typeof handler !== "string" && handler !== undefined : boolean +>typeof handler !== "string" : boolean +>typeof handler : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>handler : string | HandlerOptions | ((value: number) => void) | undefined +>"string" : "string" +>handler !== undefined : boolean +>handler : HandlerOptions | ((value: number) => void) | undefined +>undefined : undefined +>typeof handler === "function" : boolean +>typeof handler : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>handler : HandlerOptions | ((value: number) => void) +>"function" : "function" + + handler(0); +>handler(0) : void +>handler : (value: number) => void +>0 : 0 +} + +let count = 1 as number; +>count : number +>1 as number : number +>1 : 1 + +if (count !== 0) { +>count !== 0 : boolean +>count : number +>0 : 0 + + count--; +>count-- : number +>count : number & not 0 + + if (count === 0) { +>count === 0 : boolean +>count : number +>0 : 0 + + count; +>count : 0 + } +} + +let offset = 1 as number; +>offset : number +>1 as number : number +>1 : 1 + +if (offset !== 0) { +>offset !== 0 : boolean +>offset : number +>0 : 0 + + offset = 0; +>offset = 0 : 0 +>offset : number +>0 : 0 +} + +let total = 1 as number; +>total : number +>1 as number : number +>1 : 1 + +if (total !== 0) { +>total !== 0 : boolean +>total : number +>0 : 0 + + total -= 1; +>total -= 1 : number +>total : number & not 0 +>1 : 1 +} + +declare let constrainedTotal: number & not 0; +>constrainedTotal : number & not 0 + +constrainedTotal -= 1; +>constrainedTotal -= 1 : number +>constrainedTotal : number & not 0 +>1 : 1 + +declare const values: Map; +>values : Map + +if (values.size !== 0) { +>values.size !== 0 : boolean +>values.size : number +>values : Map +>size : number +>0 : 0 + + values.delete("key"); +>values.delete("key") : boolean +>values.delete : (key: string) => boolean +>values : Map +>delete : (key: string) => boolean +>"key" : "key" + + if (values.size === 0) { +>values.size === 0 : boolean +>values.size : number +>values : Map +>size : number +>0 : 0 + + values; +>values : Map + } +} + +interface Options { + enabled?: boolean; +>enabled : boolean | undefined + + threshold?: number; +>threshold : number | undefined +} + +declare const rawOptions: boolean | Options; +>rawOptions : boolean | Options + +const options = typeof rawOptions === "boolean" ? { enabled: rawOptions } : rawOptions; +>options : Options +>typeof rawOptions === "boolean" ? { enabled: rawOptions } : rawOptions : Options +>typeof rawOptions === "boolean" : boolean +>typeof rawOptions : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>rawOptions : boolean | Options +>"boolean" : "boolean" +>{ enabled: rawOptions } : { enabled: boolean; } +>enabled : boolean +>rawOptions : boolean +>rawOptions : Options + +options.threshold; +>options.threshold : number | undefined +>options : Options +>threshold : number | undefined + +declare const input: unknown; +>input : unknown + +const normalized = typeof input === "bigint" ? Number(input) : input; +>normalized : unknown +>typeof input === "bigint" ? Number(input) : input : number | not bigint +>typeof input === "bigint" : boolean +>typeof input : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>input : unknown +>"bigint" : "bigint" +>Number(input) : number +>Number : NumberConstructor +>input : bigint +>input : not bigint + +normalized; +>normalized : unknown + diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.errors.txt new file mode 100644 index 0000000000000..0c627a1ce128f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.errors.txt @@ -0,0 +1,22 @@ +negatedRecursiveComponentStatics.ts(15,13): error TS2322: Type 'string' is not assignable to type 'number'. + + +==== negatedRecursiveComponentStatics.ts (1 errors) ==== + type Component = (props: any) => any; + type Statics = { + [Key in keyof Value & not (Value extends { kind: "memo" } ? "kind" : "name")]: Value[Key]; + }; + type Styled = string & StyledBase & Statics; + interface StyledBase { + (props: Parameters[0]): void; + withComponent>(other: Other): Styled>; + } + type Inner = Value extends Styled ? Result : Value; + + declare const component: Styled<(props: { count: number }) => void>; + component({ count: 1 }); + // Error: The original component parameter type must be preserved. + component({ count: "wrong" }); + ~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 negatedRecursiveComponentStatics.ts:12:43: The expected type comes from property 'count' which is declared here on type '{ count: number; }' \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.symbols b/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.symbols new file mode 100644 index 0000000000000..6ad9c57e8808c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.symbols @@ -0,0 +1,74 @@ +//// [tests/cases/compiler/negatedRecursiveComponentStatics.ts] //// + +=== negatedRecursiveComponentStatics.ts === +type Component = (props: any) => any; +>Component : Symbol(Component, Decl(negatedRecursiveComponentStatics.ts, 0, 0)) +>props : Symbol(props, Decl(negatedRecursiveComponentStatics.ts, 0, 18)) + +type Statics = { +>Statics : Symbol(Statics, Decl(negatedRecursiveComponentStatics.ts, 0, 37)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 1, 13)) + + [Key in keyof Value & not (Value extends { kind: "memo" } ? "kind" : "name")]: Value[Key]; +>Key : Symbol(Key, Decl(negatedRecursiveComponentStatics.ts, 2, 5)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 1, 13)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 1, 13)) +>kind : Symbol(kind, Decl(negatedRecursiveComponentStatics.ts, 2, 46)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 1, 13)) +>Key : Symbol(Key, Decl(negatedRecursiveComponentStatics.ts, 2, 5)) + +}; +type Styled = string & StyledBase & Statics; +>Styled : Symbol(Styled, Decl(negatedRecursiveComponentStatics.ts, 3, 2)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 4, 12)) +>Component : Symbol(Component, Decl(negatedRecursiveComponentStatics.ts, 0, 0)) +>StyledBase : Symbol(StyledBase, Decl(negatedRecursiveComponentStatics.ts, 4, 83)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 4, 12)) +>Statics : Symbol(Statics, Decl(negatedRecursiveComponentStatics.ts, 0, 37)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 4, 12)) + +interface StyledBase { +>StyledBase : Symbol(StyledBase, Decl(negatedRecursiveComponentStatics.ts, 4, 83)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 5, 21)) +>Component : Symbol(Component, Decl(negatedRecursiveComponentStatics.ts, 0, 0)) + + (props: Parameters[0]): void; +>props : Symbol(props, Decl(negatedRecursiveComponentStatics.ts, 6, 5)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 5, 21)) + + withComponent>(other: Other): Styled>; +>withComponent : Symbol(StyledBase.withComponent, Decl(negatedRecursiveComponentStatics.ts, 6, 40)) +>Other : Symbol(Other, Decl(negatedRecursiveComponentStatics.ts, 7, 18)) +>Styled : Symbol(Styled, Decl(negatedRecursiveComponentStatics.ts, 3, 2)) +>other : Symbol(other, Decl(negatedRecursiveComponentStatics.ts, 7, 45)) +>Other : Symbol(Other, Decl(negatedRecursiveComponentStatics.ts, 7, 18)) +>Styled : Symbol(Styled, Decl(negatedRecursiveComponentStatics.ts, 3, 2)) +>Inner : Symbol(Inner, Decl(negatedRecursiveComponentStatics.ts, 8, 1)) +>Other : Symbol(Other, Decl(negatedRecursiveComponentStatics.ts, 7, 18)) +} +type Inner = Value extends Styled ? Result : Value; +>Inner : Symbol(Inner, Decl(negatedRecursiveComponentStatics.ts, 8, 1)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 9, 11)) +>Component : Symbol(Component, Decl(negatedRecursiveComponentStatics.ts, 0, 0)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 9, 11)) +>Styled : Symbol(Styled, Decl(negatedRecursiveComponentStatics.ts, 3, 2)) +>Result : Symbol(Result, Decl(negatedRecursiveComponentStatics.ts, 9, 64)) +>Result : Symbol(Result, Decl(negatedRecursiveComponentStatics.ts, 9, 64)) +>Value : Symbol(Value, Decl(negatedRecursiveComponentStatics.ts, 9, 11)) + +declare const component: Styled<(props: { count: number }) => void>; +>component : Symbol(component, Decl(negatedRecursiveComponentStatics.ts, 11, 13)) +>Styled : Symbol(Styled, Decl(negatedRecursiveComponentStatics.ts, 3, 2)) +>props : Symbol(props, Decl(negatedRecursiveComponentStatics.ts, 11, 33)) +>count : Symbol(count, Decl(negatedRecursiveComponentStatics.ts, 11, 41)) + +component({ count: 1 }); +>component : Symbol(component, Decl(negatedRecursiveComponentStatics.ts, 11, 13)) +>count : Symbol(count, Decl(negatedRecursiveComponentStatics.ts, 12, 11)) + +// Error: The original component parameter type must be preserved. +component({ count: "wrong" }); +>component : Symbol(component, Decl(negatedRecursiveComponentStatics.ts, 11, 13)) +>count : Symbol(count, Decl(negatedRecursiveComponentStatics.ts, 14, 11)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.types b/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.types new file mode 100644 index 0000000000000..e80a86eeaa99c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveComponentStatics.types @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/negatedRecursiveComponentStatics.ts] //// + +=== negatedRecursiveComponentStatics.ts === +type Component = (props: any) => any; +>Component : Component +>props : any + +type Statics = { +>Statics : Statics + + [Key in keyof Value & not (Value extends { kind: "memo" } ? "kind" : "name")]: Value[Key]; +>kind : "memo" + +}; +type Styled = string & StyledBase & Statics; +>Styled : Styled + +interface StyledBase { + (props: Parameters[0]): void; +>props : Parameters[0] + + withComponent>(other: Other): Styled>; +>withComponent : >(other: Other) => Styled> +>other : Other +} +type Inner = Value extends Styled ? Result : Value; +>Inner : Inner + +declare const component: Styled<(props: { count: number }) => void>; +>component : Styled<(props: { count: number; }) => void> +>props : { count: number; } +>count : number + +component({ count: 1 }); +>component({ count: 1 }) : void +>component : Styled<(props: { count: number; }) => void> +>{ count: 1 } : { count: number; } +>count : number +>1 : 1 + +// Error: The original component parameter type must be preserved. +component({ count: "wrong" }); +>component({ count: "wrong" }) : void +>component : Styled<(props: { count: number; }) => void> +>{ count: "wrong" } : { count: string; } +>count : string +>"wrong" : "wrong" + diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.errors.txt b/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.errors.txt new file mode 100644 index 0000000000000..2e4907d182a36 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.errors.txt @@ -0,0 +1,28 @@ +negatedRecursiveKeyConstraints.ts(17,16): error TS2322: Type 'Value<"same">' is not assignable to type 'never'. +negatedRecursiveKeyConstraints.ts(17,38): error TS2322: Type 'Value<"same">' is not assignable to type 'never'. + + +==== negatedRecursiveKeyConstraints.ts (2 errors) ==== + type MyExclude = T & not U; + type MyExtract = T & U; + + type Recursive], { value: string }>["value"]; + }> = Shape; + + type Value = { value: Text }; + declare function value(text: Text): Value; + declare function uniqueValues["value"] extends + MyExtract], Value>["value"] ? never : unknown; + }>(shape: Shape): void; + + uniqueValues({ first: value("one"), second: value("two") }); + uniqueValues({ first: value("one") }); + uniqueValues({ first: value("same"), second: value("same") }); + ~~~~~ +!!! error TS2322: Type 'Value<"same">' is not assignable to type 'never'. +!!! related TS6500 negatedRecursiveKeyConstraints.ts:17:16: The expected type comes from property 'first' which is declared here on type '{ first: never; second: never; }' + ~~~~~~ +!!! error TS2322: Type 'Value<"same">' is not assignable to type 'never'. +!!! related TS6500 negatedRecursiveKeyConstraints.ts:17:38: The expected type comes from property 'second' which is declared here on type '{ first: never; second: never; }' \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.symbols b/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.symbols new file mode 100644 index 0000000000000..7c4fe6eda7f1a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.symbols @@ -0,0 +1,91 @@ +//// [tests/cases/compiler/negatedRecursiveKeyConstraints.ts] //// + +=== negatedRecursiveKeyConstraints.ts === +type MyExclude = T & not U; +>MyExclude : Symbol(MyExclude, Decl(negatedRecursiveKeyConstraints.ts, 0, 0)) +>T : Symbol(T, Decl(negatedRecursiveKeyConstraints.ts, 0, 15)) +>U : Symbol(U, Decl(negatedRecursiveKeyConstraints.ts, 0, 17)) +>T : Symbol(T, Decl(negatedRecursiveKeyConstraints.ts, 0, 15)) +>U : Symbol(U, Decl(negatedRecursiveKeyConstraints.ts, 0, 17)) + +type MyExtract = T & U; +>MyExtract : Symbol(MyExtract, Decl(negatedRecursiveKeyConstraints.ts, 0, 33)) +>T : Symbol(T, Decl(negatedRecursiveKeyConstraints.ts, 1, 15)) +>U : Symbol(U, Decl(negatedRecursiveKeyConstraints.ts, 1, 17)) +>T : Symbol(T, Decl(negatedRecursiveKeyConstraints.ts, 1, 15)) +>U : Symbol(U, Decl(negatedRecursiveKeyConstraints.ts, 1, 17)) + +type RecursiveRecursive : Symbol(Recursive, Decl(negatedRecursiveKeyConstraints.ts, 1, 29)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 3, 15)) + + [Key in keyof Shape]: MyExtract], { value: string }>["value"]; +>Key : Symbol(Key, Decl(negatedRecursiveKeyConstraints.ts, 4, 5)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 3, 15)) +>MyExtract : Symbol(MyExtract, Decl(negatedRecursiveKeyConstraints.ts, 0, 33)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 3, 15)) +>MyExclude : Symbol(MyExclude, Decl(negatedRecursiveKeyConstraints.ts, 0, 0)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 3, 15)) +>Key : Symbol(Key, Decl(negatedRecursiveKeyConstraints.ts, 4, 5)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 4, 73)) + +}> = Shape; +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 3, 15)) + +type Value = { value: Text }; +>Value : Symbol(Value, Decl(negatedRecursiveKeyConstraints.ts, 5, 11)) +>Text : Symbol(Text, Decl(negatedRecursiveKeyConstraints.ts, 7, 11)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 44)) +>Text : Symbol(Text, Decl(negatedRecursiveKeyConstraints.ts, 7, 11)) + +declare function value(text: Text): Value; +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 59)) +>Text : Symbol(Text, Decl(negatedRecursiveKeyConstraints.ts, 8, 23)) +>text : Symbol(text, Decl(negatedRecursiveKeyConstraints.ts, 8, 44)) +>Text : Symbol(Text, Decl(negatedRecursiveKeyConstraints.ts, 8, 23)) +>Value : Symbol(Value, Decl(negatedRecursiveKeyConstraints.ts, 5, 11)) +>Text : Symbol(Text, Decl(negatedRecursiveKeyConstraints.ts, 8, 23)) + +declare function uniqueValuesuniqueValues : Symbol(uniqueValues, Decl(negatedRecursiveKeyConstraints.ts, 8, 69)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 9, 30)) + + [Key in keyof Shape]: MyExtract["value"] extends +>Key : Symbol(Key, Decl(negatedRecursiveKeyConstraints.ts, 10, 5)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 9, 30)) +>MyExtract : Symbol(MyExtract, Decl(negatedRecursiveKeyConstraints.ts, 0, 33)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 9, 30)) +>Key : Symbol(Key, Decl(negatedRecursiveKeyConstraints.ts, 10, 5)) +>Value : Symbol(Value, Decl(negatedRecursiveKeyConstraints.ts, 5, 11)) + + MyExtract], Value>["value"] ? never : unknown; +>MyExtract : Symbol(MyExtract, Decl(negatedRecursiveKeyConstraints.ts, 0, 33)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 9, 30)) +>MyExclude : Symbol(MyExclude, Decl(negatedRecursiveKeyConstraints.ts, 0, 0)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 9, 30)) +>Key : Symbol(Key, Decl(negatedRecursiveKeyConstraints.ts, 10, 5)) +>Value : Symbol(Value, Decl(negatedRecursiveKeyConstraints.ts, 5, 11)) + +}>(shape: Shape): void; +>shape : Symbol(shape, Decl(negatedRecursiveKeyConstraints.ts, 12, 3)) +>Shape : Symbol(Shape, Decl(negatedRecursiveKeyConstraints.ts, 9, 30)) + +uniqueValues({ first: value("one"), second: value("two") }); +>uniqueValues : Symbol(uniqueValues, Decl(negatedRecursiveKeyConstraints.ts, 8, 69)) +>first : Symbol(first, Decl(negatedRecursiveKeyConstraints.ts, 14, 14)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 59)) +>second : Symbol(second, Decl(negatedRecursiveKeyConstraints.ts, 14, 35)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 59)) + +uniqueValues({ first: value("one") }); +>uniqueValues : Symbol(uniqueValues, Decl(negatedRecursiveKeyConstraints.ts, 8, 69)) +>first : Symbol(first, Decl(negatedRecursiveKeyConstraints.ts, 15, 14)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 59)) + +uniqueValues({ first: value("same"), second: value("same") }); +>uniqueValues : Symbol(uniqueValues, Decl(negatedRecursiveKeyConstraints.ts, 8, 69)) +>first : Symbol(first, Decl(negatedRecursiveKeyConstraints.ts, 16, 14)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 59)) +>second : Symbol(second, Decl(negatedRecursiveKeyConstraints.ts, 16, 36)) +>value : Symbol(value, Decl(negatedRecursiveKeyConstraints.ts, 7, 59)) + diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.types b/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.types new file mode 100644 index 0000000000000..285079151a84c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveKeyConstraints.types @@ -0,0 +1,68 @@ +//// [tests/cases/compiler/negatedRecursiveKeyConstraints.ts] //// + +=== negatedRecursiveKeyConstraints.ts === +type MyExclude = T & not U; +>MyExclude : MyExclude + +type MyExtract = T & U; +>MyExtract : MyExtract + +type RecursiveRecursive : Shape + + [Key in keyof Shape]: MyExtract], { value: string }>["value"]; +>value : string + +}> = Shape; + +type Value = { value: Text }; +>Value : Value +>value : Text + +declare function value(text: Text): Value; +>value : (text: Text) => Value +>text : Text + +declare function uniqueValuesuniqueValues : ["value"] extends MyExtract], Value>["value"] ? never : unknown; }>(shape: Shape) => void + + [Key in keyof Shape]: MyExtract["value"] extends + MyExtract], Value>["value"] ? never : unknown; +}>(shape: Shape): void; +>shape : Shape + +uniqueValues({ first: value("one"), second: value("two") }); +>uniqueValues({ first: value("one"), second: value("two") }) : void +>uniqueValues : ["value"] extends MyExtract], Value>["value"] ? never : unknown; }>(shape: Shape) => void +>{ first: value("one"), second: value("two") } : { first: Value<"one">; second: Value<"two">; } +>first : Value<"one"> +>value("one") : Value<"one"> +>value : (text: Text) => Value +>"one" : "one" +>second : Value<"two"> +>value("two") : Value<"two"> +>value : (text: Text) => Value +>"two" : "two" + +uniqueValues({ first: value("one") }); +>uniqueValues({ first: value("one") }) : void +>uniqueValues : ["value"] extends MyExtract], Value>["value"] ? never : unknown; }>(shape: Shape) => void +>{ first: value("one") } : { first: Value<"one">; } +>first : Value<"one"> +>value("one") : Value<"one"> +>value : (text: Text) => Value +>"one" : "one" + +uniqueValues({ first: value("same"), second: value("same") }); +>uniqueValues({ first: value("same"), second: value("same") }) : void +>uniqueValues : ["value"] extends MyExtract], Value>["value"] ? never : unknown; }>(shape: Shape) => void +>{ first: value("same"), second: value("same") } : { first: Value<"same">; second: Value<"same">; } +>first : Value<"same"> +>value("same") : Value<"same"> +>value : (text: Text) => Value +>"same" : "same" +>second : Value<"same"> +>value("same") : Value<"same"> +>value : (text: Text) => Value +>"same" : "same" + diff --git a/tsc/testdata/baselines/reference/compiler/negatedRecursiveTree.symbols b/tsc/testdata/baselines/reference/compiler/negatedRecursiveTree.symbols new file mode 100644 index 0000000000000..9d44aece2f890 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/negatedRecursiveTree.symbols @@ -0,0 +1,60 @@ +//// [tests/cases/compiler/negatedRecursiveTree.ts] //// + +=== negatedRecursiveTree.ts === +type Tree