diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 14745d258b733..d85a1e85fd0c1 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -406,7 +406,7 @@ export const generateExtension = task({ 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: "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" }, @@ -843,7 +843,7 @@ ${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 // 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) } @@ -1445,8 +1445,8 @@ export const validate = task({ }); async function runSmokeTest() { - await run("./built/local/tsc", ["-p", "./tsc/testdata/fixtures/compiler", "--noEmit", "--singleThreaded"]); - await run("./built/local/tsc", ["-p", "./tsc/testdata/fixtures/compiler", "--noEmit"]); + await run("./built/local/tsc", ["-p", "./tsc/testdata/fixtures/compiler", "--noEmit", "--composite", "false", "--incremental", "false", "--singleThreaded"]); + await run("./built/local/tsc", ["-p", "./tsc/testdata/fixtures/compiler", "--noEmit", "--composite", "false", "--incremental", "false"]); } export const smokeTest = task({ diff --git a/packages/typescript/src/api/async/api.ts b/packages/typescript/src/api/async/api.ts index d1e0edd52d580..112a9d340f74e 100644 --- a/packages/typescript/src/api/async/api.ts +++ b/packages/typescript/src/api/async/api.ts @@ -1900,6 +1900,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 @@ -2676,6 +2681,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; @@ -2750,6 +2756,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; @@ -2804,6 +2811,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 b07981f856361..197e9e1e34b5d 100644 --- a/packages/typescript/src/api/async/types.ts +++ b/packages/typescript/src/api/async/types.ts @@ -66,6 +66,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 df5572d9690aa..b68b758bff9b8 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 aa31609a06584..9c00ad31fb67e 100644 --- a/packages/typescript/src/api/node/node.generated.ts +++ b/packages/typescript/src/api/node/node.generated.ts @@ -546,6 +546,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 79aea215d0e3c..15a2f578d68ba 100644 --- a/packages/typescript/src/api/proto.generated.ts +++ b/packages/typescript/src/api/proto.generated.ts @@ -111,6 +111,7 @@ export interface APIMethodInfo { getApparentPropertiesOfType: APIMethod; getApparentType: APIMethod; getReducedType: APIMethod; + getNegatedType: APIMethod; getPropertyOfType: APIMethod; getTypeOfPropertyOfType: APIMethod; getIndexInfoOfType: APIMethod; @@ -1078,6 +1079,7 @@ export interface BatchRequest { | "getMembersOfSymbol" | "getModeForResolutionAtIndex" | "getModeForUsageLocation" + | "getNegatedType" | "getNeverType" | "getNonMissingTypeOfSymbol" | "getNonNullableType" @@ -1238,6 +1240,7 @@ export interface BatchResponse { | "getMembersOfSymbol" | "getModeForResolutionAtIndex" | "getModeForUsageLocation" + | "getNegatedType" | "getNeverType" | "getNonMissingTypeOfSymbol" | "getNonNullableType" diff --git a/packages/typescript/src/api/sync/api.ts b/packages/typescript/src/api/sync/api.ts index fedad5211ef02..69d834fdc3264 100644 --- a/packages/typescript/src/api/sync/api.ts +++ b/packages/typescript/src/api/sync/api.ts @@ -3866,6 +3866,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 @@ -5823,6 +5841,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; @@ -5897,6 +5916,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; @@ -6056,6 +6076,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 94ee7bc78735e..859c0a0e70053 100644 --- a/packages/typescript/src/api/sync/types.ts +++ b/packages/typescript/src/api/sync/types.ts @@ -106,6 +106,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 8ea660ad52bbf..571b39ee8f49d 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 @@ -311,6 +312,7 @@ export type TokenSyntaxKind = | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword + | SyntaxKind.NotKeyword | SyntaxKind.OutKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword @@ -962,7 +964,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 fa11c564e585f..f48c7887fa6d3 100644 --- a/packages/typescript/src/ast/factory.generated.ts +++ b/packages/typescript/src/ast/factory.generated.ts @@ -2477,7 +2477,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 63ed4e4d3c93f..e4b4bc90ab436 100644 --- a/packages/typescript/src/enums/objectFlags.enum.ts +++ b/packages/typescript/src/enums/objectFlags.enum.ts @@ -50,4 +50,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 1c17a70d5f797..5b364b40213a5 100644 --- a/packages/typescript/src/enums/objectFlags.ts +++ b/packages/typescript/src/enums/objectFlags.ts @@ -50,4 +50,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 400c16806abf5..7e1f4279882a2 100644 --- a/packages/typescript/src/enums/syntaxKind.enum.ts +++ b/packages/typescript/src/enums/syntaxKind.enum.ts @@ -148,211 +148,212 @@ 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, - QualifiedName = 167, - ComputedPropertyName = 168, - TypeParameter = 169, - Parameter = 170, - Decorator = 171, - PropertySignature = 172, - PropertyDeclaration = 173, - MethodSignature = 174, - MethodDeclaration = 175, - ClassStaticBlockDeclaration = 176, - Constructor = 177, - GetAccessor = 178, - SetAccessor = 179, - CallSignature = 180, - ConstructSignature = 181, - IndexSignature = 182, - TypePredicate = 183, - TypeReference = 184, - FunctionType = 185, - ConstructorType = 186, - TypeQuery = 187, - TypeLiteral = 188, - ArrayType = 189, - TupleType = 190, - OptionalType = 191, - RestType = 192, - UnionType = 193, - IntersectionType = 194, - ConditionalType = 195, - InferType = 196, - ParenthesizedType = 197, - ThisType = 198, - TypeOperator = 199, - IndexedAccessType = 200, - MappedType = 201, - LiteralType = 202, - NamedTupleMember = 203, - TemplateLiteralType = 204, - TemplateLiteralTypeSpan = 205, - ImportType = 206, - ObjectBindingPattern = 207, - ArrayBindingPattern = 208, - BindingElement = 209, - ArrayLiteralExpression = 210, - ObjectLiteralExpression = 211, - PropertyAccessExpression = 212, - ElementAccessExpression = 213, - CallExpression = 214, - NewExpression = 215, - TaggedTemplateExpression = 216, - TypeAssertionExpression = 217, - ParenthesizedExpression = 218, - FunctionExpression = 219, - ArrowFunction = 220, - DeleteExpression = 221, - TypeOfExpression = 222, - VoidExpression = 223, - AwaitExpression = 224, - PrefixUnaryExpression = 225, - PostfixUnaryExpression = 226, - BinaryExpression = 227, - ConditionalExpression = 228, - TemplateExpression = 229, - YieldExpression = 230, - SpreadElement = 231, - ClassExpression = 232, - OmittedExpression = 233, - ExpressionWithTypeArguments = 234, - AsExpression = 235, - NonNullExpression = 236, - MetaProperty = 237, - SyntheticExpression = 238, - SatisfiesExpression = 239, - TemplateSpan = 240, - SemicolonClassElement = 241, - Block = 242, - EmptyStatement = 243, - VariableStatement = 244, - ExpressionStatement = 245, - IfStatement = 246, - DoStatement = 247, - WhileStatement = 248, - ForStatement = 249, - ForInStatement = 250, - ForOfStatement = 251, - ContinueStatement = 252, - BreakStatement = 253, - ReturnStatement = 254, - WithStatement = 255, - SwitchStatement = 256, - LabeledStatement = 257, - ThrowStatement = 258, - TryStatement = 259, - DebuggerStatement = 260, - VariableDeclaration = 261, - VariableDeclarationList = 262, - FunctionDeclaration = 263, - ClassDeclaration = 264, - InterfaceDeclaration = 265, - TypeAliasDeclaration = 266, - EnumDeclaration = 267, - ModuleDeclaration = 268, - ModuleBlock = 269, - CaseBlock = 270, - NamespaceExportDeclaration = 271, - ImportEqualsDeclaration = 272, - ImportDeclaration = 273, - ImportClause = 274, - NamespaceImport = 275, - NamedImports = 276, - ImportSpecifier = 277, - ExportAssignment = 278, - ExportDeclaration = 279, - NamedExports = 280, - NamespaceExport = 281, - ExportSpecifier = 282, - MissingDeclaration = 283, - ExternalModuleReference = 284, - JsxElement = 285, - JsxSelfClosingElement = 286, - JsxOpeningElement = 287, - JsxClosingElement = 288, - JsxFragment = 289, - JsxOpeningFragment = 290, - JsxClosingFragment = 291, - JsxAttribute = 292, - JsxAttributes = 293, - JsxSpreadAttribute = 294, - JsxExpression = 295, - JsxNamespacedName = 296, - CaseClause = 297, - DefaultClause = 298, - HeritageClause = 299, - CatchClause = 300, - ImportAttributes = 301, - ImportAttribute = 302, - PropertyAssignment = 303, - ShorthandPropertyAssignment = 304, - SpreadAssignment = 305, - EnumMember = 306, - SourceFile = 307, - JSDocTypeExpression = 308, - JSDocNameReference = 309, - JSDocAllType = 310, - JSDocNullableType = 311, - JSDocNonNullableType = 312, - JSDocOptionalType = 313, - JSDocVariadicType = 314, - JSDoc = 315, - JSDocText = 316, - JSDocTypeLiteral = 317, - JSDocSignature = 318, - JSDocLink = 319, - JSDocLinkCode = 320, - JSDocLinkPlain = 321, - JSDocUnknownTag = 322, - JSDocAugmentsTag = 323, - JSDocImplementsTag = 324, - JSDocDeprecatedTag = 325, - JSDocPublicTag = 326, - JSDocPrivateTag = 327, - JSDocProtectedTag = 328, - JSDocReadonlyTag = 329, - JSDocOverrideTag = 330, - JSDocCallbackTag = 331, - JSDocOverloadTag = 332, - JSDocParameterTag = 333, - JSDocReturnTag = 334, - JSDocThisTag = 335, - JSDocTypeTag = 336, - JSDocTemplateTag = 337, - JSDocTypedefTag = 338, - JSDocSeeTag = 339, - JSDocPropertyTag = 340, - JSDocThrowsTag = 341, - JSDocSatisfiesTag = 342, - JSDocImportTag = 343, - SyntaxList = 344, - JSTypeAliasDeclaration = 345, - JSImportDeclaration = 346, - NotEmittedStatement = 347, - PartiallyEmittedExpression = 348, - SyntheticReferenceExpression = 349, - NotEmittedTypeElement = 350, - Count = 351, + 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, + 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, FirstAssignment = EqualsToken, LastAssignment = CaretEqualsToken, FirstCompoundAssignment = PlusEqualsToken, diff --git a/packages/typescript/src/enums/syntaxKind.ts b/packages/typescript/src/enums/syntaxKind.ts index 87c2385c7cd47..827e56ced07f4 100644 --- a/packages/typescript/src/enums/syntaxKind.ts +++ b/packages/typescript/src/enums/syntaxKind.ts @@ -148,211 +148,212 @@ 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["QualifiedName"] = 167] = "QualifiedName"; - SyntaxKind[SyntaxKind["ComputedPropertyName"] = 168] = "ComputedPropertyName"; - SyntaxKind[SyntaxKind["TypeParameter"] = 169] = "TypeParameter"; - SyntaxKind[SyntaxKind["Parameter"] = 170] = "Parameter"; - SyntaxKind[SyntaxKind["Decorator"] = 171] = "Decorator"; - SyntaxKind[SyntaxKind["PropertySignature"] = 172] = "PropertySignature"; - SyntaxKind[SyntaxKind["PropertyDeclaration"] = 173] = "PropertyDeclaration"; - SyntaxKind[SyntaxKind["MethodSignature"] = 174] = "MethodSignature"; - SyntaxKind[SyntaxKind["MethodDeclaration"] = 175] = "MethodDeclaration"; - SyntaxKind[SyntaxKind["ClassStaticBlockDeclaration"] = 176] = "ClassStaticBlockDeclaration"; - SyntaxKind[SyntaxKind["Constructor"] = 177] = "Constructor"; - SyntaxKind[SyntaxKind["GetAccessor"] = 178] = "GetAccessor"; - SyntaxKind[SyntaxKind["SetAccessor"] = 179] = "SetAccessor"; - SyntaxKind[SyntaxKind["CallSignature"] = 180] = "CallSignature"; - SyntaxKind[SyntaxKind["ConstructSignature"] = 181] = "ConstructSignature"; - SyntaxKind[SyntaxKind["IndexSignature"] = 182] = "IndexSignature"; - SyntaxKind[SyntaxKind["TypePredicate"] = 183] = "TypePredicate"; - SyntaxKind[SyntaxKind["TypeReference"] = 184] = "TypeReference"; - SyntaxKind[SyntaxKind["FunctionType"] = 185] = "FunctionType"; - SyntaxKind[SyntaxKind["ConstructorType"] = 186] = "ConstructorType"; - SyntaxKind[SyntaxKind["TypeQuery"] = 187] = "TypeQuery"; - SyntaxKind[SyntaxKind["TypeLiteral"] = 188] = "TypeLiteral"; - SyntaxKind[SyntaxKind["ArrayType"] = 189] = "ArrayType"; - SyntaxKind[SyntaxKind["TupleType"] = 190] = "TupleType"; - SyntaxKind[SyntaxKind["OptionalType"] = 191] = "OptionalType"; - SyntaxKind[SyntaxKind["RestType"] = 192] = "RestType"; - SyntaxKind[SyntaxKind["UnionType"] = 193] = "UnionType"; - SyntaxKind[SyntaxKind["IntersectionType"] = 194] = "IntersectionType"; - SyntaxKind[SyntaxKind["ConditionalType"] = 195] = "ConditionalType"; - SyntaxKind[SyntaxKind["InferType"] = 196] = "InferType"; - SyntaxKind[SyntaxKind["ParenthesizedType"] = 197] = "ParenthesizedType"; - SyntaxKind[SyntaxKind["ThisType"] = 198] = "ThisType"; - SyntaxKind[SyntaxKind["TypeOperator"] = 199] = "TypeOperator"; - SyntaxKind[SyntaxKind["IndexedAccessType"] = 200] = "IndexedAccessType"; - SyntaxKind[SyntaxKind["MappedType"] = 201] = "MappedType"; - SyntaxKind[SyntaxKind["LiteralType"] = 202] = "LiteralType"; - SyntaxKind[SyntaxKind["NamedTupleMember"] = 203] = "NamedTupleMember"; - SyntaxKind[SyntaxKind["TemplateLiteralType"] = 204] = "TemplateLiteralType"; - SyntaxKind[SyntaxKind["TemplateLiteralTypeSpan"] = 205] = "TemplateLiteralTypeSpan"; - SyntaxKind[SyntaxKind["ImportType"] = 206] = "ImportType"; - SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 207] = "ObjectBindingPattern"; - SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 208] = "ArrayBindingPattern"; - SyntaxKind[SyntaxKind["BindingElement"] = 209] = "BindingElement"; - SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 210] = "ArrayLiteralExpression"; - SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 211] = "ObjectLiteralExpression"; - SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 212] = "PropertyAccessExpression"; - SyntaxKind[SyntaxKind["ElementAccessExpression"] = 213] = "ElementAccessExpression"; - SyntaxKind[SyntaxKind["CallExpression"] = 214] = "CallExpression"; - SyntaxKind[SyntaxKind["NewExpression"] = 215] = "NewExpression"; - SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 216] = "TaggedTemplateExpression"; - SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 217] = "TypeAssertionExpression"; - SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 218] = "ParenthesizedExpression"; - SyntaxKind[SyntaxKind["FunctionExpression"] = 219] = "FunctionExpression"; - SyntaxKind[SyntaxKind["ArrowFunction"] = 220] = "ArrowFunction"; - SyntaxKind[SyntaxKind["DeleteExpression"] = 221] = "DeleteExpression"; - SyntaxKind[SyntaxKind["TypeOfExpression"] = 222] = "TypeOfExpression"; - SyntaxKind[SyntaxKind["VoidExpression"] = 223] = "VoidExpression"; - SyntaxKind[SyntaxKind["AwaitExpression"] = 224] = "AwaitExpression"; - SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 225] = "PrefixUnaryExpression"; - SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 226] = "PostfixUnaryExpression"; - SyntaxKind[SyntaxKind["BinaryExpression"] = 227] = "BinaryExpression"; - SyntaxKind[SyntaxKind["ConditionalExpression"] = 228] = "ConditionalExpression"; - SyntaxKind[SyntaxKind["TemplateExpression"] = 229] = "TemplateExpression"; - SyntaxKind[SyntaxKind["YieldExpression"] = 230] = "YieldExpression"; - SyntaxKind[SyntaxKind["SpreadElement"] = 231] = "SpreadElement"; - SyntaxKind[SyntaxKind["ClassExpression"] = 232] = "ClassExpression"; - SyntaxKind[SyntaxKind["OmittedExpression"] = 233] = "OmittedExpression"; - SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 234] = "ExpressionWithTypeArguments"; - SyntaxKind[SyntaxKind["AsExpression"] = 235] = "AsExpression"; - SyntaxKind[SyntaxKind["NonNullExpression"] = 236] = "NonNullExpression"; - SyntaxKind[SyntaxKind["MetaProperty"] = 237] = "MetaProperty"; - SyntaxKind[SyntaxKind["SyntheticExpression"] = 238] = "SyntheticExpression"; - SyntaxKind[SyntaxKind["SatisfiesExpression"] = 239] = "SatisfiesExpression"; - SyntaxKind[SyntaxKind["TemplateSpan"] = 240] = "TemplateSpan"; - SyntaxKind[SyntaxKind["SemicolonClassElement"] = 241] = "SemicolonClassElement"; - SyntaxKind[SyntaxKind["Block"] = 242] = "Block"; - SyntaxKind[SyntaxKind["EmptyStatement"] = 243] = "EmptyStatement"; - SyntaxKind[SyntaxKind["VariableStatement"] = 244] = "VariableStatement"; - SyntaxKind[SyntaxKind["ExpressionStatement"] = 245] = "ExpressionStatement"; - SyntaxKind[SyntaxKind["IfStatement"] = 246] = "IfStatement"; - SyntaxKind[SyntaxKind["DoStatement"] = 247] = "DoStatement"; - SyntaxKind[SyntaxKind["WhileStatement"] = 248] = "WhileStatement"; - SyntaxKind[SyntaxKind["ForStatement"] = 249] = "ForStatement"; - SyntaxKind[SyntaxKind["ForInStatement"] = 250] = "ForInStatement"; - SyntaxKind[SyntaxKind["ForOfStatement"] = 251] = "ForOfStatement"; - SyntaxKind[SyntaxKind["ContinueStatement"] = 252] = "ContinueStatement"; - SyntaxKind[SyntaxKind["BreakStatement"] = 253] = "BreakStatement"; - SyntaxKind[SyntaxKind["ReturnStatement"] = 254] = "ReturnStatement"; - SyntaxKind[SyntaxKind["WithStatement"] = 255] = "WithStatement"; - SyntaxKind[SyntaxKind["SwitchStatement"] = 256] = "SwitchStatement"; - SyntaxKind[SyntaxKind["LabeledStatement"] = 257] = "LabeledStatement"; - SyntaxKind[SyntaxKind["ThrowStatement"] = 258] = "ThrowStatement"; - SyntaxKind[SyntaxKind["TryStatement"] = 259] = "TryStatement"; - SyntaxKind[SyntaxKind["DebuggerStatement"] = 260] = "DebuggerStatement"; - SyntaxKind[SyntaxKind["VariableDeclaration"] = 261] = "VariableDeclaration"; - SyntaxKind[SyntaxKind["VariableDeclarationList"] = 262] = "VariableDeclarationList"; - SyntaxKind[SyntaxKind["FunctionDeclaration"] = 263] = "FunctionDeclaration"; - SyntaxKind[SyntaxKind["ClassDeclaration"] = 264] = "ClassDeclaration"; - SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 265] = "InterfaceDeclaration"; - SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 266] = "TypeAliasDeclaration"; - SyntaxKind[SyntaxKind["EnumDeclaration"] = 267] = "EnumDeclaration"; - SyntaxKind[SyntaxKind["ModuleDeclaration"] = 268] = "ModuleDeclaration"; - SyntaxKind[SyntaxKind["ModuleBlock"] = 269] = "ModuleBlock"; - SyntaxKind[SyntaxKind["CaseBlock"] = 270] = "CaseBlock"; - SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 271] = "NamespaceExportDeclaration"; - SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 272] = "ImportEqualsDeclaration"; - SyntaxKind[SyntaxKind["ImportDeclaration"] = 273] = "ImportDeclaration"; - SyntaxKind[SyntaxKind["ImportClause"] = 274] = "ImportClause"; - SyntaxKind[SyntaxKind["NamespaceImport"] = 275] = "NamespaceImport"; - SyntaxKind[SyntaxKind["NamedImports"] = 276] = "NamedImports"; - SyntaxKind[SyntaxKind["ImportSpecifier"] = 277] = "ImportSpecifier"; - SyntaxKind[SyntaxKind["ExportAssignment"] = 278] = "ExportAssignment"; - SyntaxKind[SyntaxKind["ExportDeclaration"] = 279] = "ExportDeclaration"; - SyntaxKind[SyntaxKind["NamedExports"] = 280] = "NamedExports"; - SyntaxKind[SyntaxKind["NamespaceExport"] = 281] = "NamespaceExport"; - SyntaxKind[SyntaxKind["ExportSpecifier"] = 282] = "ExportSpecifier"; - SyntaxKind[SyntaxKind["MissingDeclaration"] = 283] = "MissingDeclaration"; - SyntaxKind[SyntaxKind["ExternalModuleReference"] = 284] = "ExternalModuleReference"; - SyntaxKind[SyntaxKind["JsxElement"] = 285] = "JsxElement"; - SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 286] = "JsxSelfClosingElement"; - SyntaxKind[SyntaxKind["JsxOpeningElement"] = 287] = "JsxOpeningElement"; - SyntaxKind[SyntaxKind["JsxClosingElement"] = 288] = "JsxClosingElement"; - SyntaxKind[SyntaxKind["JsxFragment"] = 289] = "JsxFragment"; - SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 290] = "JsxOpeningFragment"; - SyntaxKind[SyntaxKind["JsxClosingFragment"] = 291] = "JsxClosingFragment"; - SyntaxKind[SyntaxKind["JsxAttribute"] = 292] = "JsxAttribute"; - SyntaxKind[SyntaxKind["JsxAttributes"] = 293] = "JsxAttributes"; - SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 294] = "JsxSpreadAttribute"; - SyntaxKind[SyntaxKind["JsxExpression"] = 295] = "JsxExpression"; - SyntaxKind[SyntaxKind["JsxNamespacedName"] = 296] = "JsxNamespacedName"; - SyntaxKind[SyntaxKind["CaseClause"] = 297] = "CaseClause"; - SyntaxKind[SyntaxKind["DefaultClause"] = 298] = "DefaultClause"; - SyntaxKind[SyntaxKind["HeritageClause"] = 299] = "HeritageClause"; - SyntaxKind[SyntaxKind["CatchClause"] = 300] = "CatchClause"; - SyntaxKind[SyntaxKind["ImportAttributes"] = 301] = "ImportAttributes"; - SyntaxKind[SyntaxKind["ImportAttribute"] = 302] = "ImportAttribute"; - SyntaxKind[SyntaxKind["PropertyAssignment"] = 303] = "PropertyAssignment"; - SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 304] = "ShorthandPropertyAssignment"; - SyntaxKind[SyntaxKind["SpreadAssignment"] = 305] = "SpreadAssignment"; - SyntaxKind[SyntaxKind["EnumMember"] = 306] = "EnumMember"; - SyntaxKind[SyntaxKind["SourceFile"] = 307] = "SourceFile"; - SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 308] = "JSDocTypeExpression"; - SyntaxKind[SyntaxKind["JSDocNameReference"] = 309] = "JSDocNameReference"; - SyntaxKind[SyntaxKind["JSDocAllType"] = 310] = "JSDocAllType"; - SyntaxKind[SyntaxKind["JSDocNullableType"] = 311] = "JSDocNullableType"; - SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 312] = "JSDocNonNullableType"; - SyntaxKind[SyntaxKind["JSDocOptionalType"] = 313] = "JSDocOptionalType"; - SyntaxKind[SyntaxKind["JSDocVariadicType"] = 314] = "JSDocVariadicType"; - SyntaxKind[SyntaxKind["JSDoc"] = 315] = "JSDoc"; - SyntaxKind[SyntaxKind["JSDocText"] = 316] = "JSDocText"; - SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 317] = "JSDocTypeLiteral"; - SyntaxKind[SyntaxKind["JSDocSignature"] = 318] = "JSDocSignature"; - SyntaxKind[SyntaxKind["JSDocLink"] = 319] = "JSDocLink"; - SyntaxKind[SyntaxKind["JSDocLinkCode"] = 320] = "JSDocLinkCode"; - SyntaxKind[SyntaxKind["JSDocLinkPlain"] = 321] = "JSDocLinkPlain"; - SyntaxKind[SyntaxKind["JSDocUnknownTag"] = 322] = "JSDocUnknownTag"; - SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 323] = "JSDocAugmentsTag"; - SyntaxKind[SyntaxKind["JSDocImplementsTag"] = 324] = "JSDocImplementsTag"; - SyntaxKind[SyntaxKind["JSDocDeprecatedTag"] = 325] = "JSDocDeprecatedTag"; - SyntaxKind[SyntaxKind["JSDocPublicTag"] = 326] = "JSDocPublicTag"; - SyntaxKind[SyntaxKind["JSDocPrivateTag"] = 327] = "JSDocPrivateTag"; - SyntaxKind[SyntaxKind["JSDocProtectedTag"] = 328] = "JSDocProtectedTag"; - SyntaxKind[SyntaxKind["JSDocReadonlyTag"] = 329] = "JSDocReadonlyTag"; - SyntaxKind[SyntaxKind["JSDocOverrideTag"] = 330] = "JSDocOverrideTag"; - SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 331] = "JSDocCallbackTag"; - SyntaxKind[SyntaxKind["JSDocOverloadTag"] = 332] = "JSDocOverloadTag"; - SyntaxKind[SyntaxKind["JSDocParameterTag"] = 333] = "JSDocParameterTag"; - SyntaxKind[SyntaxKind["JSDocReturnTag"] = 334] = "JSDocReturnTag"; - SyntaxKind[SyntaxKind["JSDocThisTag"] = 335] = "JSDocThisTag"; - SyntaxKind[SyntaxKind["JSDocTypeTag"] = 336] = "JSDocTypeTag"; - SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 337] = "JSDocTemplateTag"; - SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 338] = "JSDocTypedefTag"; - SyntaxKind[SyntaxKind["JSDocSeeTag"] = 339] = "JSDocSeeTag"; - SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 340] = "JSDocPropertyTag"; - SyntaxKind[SyntaxKind["JSDocThrowsTag"] = 341] = "JSDocThrowsTag"; - SyntaxKind[SyntaxKind["JSDocSatisfiesTag"] = 342] = "JSDocSatisfiesTag"; - SyntaxKind[SyntaxKind["JSDocImportTag"] = 343] = "JSDocImportTag"; - SyntaxKind[SyntaxKind["SyntaxList"] = 344] = "SyntaxList"; - SyntaxKind[SyntaxKind["JSTypeAliasDeclaration"] = 345] = "JSTypeAliasDeclaration"; - SyntaxKind[SyntaxKind["JSImportDeclaration"] = 346] = "JSImportDeclaration"; - SyntaxKind[SyntaxKind["NotEmittedStatement"] = 347] = "NotEmittedStatement"; - SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 348] = "PartiallyEmittedExpression"; - SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 349] = "SyntheticReferenceExpression"; - SyntaxKind[SyntaxKind["NotEmittedTypeElement"] = 350] = "NotEmittedTypeElement"; - SyntaxKind[SyntaxKind["Count"] = 351] = "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["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["FirstAssignment"] = 63] = "FirstAssignment"; SyntaxKind[SyntaxKind["LastAssignment"] = 78] = "LastAssignment"; SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 64] = "FirstCompoundAssignment"; @@ -360,30 +361,30 @@ export var SyntaxKind: any; SyntaxKind[SyntaxKind["FirstReservedWord"] = 82] = "FirstReservedWord"; SyntaxKind[SyntaxKind["LastReservedWord"] = 117] = "LastReservedWord"; SyntaxKind[SyntaxKind["FirstKeyword"] = 82] = "FirstKeyword"; - SyntaxKind[SyntaxKind["LastKeyword"] = 166] = "LastKeyword"; + SyntaxKind[SyntaxKind["LastKeyword"] = 167] = "LastKeyword"; SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 118] = "FirstFutureReservedWord"; SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 126] = "LastFutureReservedWord"; - SyntaxKind[SyntaxKind["FirstTypeNode"] = 183] = "FirstTypeNode"; - SyntaxKind[SyntaxKind["LastTypeNode"] = 206] = "LastTypeNode"; + SyntaxKind[SyntaxKind["FirstTypeNode"] = 184] = "FirstTypeNode"; + SyntaxKind[SyntaxKind["LastTypeNode"] = 207] = "LastTypeNode"; SyntaxKind[SyntaxKind["FirstPunctuation"] = 18] = "FirstPunctuation"; SyntaxKind[SyntaxKind["LastPunctuation"] = 78] = "LastPunctuation"; SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken"; - SyntaxKind[SyntaxKind["LastToken"] = 166] = "LastToken"; + SyntaxKind[SyntaxKind["LastToken"] = 167] = "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"] = 244] = "FirstStatement"; - SyntaxKind[SyntaxKind["LastStatement"] = 260] = "LastStatement"; - SyntaxKind[SyntaxKind["FirstNode"] = 167] = "FirstNode"; - SyntaxKind[SyntaxKind["FirstJSDocNode"] = 308] = "FirstJSDocNode"; - SyntaxKind[SyntaxKind["LastJSDocNode"] = 343] = "LastJSDocNode"; - SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 322] = "FirstJSDocTagNode"; - SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 343] = "LastJSDocTagNode"; + 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["FirstContextualKeyword"] = 127] = "FirstContextualKeyword"; - SyntaxKind[SyntaxKind["LastContextualKeyword"] = 166] = "LastContextualKeyword"; + SyntaxKind[SyntaxKind["LastContextualKeyword"] = 167] = "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 88701e2174f55..2ed6e3f301db6 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 01fbbcbdeaca5..d3d49ba365786 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 e9f72d62974c2..24c77efb0a5e2 100644 --- a/packages/typescript/test/async/api.test.ts +++ b/packages/typescript/test/async/api.test.ts @@ -2220,6 +2220,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 73b7c13a728cd..52317db0424bc 100644 --- a/packages/typescript/test/sync/api-generators.test.ts +++ b/packages/typescript/test/sync/api-generators.test.ts @@ -1615,6 +1615,7 @@ describe("API - generator batching", () => { 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), @@ -1663,6 +1664,7 @@ describe("API - generator batching", () => { 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 e152579a1e2f6..ac62d8644264b 100644 --- a/packages/typescript/test/sync/api.test.ts +++ b/packages/typescript/test/sync/api.test.ts @@ -2088,6 +2088,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 d15f18aa35b81..075183791584a 100644 --- a/tools/scripts/tsc/ast.json +++ b/tools/scripts/tsc/ast.json @@ -176,6 +176,7 @@ "ModuleKeyword", "NamespaceKeyword", "NeverKeyword", + "NotKeyword", "OutKeyword", "ReadonlyKeyword", "RequireKeyword", @@ -3547,7 +3548,8 @@ "type": [ "SyntaxKind.KeyOfKeyword", "SyntaxKind.ReadonlyKeyword", - "SyntaxKind.UniqueKeyword" + "SyntaxKind.UniqueKeyword", + "SyntaxKind.NotKeyword" ] }, { diff --git a/tsc/internal/api/encoder/decoder_generated.go b/tsc/internal/api/encoder/decoder_generated.go index ff5b23cc06f22..20138a703147f 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, @@ -750,6 +751,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 b4a9021b6cd0b..185ec5813f31e 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 678051b687573..e347ba54b6a56 100644 --- a/tsc/internal/api/enum_values_generated.go +++ b/tsc/internal/api/enum_values_generated.go @@ -127,79 +127,75 @@ func main() { "Partial": toInt32(ast.CheckFlagsPartial), }, "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), @@ -251,6 +247,7 @@ func main() { "IsNeverIntersectionComputed": toInt32(checker.ObjectFlagsIsNeverIntersectionComputed), "IsNeverIntersection": toInt32(checker.ObjectFlagsIsNeverIntersection), "IsConstrainedTypeVariable": toInt32(checker.ObjectFlagsIsConstrainedTypeVariable), + "FreshNegated": toInt32(checker.ObjectFlagsFreshNegated), }, "SignatureFlags": { "None": toInt32(checker.SignatureFlagsNone), @@ -473,6 +470,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), @@ -1007,6 +1005,6 @@ 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 // 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 99185eaff8c76..38b9c9a8ebace 100644 --- a/tsc/internal/api/proto.go +++ b/tsc/internal/api/proto.go @@ -167,6 +167,7 @@ const ( MethodGetApparentPropertiesOfType Method = "getApparentPropertiesOfType" MethodGetApparentType Method = "getApparentType" MethodGetReducedType Method = "getReducedType" + MethodGetNegatedType Method = "getNegatedType" MethodGetPropertyOfType Method = "getPropertyOfType" MethodGetTypeOfPropertyOfType Method = "getTypeOfPropertyOfType" MethodGetIndexInfoOfType Method = "getIndexInfoOfType" @@ -552,6 +553,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 b1156f5b1f93e..c9fe4c5b0eea1 100644 --- a/tsc/internal/api/session.go +++ b/tsc/internal/api/session.go @@ -956,6 +956,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): @@ -3671,6 +3673,22 @@ func (s *Session) handleGetReducedType(ctx context.Context, params *GetTypePrope return setup.newTypeResponse(setup.checker.GetReducedType(t)), 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.newTypeResponse(setup.checker.GetNegatedType(t)), 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 ea7b17ee4cb47..9c87aa63db228 100644 --- a/tsc/internal/ast/ast_generated.go +++ b/tsc/internal/ast/ast_generated.go @@ -608,7 +608,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: + 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: return true } return false diff --git a/tsc/internal/ast/kind_generated.go b/tsc/internal/ast/kind_generated.go index 8c67e7947572f..5d82338431b51 100644 --- a/tsc/internal/ast/kind_generated.go +++ b/tsc/internal/ast/kind_generated.go @@ -164,6 +164,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 + 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 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 + 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 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 diff --git a/tsc/internal/ast/kind_stringer_generated.go b/tsc/internal/ast/kind_stringer_generated.go index b80f1ba531982..90fd1ce2500e5 100644 --- a/tsc/internal/ast/kind_stringer_generated.go +++ b/tsc/internal/ast/kind_stringer_generated.go @@ -155,216 +155,217 @@ 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[KindQualifiedName-167] - _ = x[KindComputedPropertyName-168] - _ = x[KindTypeParameter-169] - _ = x[KindParameter-170] - _ = x[KindDecorator-171] - _ = x[KindPropertySignature-172] - _ = x[KindPropertyDeclaration-173] - _ = x[KindMethodSignature-174] - _ = x[KindMethodDeclaration-175] - _ = x[KindClassStaticBlockDeclaration-176] - _ = x[KindConstructor-177] - _ = x[KindGetAccessor-178] - _ = x[KindSetAccessor-179] - _ = x[KindCallSignature-180] - _ = x[KindConstructSignature-181] - _ = x[KindIndexSignature-182] - _ = x[KindTypePredicate-183] - _ = x[KindTypeReference-184] - _ = x[KindFunctionType-185] - _ = x[KindConstructorType-186] - _ = x[KindTypeQuery-187] - _ = x[KindTypeLiteral-188] - _ = x[KindArrayType-189] - _ = x[KindTupleType-190] - _ = x[KindOptionalType-191] - _ = x[KindRestType-192] - _ = x[KindUnionType-193] - _ = x[KindIntersectionType-194] - _ = x[KindConditionalType-195] - _ = x[KindInferType-196] - _ = x[KindParenthesizedType-197] - _ = x[KindThisType-198] - _ = x[KindTypeOperator-199] - _ = x[KindIndexedAccessType-200] - _ = x[KindMappedType-201] - _ = x[KindLiteralType-202] - _ = x[KindNamedTupleMember-203] - _ = x[KindTemplateLiteralType-204] - _ = x[KindTemplateLiteralTypeSpan-205] - _ = x[KindImportType-206] - _ = x[KindObjectBindingPattern-207] - _ = x[KindArrayBindingPattern-208] - _ = x[KindBindingElement-209] - _ = x[KindArrayLiteralExpression-210] - _ = x[KindObjectLiteralExpression-211] - _ = x[KindPropertyAccessExpression-212] - _ = x[KindElementAccessExpression-213] - _ = x[KindCallExpression-214] - _ = x[KindNewExpression-215] - _ = x[KindTaggedTemplateExpression-216] - _ = x[KindTypeAssertionExpression-217] - _ = x[KindParenthesizedExpression-218] - _ = x[KindFunctionExpression-219] - _ = x[KindArrowFunction-220] - _ = x[KindDeleteExpression-221] - _ = x[KindTypeOfExpression-222] - _ = x[KindVoidExpression-223] - _ = x[KindAwaitExpression-224] - _ = x[KindPrefixUnaryExpression-225] - _ = x[KindPostfixUnaryExpression-226] - _ = x[KindBinaryExpression-227] - _ = x[KindConditionalExpression-228] - _ = x[KindTemplateExpression-229] - _ = x[KindYieldExpression-230] - _ = x[KindSpreadElement-231] - _ = x[KindClassExpression-232] - _ = x[KindOmittedExpression-233] - _ = x[KindExpressionWithTypeArguments-234] - _ = x[KindAsExpression-235] - _ = x[KindNonNullExpression-236] - _ = x[KindMetaProperty-237] - _ = x[KindSyntheticExpression-238] - _ = x[KindSatisfiesExpression-239] - _ = x[KindTemplateSpan-240] - _ = x[KindSemicolonClassElement-241] - _ = x[KindBlock-242] - _ = x[KindEmptyStatement-243] - _ = x[KindVariableStatement-244] - _ = x[KindExpressionStatement-245] - _ = x[KindIfStatement-246] - _ = x[KindDoStatement-247] - _ = x[KindWhileStatement-248] - _ = x[KindForStatement-249] - _ = x[KindForInStatement-250] - _ = x[KindForOfStatement-251] - _ = x[KindContinueStatement-252] - _ = x[KindBreakStatement-253] - _ = x[KindReturnStatement-254] - _ = x[KindWithStatement-255] - _ = x[KindSwitchStatement-256] - _ = x[KindLabeledStatement-257] - _ = x[KindThrowStatement-258] - _ = x[KindTryStatement-259] - _ = x[KindDebuggerStatement-260] - _ = x[KindVariableDeclaration-261] - _ = x[KindVariableDeclarationList-262] - _ = x[KindFunctionDeclaration-263] - _ = x[KindClassDeclaration-264] - _ = x[KindInterfaceDeclaration-265] - _ = x[KindTypeAliasDeclaration-266] - _ = x[KindEnumDeclaration-267] - _ = x[KindModuleDeclaration-268] - _ = x[KindModuleBlock-269] - _ = x[KindCaseBlock-270] - _ = x[KindNamespaceExportDeclaration-271] - _ = x[KindImportEqualsDeclaration-272] - _ = x[KindImportDeclaration-273] - _ = x[KindImportClause-274] - _ = x[KindNamespaceImport-275] - _ = x[KindNamedImports-276] - _ = x[KindImportSpecifier-277] - _ = x[KindExportAssignment-278] - _ = x[KindExportDeclaration-279] - _ = x[KindNamedExports-280] - _ = x[KindNamespaceExport-281] - _ = x[KindExportSpecifier-282] - _ = x[KindMissingDeclaration-283] - _ = x[KindExternalModuleReference-284] - _ = x[KindJsxElement-285] - _ = x[KindJsxSelfClosingElement-286] - _ = x[KindJsxOpeningElement-287] - _ = x[KindJsxClosingElement-288] - _ = x[KindJsxFragment-289] - _ = x[KindJsxOpeningFragment-290] - _ = x[KindJsxClosingFragment-291] - _ = x[KindJsxAttribute-292] - _ = x[KindJsxAttributes-293] - _ = x[KindJsxSpreadAttribute-294] - _ = x[KindJsxExpression-295] - _ = x[KindJsxNamespacedName-296] - _ = x[KindCaseClause-297] - _ = x[KindDefaultClause-298] - _ = x[KindHeritageClause-299] - _ = x[KindCatchClause-300] - _ = x[KindImportAttributes-301] - _ = x[KindImportAttribute-302] - _ = x[KindPropertyAssignment-303] - _ = x[KindShorthandPropertyAssignment-304] - _ = x[KindSpreadAssignment-305] - _ = x[KindEnumMember-306] - _ = x[KindSourceFile-307] - _ = x[KindJSDocTypeExpression-308] - _ = x[KindJSDocNameReference-309] - _ = x[KindJSDocAllType-310] - _ = x[KindJSDocNullableType-311] - _ = x[KindJSDocNonNullableType-312] - _ = x[KindJSDocOptionalType-313] - _ = x[KindJSDocVariadicType-314] - _ = x[KindJSDoc-315] - _ = x[KindJSDocText-316] - _ = x[KindJSDocTypeLiteral-317] - _ = x[KindJSDocSignature-318] - _ = x[KindJSDocLink-319] - _ = x[KindJSDocLinkCode-320] - _ = x[KindJSDocLinkPlain-321] - _ = x[KindJSDocUnknownTag-322] - _ = x[KindJSDocAugmentsTag-323] - _ = x[KindJSDocImplementsTag-324] - _ = x[KindJSDocDeprecatedTag-325] - _ = x[KindJSDocPublicTag-326] - _ = x[KindJSDocPrivateTag-327] - _ = x[KindJSDocProtectedTag-328] - _ = x[KindJSDocReadonlyTag-329] - _ = x[KindJSDocOverrideTag-330] - _ = x[KindJSDocCallbackTag-331] - _ = x[KindJSDocOverloadTag-332] - _ = x[KindJSDocParameterTag-333] - _ = x[KindJSDocReturnTag-334] - _ = x[KindJSDocThisTag-335] - _ = x[KindJSDocTypeTag-336] - _ = x[KindJSDocTemplateTag-337] - _ = x[KindJSDocTypedefTag-338] - _ = x[KindJSDocSeeTag-339] - _ = x[KindJSDocPropertyTag-340] - _ = x[KindJSDocThrowsTag-341] - _ = x[KindJSDocSatisfiesTag-342] - _ = x[KindJSDocImportTag-343] - _ = x[KindSyntaxList-344] - _ = x[KindJSTypeAliasDeclaration-345] - _ = x[KindJSImportDeclaration-346] - _ = x[KindNotEmittedStatement-347] - _ = x[KindPartiallyEmittedExpression-348] - _ = x[KindSyntheticReferenceExpression-349] - _ = x[KindNotEmittedTypeElement-350] - _ = x[KindCount-351] + _ = 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[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] } -const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocUnknownTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocThrowsTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCount" +const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindNotKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocUnknownTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocThrowsTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCount" -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, 3181, 3198, 3211, 3224, 3245, 3268, 3287, 3308, 3339, 3354, 3369, 3384, 3401, 3423, 3441, 3458, 3475, 3491, 3510, 3523, 3538, 3551, 3564, 3580, 3592, 3605, 3625, 3644, 3657, 3678, 3690, 3706, 3727, 3741, 3756, 3776, 3799, 3826, 3840, 3864, 3887, 3905, 3931, 3958, 3986, 4013, 4031, 4048, 4076, 4103, 4130, 4152, 4169, 4189, 4209, 4227, 4246, 4271, 4297, 4317, 4342, 4364, 4383, 4400, 4419, 4440, 4471, 4487, 4508, 4524, 4547, 4570, 4586, 4611, 4620, 4638, 4659, 4682, 4697, 4712, 4730, 4746, 4764, 4782, 4803, 4821, 4840, 4857, 4876, 4896, 4914, 4930, 4951, 4974, 5001, 5024, 5044, 5068, 5092, 5111, 5132, 5147, 5160, 5190, 5217, 5238, 5254, 5273, 5289, 5308, 5328, 5349, 5365, 5384, 5403, 5425, 5452, 5466, 5491, 5512, 5533, 5548, 5570, 5592, 5608, 5625, 5647, 5664, 5685, 5699, 5716, 5734, 5749, 5769, 5788, 5810, 5841, 5861, 5875, 5889, 5912, 5934, 5950, 5971, 5995, 6016, 6037, 6046, 6059, 6079, 6097, 6110, 6127, 6145, 6164, 6184, 6206, 6228, 6246, 6265, 6286, 6306, 6326, 6346, 6366, 6387, 6405, 6421, 6437, 6457, 6476, 6491, 6511, 6529, 6550, 6568, 6582, 6608, 6631, 6654, 6684, 6716, 6741, 6750} +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, 3195, 3212, 3225, 3238, 3259, 3282, 3301, 3322, 3353, 3368, 3383, 3398, 3415, 3437, 3455, 3472, 3489, 3505, 3524, 3537, 3552, 3565, 3578, 3594, 3606, 3619, 3639, 3658, 3671, 3692, 3704, 3720, 3741, 3755, 3770, 3790, 3813, 3840, 3854, 3878, 3901, 3919, 3945, 3972, 4000, 4027, 4045, 4062, 4090, 4117, 4144, 4166, 4183, 4203, 4223, 4241, 4260, 4285, 4311, 4331, 4356, 4378, 4397, 4414, 4433, 4454, 4485, 4501, 4522, 4538, 4561, 4584, 4600, 4625, 4634, 4652, 4673, 4696, 4711, 4726, 4744, 4760, 4778, 4796, 4817, 4835, 4854, 4871, 4890, 4910, 4928, 4944, 4965, 4988, 5015, 5038, 5058, 5082, 5106, 5125, 5146, 5161, 5174, 5204, 5231, 5252, 5268, 5287, 5303, 5322, 5342, 5363, 5379, 5398, 5417, 5439, 5466, 5480, 5505, 5526, 5547, 5562, 5584, 5606, 5622, 5639, 5661, 5678, 5699, 5713, 5730, 5748, 5763, 5783, 5802, 5824, 5855, 5875, 5889, 5903, 5926, 5948, 5964, 5985, 6009, 6030, 6051, 6060, 6073, 6093, 6111, 6124, 6141, 6159, 6178, 6198, 6220, 6242, 6260, 6279, 6300, 6320, 6340, 6360, 6380, 6401, 6419, 6435, 6451, 6471, 6490, 6505, 6525, 6543, 6564, 6582, 6596, 6622, 6645, 6668, 6698, 6730, 6755, 6764} func (i Kind) String() string { idx := int(i) - 0 diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 36002eb752f4d..2e0f5a9cfe710 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -64,6 +64,7 @@ const ( TypeSystemPropertyNameWriteType TypeSystemPropertyNameInitializerIsUndefined TypeSystemPropertyNameAliasTarget + TypeSystemPropertyNameResolvedReducedType ) type TypeResolution struct { @@ -425,41 +426,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 @@ -475,6 +485,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 @@ -642,6 +655,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 @@ -957,6 +971,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) @@ -12524,7 +12539,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 @@ -17430,7 +17450,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) { @@ -18573,7 +18599,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 { @@ -18679,6 +18707,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 { @@ -19137,6 +19166,8 @@ func (c *Checker) typeResolutionHasProperty(r *TypeResolution) bool { return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).writeType != 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") } @@ -20522,7 +20553,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 { @@ -20726,8 +20757,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: @@ -20743,7 +20778,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) @@ -20913,7 +20948,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 } @@ -21378,7 +21413,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) @@ -22154,7 +22193,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'. @@ -22162,13 +22201,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 { @@ -22186,14 +22237,17 @@ func (c *Checker) getReducedType(t *Type) *Type { func (c *Checker) getReducedUnionType(unionType *Type) *Type { reducedTypes := core.SameMap(unionType.Types(), c.getReducedType) + if !core.Same(reducedTypes, unionType.Types()) { + reducedTypes, _ = c.addTypesToUnion(reducedTypes) + } + 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 { @@ -22532,7 +22586,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) || @@ -22616,6 +22671,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) { @@ -23315,6 +23372,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") } @@ -25280,6 +25339,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 } @@ -25904,7 +25969,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 { @@ -25914,6 +25983,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 @@ -26061,7 +26133,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) @@ -26159,6 +26231,9 @@ func (c *Checker) addTypesToUnion(sourceTypes []*Type) ([]*Type, TypeFlags) { if flags&TypeFlagsInstantiable != 0 { includes |= TypeFlagsIncludesInstantiable } + if flags&TypeFlagsNegated != 0 { + includes |= TypeFlagsIncludesNegated + } if flags&TypeFlagsIntersection != 0 && t.objectFlags&ObjectFlagsIsConstrainedTypeVariable != 0 { includes |= TypeFlagsIncludesConstrainedTypeVariable } @@ -26198,7 +26273,7 @@ func (c *Checker) addTypesToUnion(sourceTypes []*Type) ([]*Type, TypeFlags) { 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++ } @@ -26509,6 +26584,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 } @@ -26622,6 +26705,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 } @@ -26648,6 +26735,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 @@ -26898,6 +26994,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) } @@ -27220,7 +27319,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) || @@ -27955,6 +28054,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): @@ -30998,7 +31099,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 } @@ -31010,6 +31111,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) && @@ -31367,7 +31471,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 { @@ -31518,7 +31679,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 { @@ -31548,6 +31718,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 c22901a84d2ab..5a38d579644c0 100644 --- a/tsc/internal/checker/exports.go +++ b/tsc/internal/checker/exports.go @@ -313,6 +313,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 d08254cc8ef88..093bdcb812306 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 c93efc18d3fc7..4d502c035b55e 100644 --- a/tsc/internal/checker/inference.go +++ b/tsc/internal/checker/inference.go @@ -145,6 +145,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 { @@ -244,6 +248,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 @@ -708,6 +717,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..a418aa56f1a08 --- /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) +} + +// 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 f740a1161a5f7..47d9fdc44d4e2 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -3594,6 +3594,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 9d71d2504ca0c..7b91092aed62d 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.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.CheckFlags |= ast.CheckFlagsIsDiscriminant } } @@ -2316,7 +2317,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) @@ -2329,7 +2330,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 } } @@ -2340,7 +2341,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) } } @@ -2918,7 +2919,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 @@ -2945,7 +2946,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 { @@ -3397,6 +3416,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 @@ -3452,6 +3474,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 { @@ -3694,6 +3756,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 { @@ -4770,12 +4843,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 1ec80b0a26f62..2fa8df523d8a1 100644 --- a/tsc/internal/checker/types.go +++ b/tsc/internal/checker/types.go @@ -429,7 +429,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. @@ -464,13 +464,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 @@ -495,7 +496,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 @@ -515,6 +516,7 @@ const ( TypeFlagsIncludesInstantiable = TypeFlagsSubstitution TypeFlagsIncludesConstrainedTypeVariable = TypeFlagsReserved1 TypeFlagsIncludesError = TypeFlagsReserved2 + TypeFlagsIncludesNegated = TypeFlagsReserved3 TypeFlagsNotPrimitiveUnion = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsVoid | TypeFlagsNever | TypeFlagsObject | TypeFlagsIntersection | TypeFlagsIncludesInstantiable ) @@ -551,11 +553,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) @@ -659,6 +662,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 @@ -727,6 +732,7 @@ func (t *Type) AsTemplateLiteralType() *TemplateLiteralType { return t.data.(*Te func (t *Type) AsStringMappingType() *StringMappingType { return t.data.(*StringMappingType) } func (t *Type) AsSubstitutionType() *SubstitutionType { return t.data.(*SubstitutionType) } func (t *Type) AsConditionalType() *ConditionalType { return t.data.(*ConditionalType) } +func (t *Type) AsNegatedType() *NegatedType { return t.data.(*NegatedType) } // Casts for embedded struct types @@ -1246,6 +1252,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/utilities.go b/tsc/internal/checker/utilities.go index 0a68372fcef3c..8811c7fba9d60 100644 --- a/tsc/internal/checker/utilities.go +++ b/tsc/internal/checker/utilities.go @@ -905,6 +905,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 f54b4bcebbdf3..ae6d214324683 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -2725,7 +2725,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 55c81643836bc..7938adf2bc52e 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/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/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..c63d3b909ad29 --- /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, --, --)) +>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/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/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/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/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..91af1d213cca9 --- /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, --, --)) + +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