diff --git a/tsc/internal/checker/checker_test.go b/tsc/internal/checker/checker_test.go index 79f7026840934..607898252b356 100644 --- a/tsc/internal/checker/checker_test.go +++ b/tsc/internal/checker/checker_test.go @@ -12,6 +12,8 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/checker" "github.com/microsoft/TypeScript/tsc/internal/compiler" "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" + "github.com/microsoft/TypeScript/tsc/internal/printer" "github.com/microsoft/TypeScript/tsc/internal/repo" "github.com/microsoft/TypeScript/tsc/internal/testutil/baseline" "github.com/microsoft/TypeScript/tsc/internal/tsoptions" @@ -189,6 +191,97 @@ func TestTypeToStringRecursivePrototype(t *testing.T) { } } +type typeAliasRecordingTracker struct { + *checker.SymbolTrackerImpl + scope *ast.Node + declarations []*ast.Node + cyclicErrors int + scopeQueries int +} + +func (s *typeAliasRecordingTracker) TypeAliasScope() *ast.Node { + s.scopeQueries++ + return s.scope +} + +func (s *typeAliasRecordingTracker) AddTypeAliasDeclaration(declaration *ast.Node) { + s.declarations = append(s.declarations, declaration) +} + +func (s *typeAliasRecordingTracker) ReportCyclicStructureError() { + s.cyclicErrors++ +} + +func TestNodeBuilderTypeAliasSynthesisFlag(t *testing.T) { + t.Parallel() + fs := bundled.WrapFS(vfstest.FromMap(map[string]string{ + "/foo.ts": `export function make() { + return { next() { return this; } }; +} +make();`, + "/tsconfig.json": `{"compilerOptions":{"strict":true},"files":["foo.ts"]}`, + }, tspath.CaseInsensitive)) + host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil) + parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, fs, nil) + assert.Equal(t, len(errors), 0) + p := compiler.NewProgram(compiler.ProgramOptions{Config: parsed, Host: host}) + p.BindSourceFiles() + c, done := p.GetTypeChecker(t.Context()) + defer done() + file := p.GetSourceFile("/foo.ts") + typ := c.GetTypeAtLocation(file.Statements.Nodes[1].Expression()) + builder := checker.NewNodeBuilder(c, printer.NewEmitContext()) + tracker := &typeAliasRecordingTracker{ + SymbolTrackerImpl: checker.NewSymbolTrackerImpl(&checker.NodeBuilderContext{}, nil), + scope: file.AsNode(), + } + node := builder.TypeToTypeNode(typ, file.Statements.Nodes[0], nodebuilder.FlagsNoTruncation, nodebuilder.InternalFlagsNone, tracker) + assert.Assert(t, node == nil) + assert.Equal(t, tracker.cyclicErrors, 1) + assert.Equal(t, len(tracker.declarations), 0) + assert.Equal(t, tracker.scopeQueries, 0) + + for _, synthesize := range []bool{false, true, false, true} { + tracker.declarations = nil + tracker.cyclicErrors, tracker.scopeQueries = 0, 0 + internalFlags := nodebuilder.InternalFlagsNone + if synthesize { + internalFlags |= nodebuilder.InternalFlagsSynthesizeTypeAliases + } + node := builder.TypeToTypeNode(typ, file.Statements.Nodes[0], nodebuilder.FlagsNoTruncation|nodebuilder.FlagsAllowAnonymousIdentifier, internalFlags, tracker) + assert.Assert(t, node != nil) + assert.Equal(t, tracker.cyclicErrors, 0) + if synthesize { + assert.Equal(t, len(tracker.declarations), 1) + assert.Equal(t, tracker.declarations[0].Name().Text(), "make_recursive") + assert.Assert(t, tracker.scopeQueries > 0) + assert.Equal(t, node.Kind, ast.KindTypeReference) + assert.Equal(t, node.AsTypeReferenceNode().TypeName, tracker.declarations[0].Name()) + } else { + assert.Equal(t, len(tracker.declarations), 0) + assert.Equal(t, tracker.scopeQueries, 0) + assert.Equal(t, node.Kind, ast.KindTypeLiteral) + } + } + + for _, missingTracker := range []bool{false, true} { + func() { + tracker.scope = nil + var sink nodebuilder.SymbolTracker = tracker + if missingTracker { + sink = nil + } + defer func() { + message, ok := recover().(string) + assert.Assert(t, ok, "Expected a missing-scope assertion") + assert.Assert(t, strings.Contains(message, "Type alias synthesis requires a destination scope")) + }() + checker.NewNodeBuilder(c, printer.NewEmitContext()).TypeToTypeNode(typ, file.Statements.Nodes[0], nodebuilder.FlagsNoTruncation, nodebuilder.InternalFlagsSynthesizeTypeAliases, sink) + t.Fatal("Expected type alias synthesis without a destination scope to panic") + }() + } +} + func BenchmarkNewChecker(b *testing.B) { fs := bundled.WrapFS(osvfs.FS()) rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler")) diff --git a/tsc/internal/checker/nodebuilder.go b/tsc/internal/checker/nodebuilder.go index a4fb793b334bf..77445aadfddb8 100644 --- a/tsc/internal/checker/nodebuilder.go +++ b/tsc/internal/checker/nodebuilder.go @@ -3,6 +3,7 @@ package checker import ( "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/debug" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" "github.com/microsoft/TypeScript/tsc/internal/printer" ) @@ -39,23 +40,34 @@ func (b *NodeBuilder) enterContext(enclosingDeclaration *ast.Node, flags nodebui } b.ctxStack = append(b.ctxStack, b.impl.ctx) b.impl.ctx = &NodeBuilderContext{ - host: b.host, - tracker: tracker, - flags: flags, - internalFlags: internalFlags, - maxExpansionDepth: verbosityLevel, - maxTruncationLength: maxTruncationLength, - enclosingDeclaration: enclosingDeclaration, - enclosingFile: ast.GetSourceFileOfNode(enclosingDeclaration), - inferTypeParameters: make([]*Type, 0), - symbolDepth: make(map[CompositeSymbolIdentity]int), - trackedSymbols: make([]*TrackedSymbolArgs, 0), - reverseMappedStack: make([]*ast.Symbol, 0), - enclosingSymbolTypes: make(map[ast.SymbolId]*Type), - remappedSymbolReferences: make(map[ast.SymbolId]*ast.Symbol), + host: b.host, + tracker: tracker, + flags: flags, + internalFlags: internalFlags, + maxExpansionDepth: verbosityLevel, + maxTruncationLength: maxTruncationLength, + enclosingDeclaration: enclosingDeclaration, + typeAliasNamingDeclaration: enclosingDeclaration, + enclosingFile: ast.GetSourceFileOfNode(enclosingDeclaration), + inferTypeParameters: make([]*Type, 0), + symbolDepth: make(map[CompositeSymbolIdentity]int), + trackedSymbols: make([]*TrackedSymbolArgs, 0), + reverseMappedStack: make([]*ast.Symbol, 0), + enclosingSymbolTypes: make(map[ast.SymbolId]*Type), + remappedSymbolReferences: make(map[ast.SymbolId]*ast.Symbol), + } + for node := enclosingDeclaration; node != nil; node = node.Parent { + if ast.IsClassLike(node) || ast.IsInterfaceDeclaration(node) { + if symbol := b.impl.ch.getSymbolOfDeclaration(node); symbol != nil { + parameters := b.impl.ch.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) + b.impl.ctx.typeParameters = append(parameters, b.impl.ctx.typeParameters...) + } + } + } + b.impl.ctx.tracker = NewSymbolTrackerImpl(b.impl.ctx, tracker) + if internalFlags&nodebuilder.InternalFlagsSynthesizeTypeAliases != 0 { + debug.Assert(b.impl.ctx.tracker.TypeAliasScope() != nil, "Type alias synthesis requires a destination scope") } - tracker = NewSymbolTrackerImpl(b.impl.ctx, tracker) - b.impl.ctx.tracker = tracker } // propagateVerbosityOut copies expansion signals from the context to the VerbosityContext output. @@ -102,6 +114,9 @@ func (b *NodeBuilder) exitContextSlice(result []*ast.Node) []*ast.Node { } func (b *NodeBuilder) exitContextCheck() { + if !b.impl.ctx.encounteredError { + b.impl.emitSerializationTypeAliases() + } if b.impl.ctx.truncating && b.impl.ctx.flags&nodebuilder.FlagsNoTruncation != 0 { b.impl.ctx.tracker.ReportTruncationError() } @@ -116,6 +131,7 @@ func (b *NodeBuilder) IndexInfoToIndexSignatureDeclaration(info *IndexInfo, encl // SerializeReturnTypeForSignature implements NodeBuilderInterface. func (b *NodeBuilder) SerializeReturnTypeForSignature(signatureDeclaration *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = signatureDeclaration signature := b.impl.ch.getSignatureFromDeclaration(signatureDeclaration) _, cleanup := b.impl.enterSignatureScope(signature) result := b.impl.serializeReturnTypeForSignature(signature, true) @@ -133,6 +149,7 @@ func (b *NodeBuilder) SerializeTypeParametersForSignature(signatureDeclaration * // SerializeTypeForDeclaration implements NodeBuilderInterface. func (b *NodeBuilder) SerializeTypeForDeclaration(declaration *ast.Node, symbol *ast.Symbol, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = declaration return b.exitContext(b.impl.serializeTypeForDeclaration(declaration, nil, symbol, true)) } @@ -236,24 +253,28 @@ func (b *NodeBuilder) SymbolToExpression(symbol *ast.Symbol, meaning ast.SymbolF // SymbolToNode implements NodeBuilderInterface. func (b *NodeBuilder) SymbolToNode(symbol *ast.Symbol, meaning ast.SymbolFlags, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = core.Coalesce(core.FirstOrNil(symbol.Declarations()), enclosingDeclaration) return b.exitContext(b.impl.symbolToNode(symbol, meaning)) } // SymbolToParameterDeclaration implements NodeBuilderInterface. func (b NodeBuilder) SymbolToParameterDeclaration(symbol *ast.Symbol, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = core.Coalesce(getEffectiveParameterDeclaration(symbol), enclosingDeclaration) return b.exitContext(b.impl.symbolToParameterDeclaration(symbol, false)) } // SymbolToTypeParameterDeclarations implements NodeBuilderInterface. func (b *NodeBuilder) SymbolToTypeParameterDeclarations(symbol *ast.Symbol, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) []*ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = core.Coalesce(core.FirstOrNil(symbol.Declarations()), enclosingDeclaration) return b.exitContextSlice(b.impl.symbolToTypeParameterDeclarations(symbol)) } // TypeParameterToDeclaration implements NodeBuilderInterface. func (b *NodeBuilder) TypeParameterToDeclaration(parameter *Type, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = core.Coalesce(core.FirstOrNil(parameter.symbol.Declarations()), enclosingDeclaration) return b.exitContext(b.impl.typeParameterToDeclaration(parameter)) } @@ -271,6 +292,7 @@ func (b *NodeBuilder) TypeToTypeNode(typ *Type, enclosingDeclaration *ast.Node, func (b *NodeBuilder) TryJSTypeNodeToTypeNode(node *ast.Node, enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) *ast.Node { b.enterContext(enclosingDeclaration, flags, internalFlags, tracker) + b.impl.ctx.typeAliasNamingDeclaration = node return b.exitContext(b.impl.tryJSTypeNodeToTypeNode(node)) } diff --git a/tsc/internal/checker/nodebuilderbindings.go b/tsc/internal/checker/nodebuilderbindings.go new file mode 100644 index 0000000000000..754211f25eee2 --- /dev/null +++ b/tsc/internal/checker/nodebuilderbindings.go @@ -0,0 +1,263 @@ +package checker + +import ( + "slices" + "strings" + + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" + "github.com/microsoft/TypeScript/tsc/internal/printer" + "github.com/microsoft/TypeScript/tsc/internal/scanner" +) + +type serializationTypeAlias struct { + t *Type + typeId TypeId + name *ast.IdentifierNode + scope *ast.Node + typeParameters []*Type + usedParameters []bool + parameterNodes []*ast.Node + mapper *TypeMapper + body *ast.TypeNode +} + +type serializationTypeAliasReference struct { + alias *serializationTypeAlias + node *ast.TypeReferenceNode + arguments []*ast.TypeNode + owner *serializationTypeAlias + freeArguments []bool +} + +func (ctx *NodeBuilderContext) recordTypeAliasParameter(symbol *ast.Symbol) { + alias := ctx.currentTypeAlias + if alias == nil || ctx.writingTypeAliasArguments || symbol == nil || symbol.Flags()&ast.SymbolFlagsTypeParameter == 0 { + return + } + for _, parameter := range ctx.typeParameters[ctx.typeAliasParameterDepth:] { + if parameter.symbol == symbol { + return + } + } + for i, parameter := range alias.typeParameters { + if parameter.symbol == symbol { + alias.usedParameters[i] = true + } + } +} + +func (b *NodeBuilderImpl) serializationTypeAliasName(scope *ast.Node) string { + parts := []string{} + // Keep the emitted owner even while bodies are rebuilt in synthetic helper scopes. + for node := b.ctx.typeAliasNamingDeclaration; node != nil && node != scope; node = node.Parent { + name := ast.GetNameOfDeclaration(node) + if name == nil { + continue + } + if ast.IsComputedPropertyName(name) { + name = ast.SkipParentheses(name.Expression()) + } + if name == nil || !(ast.IsIdentifier(name) || ast.IsPrivateIdentifier(name) || ast.IsStringOrNumericLiteralLike(name)) || name.Text() == "" { + continue + } + parts = append(parts, strings.Map(func(ch rune) rune { + if scanner.IsIdentifierPart(ch) { + return ch + } + return '_' + }, name.Text())) + } + if len(parts) == 0 { + return "_recursive" + } + slices.Reverse(parts) + name := strings.Join(parts, "_") + if !scanner.IsIdentifierText(name, core.LanguageVariantStandard) { + name = "_" + name + } + return name + "_recursive" +} + +func (b *NodeBuilderImpl) createSerializationTypeAlias(expansion *serializationExpansion) *serializationTypeAlias { + destination := b.ctx.tracker.TypeAliasScope() + // Hoisted helpers need unscoped uniqueness even when first referenced inside a class. + name := b.e.Factory.NewUniqueNameEx(b.serializationTypeAliasName(destination), printer.AutoGenerateOptions{ + Flags: printer.GeneratedIdentifierFlagsOptimistic, + }) + scope := b.f.NewBlock(b.f.NewNodeList(nil), false) + scope.Parent = destination + parameters := []*Type{} + for _, parameter := range expansion.typeParameters { + if !slices.Contains(parameters, parameter) { + parameters = append(parameters, parameter) + } + } + alias := &serializationTypeAlias{ + t: expansion.t, + typeId: expansion.typeId, + name: name, + scope: scope, + typeParameters: parameters, + usedParameters: make([]bool, len(parameters)), + parameterNodes: make([]*ast.Node, len(parameters)), + mapper: expansion.mapper, + } + b.ctx.typeAliases = append(b.ctx.typeAliases, alias) + return alias +} + +func (b *NodeBuilderImpl) getSerializationTypeAlias(t *Type) *serializationTypeAlias { + if len(b.ctx.typeAliases) == 0 { + return nil + } + typeId := b.serializationTypeId(t) + for _, alias := range b.ctx.typeAliases { + if b.isSameSerializationType(t, typeId, alias.t, alias.typeId) { + return alias + } + } + return nil +} + +func (b *NodeBuilderImpl) serializationTypeAliasToNode(alias *serializationTypeAlias) *ast.TypeNode { + arguments := make([]*ast.TypeNode, len(alias.typeParameters)) + freeArguments := make([]bool, len(arguments)) + writingArguments := b.ctx.writingTypeAliasArguments + b.ctx.writingTypeAliasArguments = true + for i, parameter := range alias.typeParameters { + arguments[i] = b.typeToTypeNode(parameter) + freeArguments[i] = b.ctx.currentTypeAlias != nil && + !slices.Contains(b.ctx.typeParameters[b.ctx.typeAliasParameterDepth:], parameter) + } + b.ctx.writingTypeAliasArguments = writingArguments + node := b.f.NewTypeReferenceNode(alias.name, b.f.NewNodeList(arguments)) + b.ctx.typeAliasReferences = append(b.ctx.typeAliasReferences, serializationTypeAliasReference{ + alias: alias, node: node.AsTypeReferenceNode(), arguments: arguments, + owner: b.ctx.currentTypeAlias, freeArguments: freeArguments, + }) + b.ctx.approximateLength += len(alias.name.Text()) + return node +} + +func (b *NodeBuilderImpl) enterSerializationTypeAliasScope(alias *serializationTypeAlias) func() { + ctx := b.ctx + bindings, expansions := ctx.bindings, ctx.expansions + parameters, enclosingDeclaration, mapper := ctx.typeParameters, ctx.enclosingDeclaration, ctx.mapper + currentAlias, parameterDepth := ctx.currentTypeAlias, ctx.typeAliasParameterDepth + inferParameters, flags := ctx.inferTypeParameters, ctx.flags + ctx.bindings, ctx.expansions, ctx.typeParameters = nil, nil, nil + ctx.enclosingDeclaration = alias.scope + ctx.mapper = alias.mapper + ctx.currentTypeAlias = alias + ctx.inferTypeParameters = nil + ctx.flags &^= nodebuilder.FlagsInObjectTypeLiteral | nodebuilder.FlagsInTypeAlias + restoreScope := b.enterNewScope(alias.scope, nil, alias.typeParameters, nil, nil) + ctx.typeAliasParameterDepth = len(ctx.typeParameters) + return func() { + restoreScope() + ctx.bindings, ctx.expansions, ctx.typeParameters = bindings, expansions, parameters + ctx.enclosingDeclaration, ctx.mapper = enclosingDeclaration, mapper + ctx.currentTypeAlias, ctx.typeAliasParameterDepth = currentAlias, parameterDepth + ctx.inferTypeParameters, ctx.flags = inferParameters, flags + } +} + +func (b *NodeBuilderImpl) emitSerializationTypeAliases() { + if b.ctx.internalFlags&nodebuilder.InternalFlagsSynthesizeTypeAliases == 0 || len(b.ctx.typeAliases) == 0 { + return + } + // Bodies are rebuilt in their destination scope, not moved out of a source signature. + // This also makes lexical value references and captured generic parameters independent. + for { + changed := false + for i := range len(b.ctx.typeAliases) { + alias := b.ctx.typeAliases[i] + if alias.body == nil { + changed = true + restoreScope := b.enterSerializationTypeAliasScope(alias) + b.ctx.flags |= nodebuilder.FlagsInTypeAlias + b.ctx.skipTypeAliasReference = true + alias.body = b.typeToTypeNode(alias.t) + restoreScope() + if alias.body == nil && !b.ctx.encounteredError { + b.ctx.encounteredError = true + b.ctx.tracker.ReportCyclicStructureError() + } + if b.ctx.encounteredError { + return + } + } + } + for _, reference := range b.ctx.typeAliasReferences { + if reference.owner == nil { + continue + } + for i, parameter := range reference.alias.typeParameters { + if !reference.alias.usedParameters[i] || !reference.freeArguments[i] { + continue + } + index := slices.Index(reference.owner.typeParameters, parameter) + if index >= 0 && !reference.owner.usedParameters[index] { + reference.owner.usedParameters[index] = true + changed = true + } + } + } + // Capture constraints can introduce further captures or recursive bindings. + for _, alias := range b.ctx.typeAliases { + restoreScope := b.enterSerializationTypeAliasScope(alias) + for i, parameter := range alias.typeParameters { + if alias.usedParameters[i] && alias.parameterNodes[i] == nil { + var constraint *ast.TypeNode + if t := b.ch.getConstraintOfTypeParameter(parameter); t != nil { + constraint = b.typeToTypeNode(t) + } + var modifiers *ast.ModifierList + if symbol := alias.t.symbol; symbol != nil && symbol.Flags()&(ast.SymbolFlagsClass|ast.SymbolFlagsInterface) != 0 && + slices.Contains(b.ch.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), parameter) { + if flags := b.ch.getTypeParameterModifiers(parameter) & (ast.ModifierFlagsIn | ast.ModifierFlagsOut); flags != ast.ModifierFlagsNone { + modifiers = b.f.NewModifierList(ast.CreateModifiersFromModifierFlags(flags, b.f.NewModifier)) + } + } + alias.parameterNodes[i] = b.f.NewTypeParameterDeclaration(modifiers, b.typeParameterToName(parameter).AsNode(), constraint, nil, nil) + changed = true + } + } + restoreScope() + if b.ctx.encounteredError { + return + } + } + if !changed { + break + } + } + for _, reference := range b.ctx.typeAliasReferences { + arguments := []*ast.TypeNode{} + for i, argument := range reference.arguments { + if reference.alias.usedParameters[i] { + arguments = append(arguments, argument) + } + } + if len(arguments) == 0 { + reference.node.TypeArguments = nil + } else { + reference.node.TypeArguments = b.f.NewNodeList(arguments) + } + } + for _, alias := range b.ctx.typeAliases { + parameters := []*ast.Node{} + for i, parameter := range alias.parameterNodes { + if alias.usedParameters[i] { + parameters = append(parameters, parameter) + } + } + var parameterList *ast.NodeList + if len(parameters) != 0 { + parameterList = b.f.NewNodeList(parameters) + } + b.ctx.tracker.AddTypeAliasDeclaration(b.f.NewTypeAliasDeclaration(nil, alias.name, parameterList, alias.body)) + } +} diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index 8aa88416fa7a2..bb9db6f0f8965 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -45,7 +45,8 @@ type CompositeTypeCacheIdentity struct { flags nodebuilder.Flags internalFlags nodebuilder.InternalFlags inferTypeParameters CacheHashKey - definitions CacheHashKey + bindings CacheHashKey + expansions CacheHashKey } // A reference's spelling is independent of the definition currently being emitted. @@ -56,14 +57,22 @@ type serializationTypeName struct { path []*Type } -// Definitions include standalone signatures and types emitted syntactically or structurally. -type serializationDefinition struct { - t *Type - typeId TypeId - signature *Signature - symbol *ast.Symbol - depth int - expanding bool +// A value binding denotes its complete annotation, not an arbitrary constituent. +type serializationTypeBinding struct { + t *Type + typeId TypeId + symbol *ast.Symbol + path []*Type + depth int +} + +// Structural graph traversal is independent of the bindings chosen for its cycles. +type serializationExpansion struct { + t *Type + typeId TypeId + typeParameters []*Type + mapper *TypeMapper + alias *serializationTypeAlias } type NodeBuilderLinks struct { @@ -105,8 +114,17 @@ type NodeBuilderContext struct { enclosingSymbolTypes map[ast.SymbolId]*Type suppressReportInferenceFallback bool remappedSymbolReferences map[ast.SymbolId]*ast.Symbol - definitions []serializationDefinition + bindings []serializationTypeBinding + expansions []*serializationExpansion deferredTypeDepth int // Lazy member boundaries, excluding eager type arguments and container elements. + typeParameters []*Type + typeAliases []*serializationTypeAlias + typeAliasNamingDeclaration *ast.Node + typeAliasReferences []serializationTypeAliasReference + currentTypeAlias *serializationTypeAlias + typeAliasParameterDepth int + writingTypeAliasArguments bool + skipTypeAliasReference bool // per signature scope state typeParameterNames collections.CopyOnWriteMap[TypeId, *ast.Identifier] @@ -1898,7 +1916,17 @@ func (b *NodeBuilderImpl) signatureToSignatureDeclarationHelper(signature *Signa } } else { for _, parameter := range signature.typeParameters { - typeParameters = append(typeParameters, b.typeParameterToDeclaration(parameter)) + declaration := b.typeParameterToDeclaration(parameter) + flags := b.ch.getTypeParameterModifiers(parameter) + if (kind == ast.KindConstructorType || kind == ast.KindConstructSignature) && flags&(ast.ModifierFlagsIn|ast.ModifierFlagsOut) != 0 { + // Class variance does not apply to constructor signatures. + var modifiers *ast.ModifierList + if flags := flags &^ (ast.ModifierFlagsIn | ast.ModifierFlagsOut); flags != ast.ModifierFlagsNone { + modifiers = b.f.NewModifierList(ast.CreateModifiersFromModifierFlags(flags, b.f.NewModifier)) + } + declaration = ast.ReplaceModifiers(b.f, declaration, modifiers) + } + typeParameters = append(typeParameters, declaration) } } @@ -2312,8 +2340,8 @@ func (b *NodeBuilderImpl) serializeTypeForDeclaration(declaration *ast.Declarati t = b.ch.getOptionalType(t, false) } - restoreDefinition := b.enterTypeDefinition(t, symbol, false /*expanding*/) - defer restoreDefinition() + restoreBinding := b.enterTypeBinding(t, symbol) + defer restoreBinding() restoreFlags := b.saveRestoreFlags() if t.flags&TypeFlagsUniqueESSymbol != 0 && t.symbol == symbol && (b.ctx.enclosingDeclaration == nil || core.Some(symbol.Declarations(), func(d *ast.Declaration) bool { @@ -2998,10 +3026,12 @@ func (b *NodeBuilderImpl) conditionalTypeToTypeNode(_t *Type) *ast.TypeNode { b.ctx.approximateLength += 37 // 15 each for two added conditionals, 7 for an added infer type newMapper := prependTypeMapping(t.root.checkType, newParam, t.mapper) + restoreScope := b.enterNewScope(t.root.node.AsNode(), nil, append([]*Type{newParam}, t.root.inferTypeParameters...), nil, nil) restoreInferTypeParameters := b.enterInferTypeParameterScope(t.root.inferTypeParameters) extendsTypeNode := b.typeToTypeNode(b.ch.instantiateType(t.root.extendsType, newMapper)) restoreInferTypeParameters() trueTypeNode := b.typeToTypeNodeOrCircularityElision(b.ch.instantiateType(b.getTypeFromTypeNode(t.root.node.TrueType, false), newMapper)) + restoreScope() falseTypeNode := b.typeToTypeNodeOrCircularityElision(b.ch.instantiateType(b.getTypeFromTypeNode(t.root.node.FalseType, false), newMapper)) // outermost conditional makes `T` a type parameter, allowing the inner conditionals to be distributive @@ -3020,10 +3050,12 @@ func (b *NodeBuilderImpl) conditionalTypeToTypeNode(_t *Type) *ast.TypeNode { syntheticTrueNode := b.f.NewConditionalTypeNode(b.f.NewTypeReferenceNode(name.Clone(b.f), nil), b.f.DeepCloneNode(checkTypeNode), innerCheckConditionalNode, b.f.NewKeywordTypeNode(ast.KindNeverKeyword)) return b.f.NewConditionalTypeNode(checkTypeNode, syntheticExtendsNode, syntheticTrueNode, b.f.NewKeywordTypeNode(ast.KindNeverKeyword)) } + restoreScope := b.enterNewScope(t.root.node.AsNode(), nil, t.root.inferTypeParameters, nil, nil) restoreInferTypeParameters := b.enterInferTypeParameterScope(t.root.inferTypeParameters) extendsTypeNode := b.typeToTypeNode(t.extendsType) restoreInferTypeParameters() trueTypeNode := b.typeToTypeNodeOrCircularityElision(b.ch.getTrueTypeFromConditionalType(_t)) + restoreScope() falseTypeNode := b.typeToTypeNodeOrCircularityElision(b.ch.getFalseTypeFromConditionalType(_t)) return b.f.NewConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode) } @@ -3193,14 +3225,31 @@ func (b *NodeBuilderImpl) typeReferenceToTypeNode(t *Type) *ast.TypeNode { func (b *NodeBuilderImpl) visitType(t *Type, transform func(b *NodeBuilderImpl, t *Type) *ast.TypeNode) *ast.TypeNode { typeId := b.serializationTypeId(t) - for _, definition := range b.ctx.definitions { - if definition.expanding && b.isSameSerializationType(t, typeId, definition) { + for _, expansion := range b.ctx.expansions { + if b.isSameSerializationType(t, typeId, expansion.t, expansion.typeId) { + if b.ctx.internalFlags&nodebuilder.InternalFlagsSynthesizeTypeAliases != 0 { + if expansion.alias == nil { + expansion.alias = b.createSerializationTypeAlias(expansion) + } + return b.serializationTypeAliasToNode(expansion.alias) + } return b.createCyclicStructurePlaceholder() } } - restoreDefinition := b.enterTypeDefinition(t, nil, true /*expanding*/) - defer restoreDefinition() - return transform(b, t) + expansion := &serializationExpansion{t: t, typeId: typeId, typeParameters: slices.Clone(b.ctx.typeParameters), mapper: b.ctx.mapper} + expansions := b.ctx.expansions + bindings := b.ctx.bindings + if name := b.getSerializationValueName(t); name.symbol != nil && b.isSerializationTypeNameAccessible(name) { + b.ctx.bindings = append(bindings, serializationTypeBinding{t: t, typeId: typeId, symbol: name.symbol, path: name.path, depth: b.ctx.deferredTypeDepth}) + } + b.ctx.expansions = append(expansions, expansion) + result := transform(b, t) + b.ctx.expansions = expansions + b.ctx.bindings = bindings + if expansion.alias != nil { + return b.serializationTypeAliasToNode(expansion.alias) + } + return result } func (b *NodeBuilderImpl) visitAndTransformType(t *Type, transform func(b *NodeBuilderImpl, t *Type) *ast.TypeNode) *ast.TypeNode { @@ -3240,29 +3289,29 @@ func (b *NodeBuilderImpl) transformType(t *Type, transform func(b *NodeBuilderIm internalFlags: b.ctx.internalFlags, } // Expansion must recompute canIncreaseExpansionDepth instead of reusing cached output. - canUseCache := b.ctx.maxExpansionDepth < 0 + canUseCache := b.ctx.maxExpansionDepth < 0 && b.ctx.currentTypeAlias == nil && len(b.ctx.typeAliases) == 0 if canUseCache && len(b.ctx.inferTypeParameters) != 0 { key.inferTypeParameters = getTypeListKey(b.ctx.inferTypeParameters) } - if canUseCache && len(b.ctx.definitions) != 0 { - // Unnamed definitions matter too: they determine where cyclic output is elided. - var definitions keyBuilder - for _, definition := range b.ctx.definitions { - definitions.writeUint32(uint32(definition.typeId)) - if definition.signature != nil { - definitions.writeUint32(uint32(definition.signature.id)) - } else { - definitions.writeUint32(0) + if canUseCache && len(b.ctx.bindings) != 0 { + var bindings keyBuilder + for _, binding := range b.ctx.bindings { + bindings.writeUint32(uint32(binding.typeId)) + bindings.writeSymbol(binding.symbol) + bindings.writeInt(len(binding.path)) + for _, index := range binding.path { + bindings.writeType(index) } - if definition.symbol != nil { - definitions.writeSymbol(definition.symbol) - } else { - definitions.writeUint64(0) - } - definitions.writeByte(core.IfElse(definition.expanding, byte(1), byte(0))) - definitions.writeByte(core.IfElse(b.ctx.deferredTypeDepth > definition.depth, byte(1), byte(0))) + bindings.writeByte(core.IfElse(b.ctx.deferredTypeDepth > binding.depth, byte(1), byte(0))) } - key.definitions = definitions.hash() + key.bindings = bindings.hash() + } + if canUseCache && len(b.ctx.expansions) != 0 { + var expansions keyBuilder + for _, expansion := range b.ctx.expansions { + expansions.writeUint32(uint32(expansion.typeId)) + } + key.expansions = expansions.hash() } if canUseCache && b.ctx.enclosingDeclaration != nil && b.links.Has(b.ctx.enclosingDeclaration) { links := b.links.Get(b.ctx.enclosingDeclaration) @@ -3307,7 +3356,7 @@ func (b *NodeBuilderImpl) transformType(t *Type, transform func(b *NodeBuilderIm startLength := b.ctx.approximateLength result := transform(b, t) addedLength := b.ctx.approximateLength - startLength - if canUseCache && !b.ctx.reportedDiagnostic && !b.ctx.encounteredError { + if canUseCache && len(b.ctx.typeAliases) == 0 && !b.ctx.reportedDiagnostic && !b.ctx.encounteredError { links := b.links.Get(b.ctx.enclosingDeclaration) if links.serializedTypes == nil { links.serializedTypes = make(map[CompositeTypeCacheIdentity]*SerializedTypeEntry) @@ -3344,6 +3393,8 @@ func (b *NodeBuilderImpl) transformType(t *Type, transform func(b *NodeBuilderIm } func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode { + skipTypeAliasReference := b.ctx.skipTypeAliasReference + b.ctx.skipTypeAliasReference = false inTypeAlias := b.ctx.flags & nodebuilder.FlagsInTypeAlias b.ctx.flags &^= nodebuilder.FlagsInTypeAlias @@ -3513,7 +3564,12 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode { defer func() { b.ctx.depth-- }() } - if name := b.getTypeDefinitionReference(t); name.symbol != nil { + if !skipTypeAliasReference { + if alias := b.getSerializationTypeAlias(t); alias != nil { + return b.serializationTypeAliasToNode(alias) + } + } + if name := b.getTypeBindingReference(t); name.symbol != nil { return b.serializationTypeNameToNode(name) } @@ -3537,6 +3593,9 @@ func (b *NodeBuilderImpl) typeToTypeNode(t *Type) *ast.TypeNode { } } if t.flags&TypeFlagsTypeParameter != 0 || objectFlags&ObjectFlagsClassOrInterface != 0 { + if t.flags&TypeFlagsTypeParameter != 0 { + b.ctx.recordTypeAliasParameter(t.symbol) + } // When expanding class or interface types, show their structural form if objectFlags&ObjectFlagsClassOrInterface != 0 && b.shouldExpandType(t, false /*isAlias*/) { b.ctx.depth++ diff --git a/tsc/internal/checker/nodebuilderscopes.go b/tsc/internal/checker/nodebuilderscopes.go index 73cc1b4bc7b74..78866f422645c 100644 --- a/tsc/internal/checker/nodebuilderscopes.go +++ b/tsc/internal/checker/nodebuilderscopes.go @@ -62,15 +62,44 @@ func (b *NodeBuilderImpl) serializationTypeId(t *Type) TypeId { return t.id } -func (b *NodeBuilderImpl) enterTypeDefinition(t *Type, symbol *ast.Symbol, expanding bool) func() { - return b.enterDefinition(serializationDefinition{t: t, typeId: b.serializationTypeId(t), symbol: symbol, expanding: expanding}) +func (b *NodeBuilderImpl) enterTypeBinding(t *Type, symbol *ast.Symbol) func() { + bindings := b.ctx.bindings + if symbol != nil { + binding := serializationTypeBinding{t: t, typeId: b.serializationTypeId(t), symbol: symbol, depth: b.ctx.deferredTypeDepth} + if len(bindings) != 0 && t.flags&TypeFlagsStructuredOrInstantiable != 0 && + symbol.Flags()&(ast.SymbolFlagsProperty|ast.SymbolFlagsMethod|ast.SymbolFlagsAccessor) != 0 { + name := b.getTypeBindingName(t, binding) + if name.symbol == nil || !b.isSerializationTypeNameAccessible(name) { + index := b.getSerializationPropertyIndex(symbol) + if isTypeUsableAsPropertyName(index) { + for _, parent := range slices.Backward(bindings) { + if b.ch.getPropertyOfType(parent.t, symbol.Name()) != symbol { + continue + } + parentName := b.getTypeBindingName(parent.t, parent) + if parentName.symbol == nil || !b.isSerializationTypeNameAccessible(parentName) { + continue + } + path := append(slices.Clone(parentName.path), index) + if name := b.getValueTypeName(t, parentName.symbol, path); name.symbol != nil { + binding.symbol, binding.path = name.symbol, name.path + break + } + } + } + } + } + b.ctx.bindings = append(bindings, binding) + } + return func() { b.ctx.bindings = bindings } } -func (b *NodeBuilderImpl) enterDefinition(definition serializationDefinition) func() { - definitions := b.ctx.definitions - definition.depth = b.ctx.deferredTypeDepth - b.ctx.definitions = append(definitions, definition) - return func() { b.ctx.definitions = definitions } +func (b *NodeBuilderImpl) getSerializationPropertyIndex(symbol *ast.Symbol) *Type { + name := ast.GetNameOfDeclaration(symbol.ValueDeclaration()) + if name != nil && !ast.IsPropertyName(name) && b.ch.valueSymbolLinks.Get(b.ch.getLateBoundSymbol(symbol)).nameType == nil { + return b.ch.neverType + } + return b.ch.getLiteralTypeFromProperty(symbol, TypeFlagsStringOrNumberLiteralOrUnique, false /*includeNonPublic*/) } // Lexical scopes alone do not guard back-references; only lazy member boundaries do. @@ -86,11 +115,10 @@ func (b *NodeBuilderImpl) enterInferTypeParameterScope(typeParameters []*Type) f return func() { b.ctx.inferTypeParameters = inferTypeParameters } } -func (b *NodeBuilderImpl) isSameSerializationType(t *Type, typeId TypeId, definition serializationDefinition) bool { - if typeId == definition.typeId { +func (b *NodeBuilderImpl) isSameSerializationType(t *Type, typeId TypeId, other *Type, otherTypeId TypeId) bool { + if typeId == otherTypeId { return true } - other := definition.t // Regular and widened objects may have different IDs without changing shape. // Do not collapse distinct generic instantiations. return t.objectFlags&(ObjectFlagsAnonymous|ObjectFlagsInstantiated) == ObjectFlagsAnonymous && @@ -98,38 +126,14 @@ func (b *NodeBuilderImpl) isSameSerializationType(t *Type, typeId TypeId, defini t.symbol != nil && t.symbol == other.symbol && b.ch.isTypeIdenticalTo(t, other) } -func (b *NodeBuilderImpl) getTypeDefinitionReference(t *Type) serializationTypeName { - var typeId TypeId - for _, definition := range b.ctx.definitions { - if b.ctx.deferredTypeDepth <= definition.depth { +func (b *NodeBuilderImpl) getTypeBindingReference(t *Type) serializationTypeName { + typeId := b.serializationTypeId(t) + for _, binding := range b.ctx.bindings { + if b.ctx.deferredTypeDepth <= binding.depth || + !b.isSameSerializationBindingType(t, typeId, binding.t, binding.typeId) { continue } - if signature := definition.signature; signature != nil { - if t.objectFlags&ObjectFlagsAnonymous == 0 { - continue - } - kind := core.IfElse(signature.flags&SignatureFlagsConstruct != 0, SignatureKindConstruct, SignatureKindCall) - if !slices.Contains(b.ch.getSignaturesOfType(t, kind), signature) { - continue - } - } else { - if typeId == 0 { - typeId = b.serializationTypeId(t) - } - if !b.isSameSerializationType(t, typeId, definition) { - continue - } - } - var name serializationTypeName - if symbol := definition.symbol; symbol != nil { - if symbol.Flags()&(ast.SymbolFlagsProperty|ast.SymbolFlagsMethod|ast.SymbolFlagsAccessor) != 0 { - name = b.getSerializationTypeNameFromDeclaration(t, symbol.ValueDeclaration()) - } else { - name = b.getValueTypeName(t, symbol, nil) - } - } else { - name = b.getSerializationValueName(t) - } + name := b.getTypeBindingName(t, binding) if name.symbol != nil && b.isSerializationTypeNameAccessible(name) { return name } @@ -137,8 +141,27 @@ func (b *NodeBuilderImpl) getTypeDefinitionReference(t *Type) serializationTypeN return serializationTypeName{} } +func (b *NodeBuilderImpl) isSameSerializationBindingType(t *Type, typeId TypeId, other *Type, otherTypeId TypeId) bool { + // A proven name can denote equivalent specializations without merging their graph identities. + return b.isSameSerializationType(t, typeId, other, otherTypeId) || + t.objectFlags&ObjectFlagsAnonymous != 0 && other.objectFlags&ObjectFlagsAnonymous != 0 && + t.symbol != nil && t.symbol == other.symbol && b.ch.isTypeIdenticalTo(t, other) +} + +func (b *NodeBuilderImpl) getTypeBindingName(t *Type, binding serializationTypeBinding) serializationTypeName { + if symbol := binding.symbol; symbol != nil { + if len(binding.path) == 0 && symbol.Flags()&(ast.SymbolFlagsProperty|ast.SymbolFlagsMethod|ast.SymbolFlagsAccessor) != 0 { + if name := b.getSerializationTypeNameFromDeclaration(t, symbol.ValueDeclaration()); name.symbol != nil { + return name + } + } + return b.getValueTypeName(t, symbol, binding.path) + } + return b.getSerializationValueName(t) +} + func (b *NodeBuilderImpl) getValueTypeName(t *Type, symbol *ast.Symbol, path []*Type) serializationTypeName { - if symbol == nil || symbol.Flags()&ast.SymbolFlagsValue == 0 || t.flags&TypeFlagsStructuredOrInstantiable == 0 || + if symbol == nil || symbol.Flags()&ast.SymbolFlagsValue == 0 || symbol.Flags()&ast.SymbolFlagsModuleExports != 0 || t.flags&TypeFlagsStructuredOrInstantiable == 0 || IsPrivateIdentifierSymbol(symbol) || b.ctx.flags&nodebuilder.FlagsUseStructuralFallback != 0 && getDeclarationModifierFlagsFromSymbol(symbol)&(ast.ModifierFlagsPrivate|ast.ModifierFlagsProtected) != 0 || !scanner.IsIdentifierText(symbol.Name(), core.LanguageVariantStandard) { return serializationTypeName{} @@ -159,7 +182,7 @@ func (b *NodeBuilderImpl) getValueTypeName(t *Type, symbol *ast.Symbol, path []* } namedType = b.ch.getIndexedAccessType(namedType, index) } - if b.serializationTypeId(namedType) != b.serializationTypeId(t) { + if !b.isSameSerializationBindingType(t, b.serializationTypeId(t), namedType, b.serializationTypeId(namedType)) { return serializationTypeName{} } return serializationTypeName{symbol: symbol, meaning: ast.SymbolFlagsValue, path: path} @@ -290,19 +313,40 @@ func (b *NodeBuilderImpl) getSerializationTypeNameFromDeclaration(t *Type, node } func (b *NodeBuilderImpl) enterSignatureScope(signature *Signature) (expandedParams []*ast.Symbol, cleanup func()) { - restoreDefinition := b.enterDefinition(serializationDefinition{signature: signature}) + bindings := b.ctx.bindings + if signature.declaration != nil { + var declarations []*ast.Node + if assigned := getAssignedValueDeclaration(signature.declaration); assigned != nil { + declarations = append(declarations, assigned) + } + declarations = append(declarations, signature.declaration) + for _, declaration := range declarations { + if symbol := b.ch.getSymbolOfDeclaration(declaration); symbol != nil { + t := b.ch.valueSymbolLinks.Get(symbol).resolvedType + if t == nil && symbol.Flags()&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0 && symbol.CheckFlags()&ast.CheckFlagsInstantiated == 0 { + // Function type shells do not require resolving their signatures. + t = b.ch.getTypeOfFuncClassEnumModule(symbol) + } + if t != nil { + b.enterTypeBinding(t, symbol) + } + } + } + } restoreDeferredTypeScope := b.enterDeferredTypeScope() expandedParams = b.ch.getExpandedParameters(signature, true /*skipUnionExpanding*/)[0] restoreScope := b.enterNewScope(signature.declaration, expandedParams, signature.typeParameters, signature.parameters, signature.mapper) cleanup = func() { restoreScope() restoreDeferredTypeScope() - restoreDefinition() + b.ctx.bindings = bindings } return expandedParams, cleanup } func (b *NodeBuilderImpl) enterNewScope(declaration *ast.Node, expandedParams []*ast.Symbol, typeParameters []*Type, originalParameters []*ast.Symbol, mapper *TypeMapper) func() { + oldTypeParameters := b.ctx.typeParameters + b.ctx.typeParameters = append(slices.Clone(oldTypeParameters), typeParameters...) cleanupNames := enterTypeParameterNameScope(b.ctx) // For regular function/method declarations, the enclosing declaration will already be signature.declaration, // so this is a no-op, but for arrow functions and function expressions, the enclosing declaration will be @@ -502,5 +546,6 @@ func (b *NodeBuilderImpl) enterNewScope(declaration *ast.Node, expandedParams [] cleanupNames() b.ctx.enclosingDeclaration = oldEnclosingDecl b.ctx.mapper = oldMapper + b.ctx.typeParameters = oldTypeParameters } } diff --git a/tsc/internal/checker/nodecopy.go b/tsc/internal/checker/nodecopy.go index 6a7a43d38ca24..9d1b6bf3ab760 100644 --- a/tsc/internal/checker/nodecopy.go +++ b/tsc/internal/checker/nodecopy.go @@ -136,6 +136,14 @@ type wrappingTracker struct { bound *recoveryBoundary } +func (w *wrappingTracker) TypeAliasScope() *ast.Node { + return w.wrapped.TypeAliasScope() +} + +func (w *wrappingTracker) AddTypeAliasDeclaration(declaration *ast.Node) { + w.wrapped.AddTypeAliasDeclaration(declaration) +} + func (w *wrappingTracker) PopErrorFallbackNode() { w.wrapped.PopErrorFallbackNode() } diff --git a/tsc/internal/checker/pseudotypenodebuilder.go b/tsc/internal/checker/pseudotypenodebuilder.go index cefafbabca844..7236699c587bc 100644 --- a/tsc/internal/checker/pseudotypenodebuilder.go +++ b/tsc/internal/checker/pseudotypenodebuilder.go @@ -41,7 +41,7 @@ func (b *NodeBuilderImpl) pseudoTypeToNodeWithCheckerFallback(t *pseudochecker.P return result } } else if (t.Kind == pseudochecker.PseudoTypeKindSingleCallSignature || t.Kind == pseudochecker.PseudoTypeKindObjectLiteral) && - b.getTypeDefinitionReference(checkerType).symbol != nil { + b.getTypeBindingReference(checkerType).symbol != nil { // Reusing structural syntax must not unfold an already available back-reference. return b.typeToTypeNode(checkerType) } diff --git a/tsc/internal/checker/symboltracker.go b/tsc/internal/checker/symboltracker.go index 7ee61191feace..4a64e16790d9a 100644 --- a/tsc/internal/checker/symboltracker.go +++ b/tsc/internal/checker/symboltracker.go @@ -2,6 +2,7 @@ package checker import ( "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/debug" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" ) @@ -25,7 +26,20 @@ func NewSymbolTrackerImpl(context *NodeBuilderContext, tracker nodebuilder.Symbo return &SymbolTrackerImpl{context, tracker, false} } +func (this *SymbolTrackerImpl) TypeAliasScope() *ast.Node { + if this.inner == nil { + return nil + } + return this.inner.TypeAliasScope() +} + +func (this *SymbolTrackerImpl) AddTypeAliasDeclaration(declaration *ast.Node) { + debug.Assert(this.inner != nil, "Type alias synthesis requires a symbol tracker") + this.inner.AddTypeAliasDeclaration(declaration) +} + func (this *SymbolTrackerImpl) TrackSymbol(symbol *ast.Symbol, enclosingDeclaration *ast.Node, meaning ast.SymbolFlags) bool { + this.context.recordTypeAliasParameter(symbol) if !this.DisableTrackSymbol { if this.inner != nil && this.inner.TrackSymbol(symbol, enclosingDeclaration, meaning) { this.onDiagnosticReported() diff --git a/tsc/internal/execute/tsctests/tsc_test.go b/tsc/internal/execute/tsctests/tsc_test.go index 360a2ded0e52e..1a340360aa939 100644 --- a/tsc/internal/execute/tsctests/tsc_test.go +++ b/tsc/internal/execute/tsctests/tsc_test.go @@ -2486,9 +2486,18 @@ func TestTscIncremental(t *testing.T) { subScenario: "recursive function declaration consumption", files: FileMap{ "/home/src/workspaces/project/producer/tsconfig.json": `{ - "compilerOptions": { "strict": true, "composite": true, "outDir": "dist" } + "compilerOptions": { "strict": true, "exactOptionalPropertyTypes": true, "composite": true, "outDir": "dist" } }`, "/home/src/workspaces/project/producer/index.ts": stringtestutil.Dedent(` + import { f } from "./recursive-conditional-utils"; + export const conditionalAliasCopy = f; + export function anonymousThisReturn() { + return { + relyingOnThis() { + return this; + }, + }; + } export const arrow = () => arrow; export const expression = function self() { return self; }; export const first = () => second; @@ -2566,12 +2575,156 @@ func TestTscIncremental(t *testing.T) { }, }; export const nestedNumber = nestedOwner.make(1); + type Show = { [K in keyof T]: T[K] } & unknown; + type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; + }>; + declare const build: () => { [K in keyof M]: Resolve }; + export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); + export const mappedCycleCopy = mappedCycle; + export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; + export const cycleKey = Symbol(); + export const keyedCycles = build<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; + }>(); + export const sharedCycles = { first: mappedCycle, second: mappedCycle }; + type ResolveMutual = Show<{ + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; + }>; + declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; + export const mutualCycle = buildMutual<{ + First: { value: number; next: { ref: "Second" } }; + Second: { value: string; next: { ref: "First" } }; + }>(); + type ResolveShadowed = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => ResolveShadowed : M[K][P]; + }>; + declare const buildShadowed: () => { [K in keyof M]: ResolveShadowed }; + export const shadowedCycle = buildShadowed<{ Node: { value: number; next: "ref" } }>(); + declare const buildOptional: () => { [K in keyof M]?: Resolve }; + export const optionalCycle = buildOptional<{ Node: { value: number; next: "ref" } }>(); + declare const buildNullable: () => { [K in keyof M]: Resolve | null }; + export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); + declare const wrap: (value: T) => { required: T; optional?: T | null }; + export const mixedCycles = wrap(optionalCycle); + export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; + export const nullableKeys = buildNullable<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; + }>(); + declare const buildNullableRoot: () => Resolve | null; + export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); + declare const buildOptionalRoot: () => Resolve | undefined; + export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); + type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; + }>; + declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; + export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); + declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; + export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); + type ResolveOptional = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; + }>; + declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; + export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); + type ResolveNullish = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; + }>; + declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; + export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); + declare const buildMixed: () => { [K in keyof M]?: Resolve | false | null }; + export const mixedUnionCycle = buildMixed<{ Node: { value: number; next: "ref" } }>(); + export const _recursive = 1; + export const factory = () => function self() { return self; }; + export function captured(value: T) { + const node = { value, next: () => node, consume: (other: T) => node }; + return node; + } + export function nestedCaptured(outer: T) { + return (inner: U) => { + const node = { + outer, inner, next: () => node, + shadow: (value: T) => ({ outer, inner, value, next: node }), + }; + return node; + }; + } + export function constrained(key: K) { + const node = { value: null! as T[K], next: () => node }; + return node; + } + export function optionalCaptured(value: T) { + type Node = { value: T; next: Node }; + return null! as { node?: Node | false | null }; + } + export function annotatedCaptured(value: T) { + const node: { value: typeof value; next: typeof node } = { value, next: null! }; + return node; + } + export function recursiveTuple(value: T) { + type Tuple = readonly [T, Tuple]; + return null! as Tuple; + } + export function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); + } + export function mappedCaptured() { + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; + return null! as Node; + } + export function freshGeneric(unused: T) { + const recur = (value: U) => recur; + return recur; + } + export function mutualCaptured(left: T, right: U) { + type Left = { left: T; next: Right }; + type Right = { right: U; self: Right; next: Left }; + return { left: null! as Left, right: null! as Right }; + } + export class CapturedClass { + constructor(public value: T) {} + make(inner: U) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } + } + export function covariantClass() { + return class Node { + value!: T; + next(): Node { return this; } + }; + } + export function contravariantClass() { + return class Node { + consume!: (value: T) => void; + next(): Node { return this; } + }; + } + export namespace Nested { + export function captured(value: T) { + const node = { value, next: () => node }; + return node; + } + } + type NonNullable = "shadowed"; + `), + "/home/src/workspaces/project/producer/recursive-conditional-utils.ts": stringtestutil.Dedent(` + type Recursive = T extends Array ? Recursive : T; + export const f = (): Recursive => { + return null!; + }; `), "/home/src/workspaces/project/consumer/tsconfig.json": `{ - "compilerOptions": { "strict": true, "noEmit": true }, + "compilerOptions": { "strict": true, "exactOptionalPropertyTypes": true, "noEmit": true }, "references": [{ "path": "../producer" }] }`, "/home/src/workspaces/project/consumer/index.ts": stringtestutil.Dedent(` + import { conditionalAliasCopy, anonymousThisReturn } from "../producer/dist/index.js"; import { arrow, expression, first, generic, objectReturn, tupleReturn, shadowed } from "../producer/dist/index.js"; import { object, method, accessor, tuple, array, nested } from "../producer/dist/index.js"; import { memberTuple, memberArray, quoted, numeric, key, computed, union, specialized } from "../producer/dist/index.js"; @@ -2579,6 +2732,13 @@ func TestTscIncremental(t *testing.T) { import { nextLink, nextCallable, parenthesized, asserted, Methods, overloaded } from "../producer/dist/index.js"; import { hiddenAlias, siblingHiddenAliases } from "../producer/dist/index.js"; import { nestedNumber } from "../producer/dist/index.js"; + import { mappedCycle, mappedCycleCopy, nestedCycle, cycleKey, keyedCycles, sharedCycles, mutualCycle, shadowedCycle } from "../producer/dist/index.js"; + import { optionalCycle, nullableCycle, mixedCycles, sharedOptionalCycles, nullableKeys, nullableRoot, optionalRoot, nullableLinks, nullishLinks } from "../producer/dist/index.js"; + import { optionalNullableLinks, nullableOptionalLinks } from "../producer/dist/index.js"; + import { mixedUnionCycle, factory, captured, nestedCaptured, constrained, optionalCaptured, annotatedCaptured, recursiveTuple, Nested } from "../producer/dist/index.js"; + import { inferredCaptured, mappedCaptured, freshGeneric, mutualCaptured } from "../producer/dist/index.js"; + import { CapturedClass } from "../producer/dist/index.js"; + import { covariantClass, contravariantClass } from "../producer/dist/index.js"; const a: typeof arrow = arrow()()(); const b: typeof expression = expression()()(); const c: typeof first = first()()(); @@ -2626,9 +2786,109 @@ func TestTscIncremental(t *testing.T) { const copiedInner: string = nestedNumber.copied("inner").inner; const restOuter: number = nestedNumber.rest(true).outer; const restInner: boolean = nestedNumber.rest(true).inner; + const mappedCycleValue: number = mappedCycle.Node.next.next.value; + const copiedMappedValue: number = mappedCycleCopy.Node.next.next.value; + const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; + const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; + const numericMappedValue: boolean = keyedCycles[0].next.next.value; + const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; + const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; + const mutualFirstValue: number = mutualCycle.First.next.next.value; + const mutualSecondValue: string = mutualCycle.First.next.value; + const shadowedMappedValue: number = shadowedCycle.Node.next(1).next("text").value; + const optionalCycleValue: number | undefined = optionalCycle.Node?.next.next.value; + const nullableCycleValue: string | undefined = nullableCycle.Node?.next.next.value; + const mixedCycleValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; + const mixedRequiredValue: number | undefined = mixedCycles.required.Node?.next.next.value; + const sharedOptionalValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; + const quotedNullableValue: string | undefined = nullableKeys["a-b"]?.next.next.value; + const numericNullableValue: boolean | undefined = nullableKeys[0]?.next.next.value; + const symbolNullableValue: number | undefined = nullableKeys[cycleKey]?.next.next.value; + const nullableRootValue: number | undefined = nullableRoot?.next.next.value; + const optionalRootValue: string | undefined = optionalRoot?.next.next.value; + const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; + const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; + const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; + const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; + type OptionalNode = (typeof optionalCycle)["Node"] & {}; + type NullableNode = (typeof nullableCycle)["Node"] & {}; + type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; + type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; + type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; + type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; + const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; + const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; + const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; + const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; + const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; + const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; + const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; + const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; + const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; + const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; + const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; + const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; type IsAny = 0 extends (1 & T) ? true : false; + const anonymousThisResult = anonymousThisReturn().relyingOnThis().relyingOnThis(); + const anonymousThisNotAny: IsAny = false; + const anonymousThisMethodNotAny: IsAny = false; + const conditionalAliasResult = conditionalAliasCopy(); + const conditionalNumber: number = conditionalAliasResult; + const conditionalString: string = conditionalAliasCopy(); + const conditionalNotAny: IsAny = false; const result = arrow()()(); const notAny: false = null as unknown as IsAny; + const mappedNotAny: false = null as unknown as IsAny; + const mutualNotAny: false = null as unknown as IsAny; + const shadowedMappedNotAny: false = null as unknown as IsAny; + const optionalNotAny: IsAny = false; + const nullableNotAny: IsAny = false; + const nullableLinkNotAny: IsAny = false; + const nullishLinkNotAny: IsAny = false; + const optionalNullableLinkNotAny: IsAny = false; + const nullableOptionalLinkNotAny: IsAny = false; + const factoryResult = factory()()()(); + const factoryNotAny: IsAny = false; + const capturedValue: string = captured("text").next().consume("other").value; + const capturedResult = captured("text").next(); + const capturedNotAny: IsAny = false; + const nestedCapturedValue = nestedCaptured(1)("text").shadow(true).next.next(); + const capturedOuter: number = nestedCapturedValue.outer; + const capturedInner: string = nestedCapturedValue.inner; + const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; + const annotatedCapturedValue: string = annotatedCaptured("text").next.next.value; + const recursiveTupleValue: string = recursiveTuple("text")[1][1][0]; + const namespaceValue: number = Nested.captured(1).next().next().value; + const inferredCapturedValue: string = inferredCaptured<() => string>().next.next.value; + const mappedCapturedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; + const freshGenericValue = freshGeneric(1)("text")(true)(2); + const freshGenericNotAny: IsAny = false; + const mutualCapturedValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; + const mutualCapturedResult = mutualCaptured(1, "text").right.self.next.left; + const mutualCapturedNotAny: IsAny = false; + const capturedClassResult = new CapturedClass("text").make("other").next(); + const capturedClassOuter: string = capturedClassResult.outer; + const capturedClassInner: string = capturedClassResult.inner; + const capturedClassNotAny: IsAny = false; + const Covariant = covariantClass(); + const covariantString = new Covariant(); + const covariantUnknown = new Covariant(); + const covariantWide: typeof covariantUnknown = covariantString.next(); + const covariantNotAny: IsAny = false; + const Contravariant = contravariantClass(); + const contravariantString = new Contravariant(); + const contravariantUnknown = new Contravariant(); + const contravariantNarrow: typeof contravariantString = contravariantUnknown.next(); + const contravariantNotAny: IsAny = false; + const optionalCapturedValue = optionalCaptured("text"); + if (optionalCapturedValue.node) { + const value: string = optionalCapturedValue.node.next.next.value; + const notAny: IsAny = false; + } + if (mixedUnionCycle.Node) { + const value: number = mixedUnionCycle.Node.next.next.value; + const notAny: IsAny = false; + } const invalid: number = arrow()()(); const invalidExpression: number = expression()()(); const invalidObject: number = objectReturn().call; @@ -2647,6 +2907,29 @@ func TestTscIncremental(t *testing.T) { const invalidNestedOuter: boolean = nestedString.outer; const invalidNestedInner: string = nestedString.inner; nestedNumber.constrained("wrong"); + const invalidMappedCycleValue: string = mappedCycle.Node.next.next.value; + const invalidMutualCycleValue: number = mutualCycle.First.next.value; + const invalidShadowedMappedValue: string = shadowedCycle.Node.next(1).next("text").value; + const invalidNullNext: OptionalNode["next"] = null; + const invalidUndefinedNext: OptionalNode["next"] = undefined; + const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; + const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; + captured("text").consume(1); + const invalidRecursiveTupleValue: number = recursiveTuple("text")[1][0]; + const invalidCapturedOuter: string = nestedCapturedValue.outer; + const invalidCapturedInner: number = nestedCapturedValue.inner; + type WithoutFalseOrNullish = T extends false | null | undefined ? never : T; + const invalidMixedNext: WithoutFalseOrNullish["next"] = false; + const invalidInferredCapturedValue: number = inferredCaptured<() => string>().next.value; + const invalidMappedCapturedValue: string = mappedCaptured<{ value: number }>().value.next.value.value; + const invalidMutualCapturedValue: boolean = mutualCaptured(1, "text").right.self.next.left; + const invalidCapturedClassValue: number = capturedClassResult.outer; + const invalidCovariance: typeof covariantString = covariantUnknown.next(); + const invalidContravariance: typeof contravariantUnknown = contravariantString.next(); + const invalidAnonymousThis: number = anonymousThisResult; + const invalidAnonymousThisMethod: number = anonymousThisResult.relyingOnThis; + const invalidConditionalAlias: string = conditionalAliasResult; + const invalidConditionalAliasArray: number[] = conditionalAliasResult; `), }, commandLineArgs: []string{"--build", "consumer"}, @@ -2661,6 +2944,84 @@ func TestTscIncremental(t *testing.T) { noChange, }, }, + { + subScenario: "recursive global declaration consumption", + files: FileMap{ + "/home/src/workspaces/project/first/tsconfig.json": `{ + "compilerOptions": { "strict": true, "composite": true, "outDir": "dist" }, + "files": ["index.ts"] + }`, + "/home/src/workspaces/project/first/index.ts": stringtestutil.Dedent(` + function makeA() { + return { value: 1, self() { return this; } }; + } + type makeReserved_recursive = "reserved"; + function makeReserved() { + return { value: true, self() { return this; } }; + } + class GlobalA { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } + } + `), + "/home/src/workspaces/project/second/tsconfig.json": `{ + "compilerOptions": { "strict": true, "composite": true, "outDir": "dist" }, + "files": ["index.ts"] + }`, + "/home/src/workspaces/project/second/index.ts": stringtestutil.Dedent(` + function makeB() { + return { value: "text", self() { return this; } }; + } + class GlobalB { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + } + `), + "/home/src/workspaces/project/consumer/tsconfig.json": `{ + "compilerOptions": { "strict": true, "composite": true, "skipLibCheck": false }, + "files": ["index.ts", "../first/dist/index.d.ts", "../second/dist/index.d.ts"], + "references": [{ "path": "../first" }, { "path": "../second" }] + }`, + "/home/src/workspaces/project/consumer/index.ts": stringtestutil.Dedent(` + export {}; + const fromA: number = makeA().self().value; + const fromB: string = makeB().self().value; + const reserved: boolean = makeReserved().self().value; + const genericA: string = GlobalA.create("text").next().value; + const genericB: number = GlobalB.create(1).next().value; + const quoted: boolean = GlobalA["a-b"]().next().value; + const invalidA: string = makeA().self().value; + const invalidB: number = makeB().self().value; + `), + }, + commandLineArgs: []string{"--build", "consumer"}, + edits: []*tscEdit{ + noChange, + { + caption: "add a comment to the first script", + edit: func(sys *TestSys) { + sys.appendFile("/home/src/workspaces/project/first/index.ts", "\n// comment-only edit\n") + }, + }, + noChange, + { + caption: "check both declarations with skipLibCheck", + edit: func(sys *TestSys) { + path := "/home/src/workspaces/project/consumer/tsconfig.json" + sys.writeFileNoError(path, strings.ReplaceAll(sys.readFileNoError(path), `"skipLibCheck": false`, `"skipLibCheck": true`)) + }, + }, + noChange, + }, + }, { subScenario: "json module diagnostics are cleared after fixing the json file", files: FileMap{ diff --git a/tsc/internal/fourslash/tests/recursiveFunctionQuickInfo_test.go b/tsc/internal/fourslash/tests/recursiveFunctionQuickInfo_test.go index ea030f1b9a49d..da203835241d5 100644 --- a/tsc/internal/fourslash/tests/recursiveFunctionQuickInfo_test.go +++ b/tsc/internal/fourslash/tests/recursiveFunctionQuickInfo_test.go @@ -111,7 +111,38 @@ declare const reused: { }; const copy/*reusedDeclaration*/ = reused; copy.first/*reusedFirst*/(1); -copy.shadowed/*reusedShadowed*/(1);` +copy.shadowed/*reusedShadowed*/(1); +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +const mappedCycle/*mappedCycle*/ = build<{ Node: { value: number; next: "ref" } }>(); +mappedCycle.Node/*mappedNode*/.next/*mappedNext*/.next.value; +const nestedCycle/*nestedMappedCycle*/ = { wrapped: mappedCycle }; +const sharedCycles/*sharedMappedCycles*/ = { first: mappedCycle, second: mappedCycle }; +declare const buildOptional: () => { [K in keyof M]?: Resolve }; +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +const optionalBox/*optionalMappedCycle*/ = { cycle: buildOptional<{ Node: { value: number; next: "ref" } }>() }; +const nullableBox/*nullableMappedCycle*/ = { cycle: buildNullable<{ Node: { value: number; next: "ref" } }>() }; +type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +const nullableLinkBox/*nullableMappedLinks*/ = { cycle: buildNullableLinks<{ Node: { value: number; next: "ref" } }>() }; +function captured(value: T) { + const node = { value, next: () => node }; + return node; +} +const capturedValue/*capturedValue*/ = captured(1); +capturedValue.next/*capturedNext*/(); +function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); +} +const inferredValue/*inferredCapturedValue*/ = inferredCaptured<() => string>(); +declare const buildMixed: () => { [K in keyof M]?: Resolve | false | null }; +const mixedBox/*mixedMappedCycle*/ = { cycle: buildMixed<{ Node: { value: number; next: "ref" } }>() };` f, done := fourslash.NewFourslash(t, nil, content) defer done() f.VerifyNoErrors(t) @@ -129,5 +160,11 @@ copy.shadowed/*reusedShadowed*/(1);` "reusedFirst": {0}, "reusedShadowed": {0}, "nestedNumber": {0}, "nestedGeneric": {0}, "nestedOwnerMake": {0}, "nestedConstrained": {0}, "nestedCopied": {0}, "nestedRest": {0}, + "mappedCycle": {0, 1}, "mappedNode": {0}, "mappedNext": {0}, + "nestedMappedCycle": {0}, "sharedMappedCycles": {0}, + "optionalMappedCycle": {0, 1}, "nullableMappedCycle": {0}, + "nullableMappedLinks": {0}, + "capturedValue": {0, 1}, "capturedNext": {0}, + "inferredCapturedValue": {0}, "mixedMappedCycle": {0}, }) } diff --git a/tsc/internal/nodebuilder/types.go b/tsc/internal/nodebuilder/types.go index 92f3d36d1144f..e28a00177de65 100644 --- a/tsc/internal/nodebuilder/types.go +++ b/tsc/internal/nodebuilder/types.go @@ -20,6 +20,10 @@ type SymbolTracker interface { ReportInferenceFallback(node *ast.Node) PushErrorFallbackNode(node *ast.Node) PopErrorFallbackNode() + + // Used when InternalFlagsSynthesizeTypeAliases is enabled. + TypeAliasScope() *ast.Node + AddTypeAliasDeclaration(declaration *ast.Node) } // NOTE: If modifying this enum, must modify `TypeFormatFlags` too! @@ -75,4 +79,5 @@ const ( InternalFlagsNoSyntacticPrinter InternalFlags = 1 << 1 InternalFlagsDoNotIncludeSymbolChain InternalFlags = 1 << 2 InternalFlagsAllowUnresolvedNames InternalFlags = 1 << 3 + InternalFlagsSynthesizeTypeAliases InternalFlags = 1 << 4 ) diff --git a/tsc/internal/transformers/declarations/tracker.go b/tsc/internal/transformers/declarations/tracker.go index 14d0fcd5e5032..b2d63fe498586 100644 --- a/tsc/internal/transformers/declarations/tracker.go +++ b/tsc/internal/transformers/declarations/tracker.go @@ -23,6 +23,14 @@ type SymbolTrackerImpl struct { getIsolatedDeclarationError func(node *ast.Node) *ast.Diagnostic } +func (s *SymbolTrackerImpl) TypeAliasScope() *ast.Node { + return s.state.typeAliasScope +} + +func (s *SymbolTrackerImpl) AddTypeAliasDeclaration(declaration *ast.Node) { + s.state.typeAliases = append(s.state.typeAliases, declaration) +} + // PopErrorFallbackNode implements checker.SymbolTracker. func (s *SymbolTrackerImpl) PopErrorFallbackNode() { s.fallbackStack = s.fallbackStack[:len(s.fallbackStack)-1] @@ -237,6 +245,8 @@ func createDiagnosticForNode(node *ast.Node, message *diagnostics.Message, args } type SymbolTrackerSharedState struct { + typeAliasScope *ast.Node + typeAliases []*ast.Node lateMarkedStatements []*ast.Node diagnostics []*ast.Diagnostic getSymbolAccessibilityDiagnostic GetSymbolAccessibilityDiagnostic diff --git a/tsc/internal/transformers/declarations/transform.go b/tsc/internal/transformers/declarations/transform.go index f2bb66a6803cb..767e0733a3e4c 100644 --- a/tsc/internal/transformers/declarations/transform.go +++ b/tsc/internal/transformers/declarations/transform.go @@ -218,7 +218,8 @@ const declarationEmitNodeBuilderFlags = nodebuilder.FlagsMultilineObjectLiterals nodebuilder.FlagsGenerateNamesForShadowedTypeParams | nodebuilder.FlagsNoTruncation -const declarationEmitInternalNodeBuilderFlags = nodebuilder.InternalFlagsAllowUnresolvedNames +const declarationEmitInternalNodeBuilderFlags = nodebuilder.InternalFlagsAllowUnresolvedNames | + nodebuilder.InternalFlagsSynthesizeTypeAliases // functions as both `visitDeclarationStatements` and `transformRoot`, utilitzing SyntaxList nodes func (tx *DeclarationTransformer) visit(node *ast.Node) *ast.Node { @@ -298,6 +299,8 @@ func (tx *DeclarationTransformer) visitSourceFile(node *ast.SourceFile) *ast.Nod tx.rawLibReferenceDirectives = make([]*ast.FileReference, 0) tx.witnessedCjsExports.Clear() tx.state.currentSourceFile = node + tx.state.typeAliasScope = node.AsNode() + tx.state.typeAliases = nil tx.collectFileReferences(node) tx.resolver.PrecalculateDeclarationEmitVisibility(tx.EmitContext().MostOriginal(node.AsNode()).AsSourceFile()) updated := tx.transformSourceFile(node) @@ -351,6 +354,14 @@ func (tx *DeclarationTransformer) transformSourceFile(node *ast.SourceFile) *ast statements := tx.Visitor().VisitNodes(node.Statements) combinedStatements = tx.transformAndReplaceLatePaintedStatements(statements) combinedStatements = tx.appendCjsExports(combinedStatements) + if len(tx.state.typeAliases) != 0 { + combinedStatements = tx.Factory().NewNodeList(append(tx.state.typeAliases, combinedStatements.Nodes...)) + tx.needsScopeFixMarker = true + if ast.IsExternalOrCommonJSModule(node) && !hasScopeMarker(combinedStatements) { + combinedStatements = tx.Factory().NewNodeList(append(combinedStatements.Nodes, createEmptyExports(tx.Factory().AsNodeFactory()))) + tx.resultHasScopeMarker = true + } + } combinedStatements.Loc = statements.Loc // setTextRange if ast.IsExternalOrCommonJSModule(node) { if ast.IsInJSFile(node.AsNode()) { @@ -1843,6 +1854,8 @@ func (tx *DeclarationTransformer) transformModuleDeclaration(input *ast.ModuleDe attributes := tx.Visitor().Visit(input.Attributes) if inner != nil && inner.Kind == ast.KindModuleBlock { + oldTypeAliasScope, oldTypeAliases := tx.state.typeAliasScope, tx.state.typeAliases + tx.state.typeAliasScope, tx.state.typeAliases = input.AsNode(), nil oldNeedsScopeFix := tx.needsScopeFixMarker oldHasScopeFix := tx.resultHasScopeMarker tx.resultHasScopeMarker = false @@ -1852,6 +1865,11 @@ func (tx *DeclarationTransformer) transformModuleDeclaration(input *ast.ModuleDe if input.Flags&ast.NodeFlagsAmbient != 0 { tx.needsScopeFixMarker = false // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates" } + if len(tx.state.typeAliases) != 0 { + lateStatements = tx.Factory().NewNodeList(append(tx.state.typeAliases, lateStatements.Nodes...)) + tx.needsScopeFixMarker = true + } + tx.state.typeAliasScope, tx.state.typeAliases = oldTypeAliasScope, oldTypeAliases // With the final list of statements, there are 3 possibilities: // 1. There's an export assignment or export declaration in the namespace - do nothing // 2. Everything is exported and there are no export assignments or export declarations - strip all export modifiers diff --git a/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.errors.txt b/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.errors.txt deleted file mode 100644 index 2108e03d4a196..0000000000000 --- a/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.errors.txt +++ /dev/null @@ -1,21 +0,0 @@ -arrayFakeFlatNoCrashInferenceDeclarations.ts(13,10): error TS5088: The inferred type of 'foo' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - - -==== arrayFakeFlatNoCrashInferenceDeclarations.ts (1 errors) ==== - type BadFlatArray = {obj: { - "done": Arr, - "recur": Arr extends ReadonlyArray - ? BadFlatArray - : Arr - }[Depth extends -1 ? "done" : "recur"]}["obj"]; - - declare function flat( - arr: A, - depth?: D - ): BadFlatArray[] - - function foo(arr: T[], depth: number) { - ~~~ -!!! error TS5088: The inferred type of 'foo' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - return flat(arr, depth); - } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.js b/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.js index b743d30cd5d36..b91965f3ff5a5 100644 --- a/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.js +++ b/tsc/testdata/baselines/reference/compiler/arrayFakeFlatNoCrashInferenceDeclarations.js @@ -22,3 +22,15 @@ function foo(arr: T[], depth: number) { function foo(arr, depth) { return flat(arr, depth); } + + +//// [arrayFakeFlatNoCrashInferenceDeclarations.d.ts] +type foo_recursive = InnerArr | (InnerArr extends readonly (infer InnerArr)[] ? foo_recursive : InnerArr); +type BadFlatArray = { + obj: { + "done": Arr; + "recur": Arr extends ReadonlyArray ? BadFlatArray : Arr; + }[Depth extends -1 ? "done" : "recur"]; +}["obj"]; +declare function flat(arr: A, depth?: D): BadFlatArray[]; +declare function foo(arr: T[], depth: number): (T | (T extends readonly (infer InnerArr)[] ? foo_recursive : T))[]; diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.errors.txt b/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.errors.txt index f4858319ecf28..beed1cd04564c 100644 --- a/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.errors.txt @@ -1,11 +1,8 @@ -declarationEmitInferredTypeAlias4.ts(1,10): error TS5088: The inferred type of 'f' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. declarationEmitInferredTypeAlias4.ts(4,12): error TS2454: Variable 'x' is used before being assigned. -==== declarationEmitInferredTypeAlias4.ts (2 errors) ==== +==== declarationEmitInferredTypeAlias4.ts (1 errors) ==== function f() { - ~ -!!! error TS5088: The inferred type of 'f' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. type Foo = T | { x: Foo }; var x: Foo; return x; diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.js b/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.js index 00652e1bd00da..51364e3a60fa3 100644 --- a/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.js +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitInferredTypeAlias4.js @@ -13,3 +13,10 @@ function f() { var x; return x; } + + +//// [declarationEmitInferredTypeAlias4.d.ts] +type f_recursive = { + x: A[] | f_recursive; +}; +declare function f(): A[] | f_recursive; diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.errors.txt b/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.errors.txt deleted file mode 100644 index 567eef6a3269f..0000000000000 --- a/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.errors.txt +++ /dev/null @@ -1,74 +0,0 @@ -declarationEmitStaticMethodNonIdentifierNames.ts(56,12): error TS5088: The inferred type of 'getRec' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - - -==== declarationEmitStaticMethodNonIdentifierNames.ts (1 errors) ==== - declare const uniqueSym: unique symbol; - - // none of these names can be written as `typeof Foo.` - export class Foo { - static #priv() { } - static getPriv() { - return Foo.#priv; - } - - static "quoted-name"() { } - static getQuoted() { - return Foo["quoted-name"]; - } - - static ["computed-name"]() { } - static getComputed() { - return Foo["computed-name"]; - } - - static 1() { } - static getNumeric() { - return Foo[1]; - } - - static [uniqueSym]() { } - static getUnique() { - return Foo[uniqueSym]; - } - - // property types go through the same path - static privRef = Foo.#priv; - } - - // identifier names still use `typeof` - export class Writable { - static normalName() { } - static getNormal() { - return Writable.normalName; - } - - static $dollar() { } - static getDollar() { - return Writable.$dollar; - } - } - - export class Generic { - static #priv(x: T): T { return x; } - static getPriv() { - return Generic.#priv; - } - } - - export class Recursive { - static #rec() { return Recursive.#rec; } - static getRec() { - ~~~~~~ -!!! error TS5088: The inferred type of 'getRec' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - return Recursive.#rec; - } - } - - // instance members already fall back to a structural type - export class Instance { - #priv() { } - getPriv() { - return this.#priv; - } - } - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.js b/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.js index 22995a34b56a3..bbd18f9310420 100644 --- a/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.js +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitStaticMethodNonIdentifierNames.js @@ -126,3 +126,40 @@ export class Instance { return this.#priv; } } + + +//// [declarationEmitStaticMethodNonIdentifierNames.d.ts] +type Recursive_getRec_recursive = () => Recursive_getRec_recursive; +declare const uniqueSym: unique symbol; +export declare class Foo { + #private; + static getPriv(): () => void; + static "quoted-name"(): void; + static getQuoted(): (typeof Foo)["quoted-name"]; + static ["computed-name"](): void; + static getComputed(): (typeof Foo)["computed-name"]; + static 1(): void; + static getNumeric(): (typeof Foo)[1]; + static [uniqueSym](): void; + static getUnique(): (typeof Foo)[typeof uniqueSym]; + static privRef: () => void; +} +export declare class Writable { + static normalName(): void; + static getNormal(): (typeof Writable)["normalName"]; + static $dollar(): void; + static getDollar(): (typeof Writable)["$dollar"]; +} +export declare class Generic { + #private; + static getPriv(): (x: T) => T; +} +export declare class Recursive { + #private; + static getRec(): Recursive_getRec_recursive; +} +export declare class Instance { + #private; + getPriv(): () => void; +} +export {}; diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.errors.txt b/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.errors.txt index 79536369d0a1a..177d8ae829611 100644 --- a/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.errors.txt @@ -1,25 +1,16 @@ growing.ts(1,17): error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. -local.ts(1,17): error TS5088: The inferred type of 'localArrow' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -local.ts(5,17): error TS5088: The inferred type of 'localDeclaration' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -local.ts(9,17): error TS5088: The inferred type of 'localInstantiation' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -==== local.ts (3 errors) ==== +==== local.ts (0 errors) ==== export function localArrow() { - ~~~~~~~~~~ -!!! error TS5088: The inferred type of 'localArrow' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. const inner = () => inner; return inner; } export function localDeclaration() { - ~~~~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'localDeclaration' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. function inner() { return inner; } return inner; } export function localInstantiation() { - ~~~~~~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'localInstantiation' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. function inner(): typeof inner { return inner; } return inner; } diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.js b/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.js index 459a409101941..27f4364e410ba 100644 --- a/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.js +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitUnserializableTypes.js @@ -71,6 +71,20 @@ export function local() { } +//// [local.d.ts] +type localArrow_recursive = () => localArrow_recursive; +type localDeclaration_recursive = () => localDeclaration_recursive; +type localInstantiation_recursive = () => localInstantiation_recursive; +export declare function localArrow(): localArrow_recursive; +export declare function localDeclaration(): localDeclaration_recursive; +export declare function localInstantiation(): () => localInstantiation_recursive; +export declare const object: { + self(): typeof object; +}; +export declare const annotatedObject: { + self(): typeof annotatedObject; +}; +export {}; //// [annotatedLocal.d.ts] interface Recursive { (): Recursive; diff --git a/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.errors.txt b/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.errors.txt deleted file mode 100644 index 4f2b2899d9424..0000000000000 --- a/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.errors.txt +++ /dev/null @@ -1,36 +0,0 @@ -emitClassExpressionInDeclarationFile.ts(5,12): error TS5088: The inferred type of 'circularReference' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - - -==== emitClassExpressionInDeclarationFile.ts (1 errors) ==== - export var simpleExample = class { - static getTags() { } - tags() { } - } - export var circularReference = class C { - ~~~~~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'circularReference' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - static getTags(c: C): C { return c } - tags(c: C): C { return c } - } - - // repro from #15066 - export class FooItem { - foo(): void { } - name?: string; - } - - export type Constructor = new(...args: any[]) => T; - export function WithTags>(Base: T) { - return class extends Base { - static getTags(): void { } - tags(): void { } - } - } - - export class Test extends WithTags(FooItem) {} - - const test = new Test(); - - Test.getTags() - test.tags(); - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.js b/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.js index 5fb0a6eb4a94c..16996268f1d17 100644 --- a/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.js +++ b/tsc/testdata/baselines/reference/compiler/emitClassExpressionInDeclarationFile.js @@ -64,3 +64,43 @@ exports.Test = Test; const test = new Test(); Test.getTags(); test.tags(); + + +//// [emitClassExpressionInDeclarationFile.d.ts] +type circularReference_recursive = { + tags(c: circularReference_recursive): circularReference_recursive; +}; +export declare var simpleExample: { + new (): { + tags(): void; + }; + getTags(): void; +}; +export declare var circularReference: { + new (): circularReference_recursive; + getTags(c: circularReference_recursive): circularReference_recursive; +}; +export declare class FooItem { + foo(): void; + name?: string; +} +export type Constructor = new (...args: any[]) => T; +export declare function WithTags>(Base: T): { + new (...args: any[]): { + tags(): void; + foo(): void; + name?: string; + }; + getTags(): void; +} & T; +declare const Test_base: { + new (...args: any[]): { + tags(): void; + foo(): void; + name?: string; + }; + getTags(): void; +} & typeof FooItem; +export declare class Test extends Test_base { +} +export {}; diff --git a/tsc/testdata/baselines/reference/compiler/isolatedDeclarationErrorsReturnTypes.types b/tsc/testdata/baselines/reference/compiler/isolatedDeclarationErrorsReturnTypes.types index 018c65416107d..1861b303b9d64 100644 --- a/tsc/testdata/baselines/reference/compiler/isolatedDeclarationErrorsReturnTypes.types +++ b/tsc/testdata/baselines/reference/compiler/isolatedDeclarationErrorsReturnTypes.types @@ -34,7 +34,7 @@ export const recursiveNamed = function self() { return self; }; export const annotatedRecursiveArrow: () => typeof annotatedRecursiveArrow = () => annotatedRecursiveArrow; >annotatedRecursiveArrow : () => typeof annotatedRecursiveArrow >annotatedRecursiveArrow : () => typeof annotatedRecursiveArrow ->() => annotatedRecursiveArrow : () => () => typeof annotatedRecursiveArrow +>() => annotatedRecursiveArrow : () => typeof annotatedRecursiveArrow >annotatedRecursiveArrow : () => typeof annotatedRecursiveArrow export const annotatedRecursiveObject: { next: () => typeof annotatedRecursiveObject } = { diff --git a/tsc/testdata/baselines/reference/compiler/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types b/tsc/testdata/baselines/reference/compiler/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types index 78d4ddc68b3f1..d6f8de4e5f5e4 100644 --- a/tsc/testdata/baselines/reference/compiler/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types +++ b/tsc/testdata/baselines/reference/compiler/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types @@ -2,7 +2,7 @@ === index.js === function Color(obj) { ->Color : { (obj: any): void; prototype: { negate: () => any; lighten: (ratio: any) => any; darken: (ratio: any) => any; saturate: (ratio: any) => any; desaturate: (ratio: any) => any; whiten: (ratio: any) => any; blacken: (ratio: any) => any; greyscale: () => any; clearer: (ratio: any) => any; toJSON: () => any; }; } +>Color : { (obj: any): void; prototype: { negate: () => typeof Color.prototype; lighten: (ratio: any) => typeof Color.prototype; darken: (ratio: any) => typeof Color.prototype; saturate: (ratio: any) => typeof Color.prototype; desaturate: (ratio: any) => typeof Color.prototype; whiten: (ratio: any) => typeof Color.prototype; blacken: (ratio: any) => typeof Color.prototype; greyscale: () => typeof Color.prototype; clearer: (ratio: any) => typeof Color.prototype; toJSON: () => any; }; } >obj : any this.example = true @@ -16,7 +16,7 @@ function Color(obj) { Color.prototype = { >Color.prototype = { negate: function () {return this;}, lighten: function (ratio) {return this;}, darken: function (ratio) {return this;}, saturate: function (ratio) {return this;}, desaturate: function (ratio) {return this;}, whiten: function (ratio) {return this;}, blacken: function (ratio) {return this;}, greyscale: function () {return this;}, clearer: function (ratio) {return this;}, toJSON: function () {return this.rgb();},} : { negate: () => any; lighten: (ratio: any) => any; darken: (ratio: any) => any; saturate: (ratio: any) => any; desaturate: (ratio: any) => any; whiten: (ratio: any) => any; blacken: (ratio: any) => any; greyscale: () => any; clearer: (ratio: any) => any; toJSON: () => any; } >Color.prototype : { negate: () => any; lighten: (ratio: any) => any; darken: (ratio: any) => any; saturate: (ratio: any) => any; desaturate: (ratio: any) => any; whiten: (ratio: any) => any; blacken: (ratio: any) => any; greyscale: () => any; clearer: (ratio: any) => any; toJSON: () => any; } ->Color : { (obj: any): void; prototype: { negate: () => any; lighten: (ratio: any) => any; darken: (ratio: any) => any; saturate: (ratio: any) => any; desaturate: (ratio: any) => any; whiten: (ratio: any) => any; blacken: (ratio: any) => any; greyscale: () => any; clearer: (ratio: any) => any; toJSON: () => any; }; } +>Color : { (obj: any): void; prototype: { negate: () => typeof Color.prototype; lighten: (ratio: any) => typeof Color.prototype; darken: (ratio: any) => typeof Color.prototype; saturate: (ratio: any) => typeof Color.prototype; desaturate: (ratio: any) => typeof Color.prototype; whiten: (ratio: any) => typeof Color.prototype; blacken: (ratio: any) => typeof Color.prototype; greyscale: () => typeof Color.prototype; clearer: (ratio: any) => typeof Color.prototype; toJSON: () => any; }; } >prototype : { negate: () => any; lighten: (ratio: any) => any; darken: (ratio: any) => any; saturate: (ratio: any) => any; desaturate: (ratio: any) => any; whiten: (ratio: any) => any; blacken: (ratio: any) => any; greyscale: () => any; clearer: (ratio: any) => any; toJSON: () => any; } >{ negate: function () {return this;}, lighten: function (ratio) {return this;}, darken: function (ratio) {return this;}, saturate: function (ratio) {return this;}, desaturate: function (ratio) {return this;}, whiten: function (ratio) {return this;}, blacken: function (ratio) {return this;}, greyscale: function () {return this;}, clearer: function (ratio) {return this;}, toJSON: function () {return this.rgb();},} : { negate: () => any; lighten: (ratio: any) => any; darken: (ratio: any) => any; saturate: (ratio: any) => any; desaturate: (ratio: any) => any; whiten: (ratio: any) => any; blacken: (ratio: any) => any; greyscale: () => any; clearer: (ratio: any) => any; toJSON: () => any; } diff --git a/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.errors.txt b/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.errors.txt deleted file mode 100644 index f4a4732e45395..0000000000000 --- a/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.errors.txt +++ /dev/null @@ -1,57 +0,0 @@ -noImplicitThisBigThis.ts(3,10): error TS5088: The inferred type of 'createObj' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -noImplicitThisBigThis.ts(17,10): error TS5088: The inferred type of 'createObjNoCrash' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - - -==== noImplicitThisBigThis.ts (2 errors) ==== - // https://github.com/microsoft/TypeScript/issues/29902 - - function createObj() { - ~~~~~~~~~ -!!! error TS5088: The inferred type of 'createObj' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - return { - func1() { - return this; - }, - func2() { - return this; - }, - func3() { - return this; - } - }; - } - - function createObjNoCrash() { - ~~~~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'createObjNoCrash' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - return { - func1() { - return this; - }, - func2() { - return this; - }, - func3() { - return this; - }, - func4() { - return this; - }, - func5() { - return this; - }, - func6() { - return this; - }, - func7() { - return this; - }, - func8() { - return this; - }, - func9() { - return this; - } - }; - } - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.js b/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.js index 57b0614056a9f..74a87586f654b 100644 --- a/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.js +++ b/tsc/testdata/baselines/reference/compiler/noImplicitThisBigThis.js @@ -97,3 +97,38 @@ function createObjNoCrash() { } }; } + + +//// [noImplicitThisBigThis.d.ts] +type createObj_recursive = { + func1(): createObj_recursive; + func2(): createObj_recursive; + func3(): createObj_recursive; +}; +type createObjNoCrash_recursive = { + func1(): createObjNoCrash_recursive; + func2(): createObjNoCrash_recursive; + func3(): createObjNoCrash_recursive; + func4(): createObjNoCrash_recursive; + func5(): createObjNoCrash_recursive; + func6(): createObjNoCrash_recursive; + func7(): createObjNoCrash_recursive; + func8(): createObjNoCrash_recursive; + func9(): createObjNoCrash_recursive; +}; +declare function createObj(): { + func1(): createObj_recursive; + func2(): createObj_recursive; + func3(): createObj_recursive; +}; +declare function createObjNoCrash(): { + func1(): createObjNoCrash_recursive; + func2(): createObjNoCrash_recursive; + func3(): createObjNoCrash_recursive; + func4(): createObjNoCrash_recursive; + func5(): createObjNoCrash_recursive; + func6(): createObjNoCrash_recursive; + func7(): createObjNoCrash_recursive; + func8(): createObjNoCrash_recursive; + func9(): createObjNoCrash_recursive; +}; diff --git a/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.errors.txt b/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.errors.txt deleted file mode 100644 index d46d1d28ca109..0000000000000 --- a/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.errors.txt +++ /dev/null @@ -1,48 +0,0 @@ -local.ts(1,17): error TS5088: The inferred type of 'array' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -local.ts(5,17): error TS5088: The inferred type of 'tuple' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -local.ts(9,17): error TS5088: The inferred type of 'readonlyTuple' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -local.ts(13,17): error TS5088: The inferred type of 'union' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - - -==== local.ts (4 errors) ==== - export function array() { - ~~~~~ -!!! error TS5088: The inferred type of 'array' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - type Recursive = Recursive[]; - return null as unknown as Recursive; - } - export function tuple() { - ~~~~~ -!!! error TS5088: The inferred type of 'tuple' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - type Recursive = [Recursive]; - return null as unknown as Recursive; - } - export function readonlyTuple() { - ~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'readonlyTuple' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - type Recursive = readonly [Recursive]; - return null as unknown as Recursive; - } - export function union() { - ~~~~~ -!!! error TS5088: The inferred type of 'union' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. - type Recursive = string | Recursive[]; - return null as unknown as Recursive; - } - -==== nameable.ts (0 errors) ==== - export type RecursiveArray = RecursiveArray[]; - export type RecursiveTuple = readonly [RecursiveTuple]; - declare const array: RecursiveArray; - declare const tuple: RecursiveTuple; - export const namedArray = array; - export const namedTuple = tuple; - export function finite() { - type Nested = [[[[[[[[[[[[[number]]]]]]]]]]]]]; - return null as unknown as Nested; - } - export function finiteArray() { - type Nested = number[][][][][][][][][][][][][]; - return null as unknown as Nested; - } - \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.js b/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.js index 41639f70320d7..c9759cd4230cd 100644 --- a/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.js +++ b/tsc/testdata/baselines/reference/compiler/recursiveContainerDeclarationSerialization.js @@ -59,6 +59,16 @@ export function finiteArray() { } +//// [local.d.ts] +type array_recursive = array_recursive[]; +type tuple_recursive = [tuple_recursive]; +type readonlyTuple_recursive = readonly [readonlyTuple_recursive]; +type union_recursive = (string | union_recursive)[]; +export declare function array(): array_recursive; +export declare function tuple(): tuple_recursive; +export declare function readonlyTuple(): readonlyTuple_recursive; +export declare function union(): string | union_recursive; +export {}; //// [nameable.d.ts] export type RecursiveArray = RecursiveArray[]; export type RecursiveTuple = readonly [RecursiveTuple]; diff --git a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.errors.txt b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.errors.txt index f3575f8c60533..f25d79cbf29d4 100644 --- a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.errors.txt @@ -1,17 +1,19 @@ +anonymousBindings.ts(93,26): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +anonymousBindings.ts(94,7): error TS2322: Type 'string' is not assignable to type 'number'. consumer.ts(11,7): error TS2322: Type '() => typeof arrow' is not assignable to type 'number'. consumer.ts(13,25): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -hiddenReferences.ts(3,12): error TS5088: The inferred type of 'expose' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -hiddenReferences.ts(4,15): error TS5088: The inferred type of 'next' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -hiddenReferences.ts(5,5): error TS5088: The inferred type of 'expose' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. +mappedCycles.ts(38,7): error TS2322: Type 'number' is not assignable to type 'string'. +mappedCycles.ts(39,7): error TS2322: Type 'string' is not assignable to type 'number'. namedReferences.ts(28,7): error TS2322: Type 'string' is not assignable to type 'number'. namedReferences.ts(29,14): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -nestedNamedFunctions.ts(5,14): error TS5088: The inferred type of 'factory' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -nestedNamedFunctions.ts(8,17): error TS5088: The inferred type of 'local' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. +optionalMappedCycle.ts(73,7): error TS2322: Type 'null' is not assignable to type '{ value: number; next: any; }'. +optionalMappedCycle.ts(74,7): error TS2322: Type 'undefined' is not assignable to type '{ value: number; next: any; }'. +optionalMappedCycle.ts(75,42): error TS2531: Object is possibly 'null'. +optionalMappedCycle.ts(76,41): error TS2533: Object is possibly 'null' or 'undefined'. recursiveAnnotations.ts(2,15): error TS2502: 'tuple' is referenced directly or indirectly in its own type annotation. recursiveAnnotations.ts(3,15): error TS2502: 'array' is referenced directly or indirectly in its own type annotation. recursiveAnnotations.ts(8,15): error TS2502: 'union' is referenced directly or indirectly in its own type annotation. recursiveAnnotations.ts(9,15): error TS2502: 'conditional' is referenced directly or indirectly in its own type annotation. -recursiveObject.ts(1,17): error TS5088: The inferred type of 'recursiveObject' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. recursiveObject.ts(12,7): error TS2322: Type '(arg: U) => { call: any; consume: (arg: number) => any; }' is not assignable to type 'number'. recursiveObject.ts(13,16): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. recursiveStructures.ts(47,7): error TS2322: Type 'string' is not assignable to type 'number'. @@ -74,10 +76,8 @@ recursiveStructures.ts(47,7): error TS2322: Type 'string' is not assignable to t const tupleCall: typeof tupleReturn = tupleReturn()[0]()[0]; const shadowedCall: typeof shadowed = shadowed(1)(2); -==== recursiveObject.ts (3 errors) ==== +==== recursiveObject.ts (2 errors) ==== export function recursiveObject() { - ~~~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'recursiveObject' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. const value = { call: (arg: U) => value, consume: (arg: T) => value, @@ -95,19 +95,15 @@ recursiveStructures.ts(47,7): error TS2322: Type 'string' is not assignable to t ~~~~~~~ !!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -==== nestedNamedFunctions.ts (2 errors) ==== +==== nestedNamedFunctions.ts (0 errors) ==== export const nestedObject = { recur: () => nestedObject.recur }; export const nestedTuple = [() => nestedTuple[0]] as const; export const object = { recur: function self() { return self; } }; export const tuple = [function self() { return self; }] as const; export const factory = () => function self() { return self; }; - ~~~~~~~ -!!! error TS5088: The inferred type of 'factory' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. export const method = { recur() { return method; } }; export const accessor = { get recur() { return accessor; } }; export function local() { - ~~~~~ -!!! error TS5088: The inferred type of 'local' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. function recur() { return recur; } return recur; } @@ -217,18 +213,12 @@ recursiveStructures.ts(47,7): error TS2322: Type 'string' is not assignable to t ~~~~~~~ !!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -==== hiddenReferences.ts (3 errors) ==== +==== hiddenReferences.ts (0 errors) ==== export class Hidden { private static recur() { return Hidden.recur; } static expose() { return Hidden.recur; } - ~~~~~~ -!!! error TS5088: The inferred type of 'expose' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. protected next() { return this.next; } - ~~~~ -!!! error TS5088: The inferred type of 'next' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. expose() { return this.next; } - ~~~~~~ -!!! error TS5088: The inferred type of 'expose' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. } ==== signatureScopes.ts (0 errors) ==== @@ -293,4 +283,316 @@ recursiveStructures.ts(47,7): error TS2322: Type 'string' is not assignable to t export declare const inferred: Inferred<(value: number) => { next: typeof reused }>; export const inferredCopy = inferred; const inferredValue: string = inferredCopy.next(1).second("text").value; + +==== mappedCycles.ts (2 errors) ==== + type Show = { [K in keyof T]: T[K] } & unknown; + type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; + }>; + declare const build: () => { [K in keyof M]: Resolve }; + export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); + export const mappedCycleCopy = mappedCycle; + export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; + export const cycleKey = Symbol(); + export const keyedCycles = build<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; + }>(); + export const sharedCycles = { + first: mappedCycle, + second: mappedCycle, + }; + export const broadCycle: { Node: unknown } = mappedCycle; + + type ResolveMutual = Show<{ + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; + }>; + declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; + export const mutualCycle = buildMutual<{ + First: { value: number; next: { ref: "Second" } }; + Second: { value: string; next: { ref: "First" } }; + }>(); + + const mappedValue: number = mappedCycle.Node.next.next.value; + const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; + const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; + const numericMappedValue: boolean = keyedCycles[0].next.next.value; + const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; + const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; + const mutualFirstValue: number = mutualCycle.First.next.next.value; + const mutualSecondValue: string = mutualCycle.First.next.value; + const invalidMappedValue: string = mappedCycle.Node.next.next.value; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + const invalidMutualValue: number = mutualCycle.First.next.value; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + +==== optionalMappedCycle.ts (4 errors) ==== + type Show = { [K in keyof T]: T[K] } & unknown; + type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; + }>; + declare const build: () => { [K in keyof M]?: Resolve }; + export const optionalCycle = build<{ Node: { value: number; next: "ref" } }>(); + const optionalValue: number | undefined = optionalCycle.Node?.next.next.value; + export const optionalCopy = optionalCycle; + declare const buildNullable: () => { [K in keyof M]: Resolve | null }; + export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); + declare const wrap: (value: T) => { required: T; optional?: T | null }; + export const mixedCycles = wrap(optionalCycle); + export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; + export const nullableKey = Symbol(); + export const nullableKeys = buildNullable<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [nullableKey]: { value: number; next: "ref" }; + }>(); + declare const buildNullableRoot: () => Resolve | null; + export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); + declare const buildOptionalRoot: () => Resolve | undefined; + export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); + type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; + }>; + declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; + export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); + declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; + export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); + type ResolveOptional = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; + }>; + declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; + export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); + type ResolveNullish = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; + }>; + declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; + export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); + type NonNullable = "shadowed"; + type OptionalNode = (typeof optionalCycle)["Node"] & {}; + type NullableNode = (typeof nullableCycle)["Node"] & {}; + type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; + type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; + type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; + type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; + const copiedValue: number | undefined = optionalCopy.Node?.next.next.value; + const nullableValue: string | undefined = nullableCycle.Node?.next.next.value; + const mixedValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; + const sharedValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; + const quotedValue: string | undefined = nullableKeys["a-b"]?.next.next.value; + const numericValue: boolean | undefined = nullableKeys[0]?.next.next.value; + const symbolValue: number | undefined = nullableKeys[nullableKey]?.next.next.value; + const nullableRootValue: number | undefined = nullableRoot?.next.next.value; + const optionalRootValue: string | undefined = optionalRoot?.next.next.value; + const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; + const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; + const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; + const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; + const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; + const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; + const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; + const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; + const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; + const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; + const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; + const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; + const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; + const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; + const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; + const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; + const invalidNullNext: OptionalNode["next"] = null; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'null' is not assignable to type '{ value: number; next: any; }'. + const invalidUndefinedNext: OptionalNode["next"] = undefined; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type '{ value: number; next: any; }'. + const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2531: Object is possibly 'null'. + const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2533: Object is possibly 'null' or 'undefined'. + +==== mixedMappedCycle.ts (0 errors) ==== + type Show = { [K in keyof T]: T[K] } & unknown; + type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; + }>; + declare const build: () => { [K in keyof M]: Resolve | false | null }; + export const mixedCycle = build<{ Node: { value: number; next: "ref" } }>(); + if (mixedCycle.Node) { + const value: number = mixedCycle.Node.next.next.value; + } + +==== anonymousThisReturn.ts (0 errors) ==== + export function test() { + return { + relyingOnThis() { + return this; + }, + }; + } + test().relyingOnThis(); + +==== recursiveConditionalAliasUtils.ts (0 errors) ==== + type Recursive = T extends Array ? Recursive : T; + export const f = (): Recursive => { + return null!; + }; + +==== recursiveConditionalAliasCopy.ts (0 errors) ==== + import { f } from "./recursiveConditionalAliasUtils"; + export const a = f; + const numberValue: number = a(); + const stringValue: string = a(); + +==== anonymousBindings.ts (2 errors) ==== + export const _recursive = 1; + export const factory = () => function self() { return self; }; + export function captured(value: T) { + const node = { value, next: () => node, consume: (other: T) => node }; + return node; + } + export function nestedCaptured(outer: T) { + return (inner: U) => { + const node = { + outer, + inner, + next: () => node, + shadow: (value: T) => ({ outer, inner, value, next: node }), + }; + return node; + }; + } + export function constrained(key: K) { + const node = { value: null! as T[K], next: () => node }; + return node; + } + export function optionalCaptured(value: T) { + type Node = { value: T; next: Node }; + return null! as { node?: Node | false | null }; + } + export function annotatedCaptured(value: T) { + const node: { value: typeof value; next: typeof node } = { value, next: null! }; + return node; + } + export function recursiveTuple(value: T) { + type Tuple = readonly [T, Tuple]; + return null! as Tuple; + } + export function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); + } + export function mappedCaptured() { + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; + return null! as Node; + } + export function freshGeneric(unused: T) { + const recur = (value: U) => recur; + return recur; + } + export function mutualCaptured(left: T, right: U) { + type Left = { left: T; next: Right }; + type Right = { right: U; self: Right; next: Left }; + return { left: null! as Left, right: null! as Right }; + } + export class CapturedClass { + constructor(public value: T) {} + make(inner: U) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } + } + export function covariantClass() { + return class Node { + value!: T; + next(): Node { return this; } + }; + } + export function contravariantClass() { + return class Node { + consume!: (value: T) => void; + next(): Node { return this; } + }; + } + export namespace Nested { + export function captured(value: T) { + const node = { value, next: () => node }; + return node; + } + } + const capturedValue: string = captured("text").next().consume("other").value; + const nestedValue = nestedCaptured(1)("text").shadow(true).next.next(); + const nestedOuter: number = nestedValue.outer; + const nestedInner: string = nestedValue.inner; + const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; + const annotatedValue: string = annotatedCaptured("text").next.next.value; + const tupleValue: string = recursiveTuple("text")[1][1][0]; + const namespaceValue: number = Nested.captured(1).next().next().value; + const inferredValue: string = inferredCaptured<() => string>().next.next.value; + const mappedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; + const freshValue = freshGeneric(1)("text")(true)(2); + const mutualValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; + const classValue: string = new CapturedClass("text").make("other").next().outer; + const optional = optionalCaptured("text"); + if (optional.node) { + const value: string = optional.node.next.next.value; + } + captured("text").consume(1); + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + const invalidTupleValue: number = recursiveTuple("text")[1][0]; + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + +==== shadowedMappedCycle.ts (0 errors) ==== + type Show = { [K in keyof T]: T[K] } & unknown; + type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => Resolve : M[K][P]; + }>; + declare const build: () => { [K in keyof M]: Resolve }; + export const shadowedCycle = build<{ Node: { value: number; next: "ref" } }>(); + const shadowedValue: number = shadowedCycle.Node.next(1).next("text").value; + +==== globalRecursiveA.ts (0 errors) ==== + function makeA() { + return { + value: 1, + self() { return this; }, + }; + } + type makeReserved_recursive = "reserved"; + function makeReserved() { + return { + value: true, + self() { return this; }, + }; + } + class GlobalA { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } + } + +==== globalRecursiveB.ts (0 errors) ==== + function makeB() { + return { + value: "text", + self() { return this; }, + }; + } + class GlobalB { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + } \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.js b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.js index df714bfc4e219..8e3a82b63fdc1 100644 --- a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.js +++ b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.js @@ -243,6 +243,302 @@ export declare const inferred: Inferred<(value: number) => { next: typeof reused export const inferredCopy = inferred; const inferredValue: string = inferredCopy.next(1).second("text").value; +//// [mappedCycles.ts] +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; +export const cycleKey = Symbol(); +export const keyedCycles = build<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; +}>(); +export const sharedCycles = { + first: mappedCycle, + second: mappedCycle, +}; +export const broadCycle: { Node: unknown } = mappedCycle; + +type ResolveMutual = Show<{ + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; +}>; +declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; +export const mutualCycle = buildMutual<{ + First: { value: number; next: { ref: "Second" } }; + Second: { value: string; next: { ref: "First" } }; +}>(); + +const mappedValue: number = mappedCycle.Node.next.next.value; +const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; +const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; +const numericMappedValue: boolean = keyedCycles[0].next.next.value; +const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; +const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; +const mutualFirstValue: number = mutualCycle.First.next.next.value; +const mutualSecondValue: string = mutualCycle.First.next.value; +const invalidMappedValue: string = mappedCycle.Node.next.next.value; +const invalidMutualValue: number = mutualCycle.First.next.value; + +//// [optionalMappedCycle.ts] +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]?: Resolve }; +export const optionalCycle = build<{ Node: { value: number; next: "ref" } }>(); +const optionalValue: number | undefined = optionalCycle.Node?.next.next.value; +export const optionalCopy = optionalCycle; +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); +declare const wrap: (value: T) => { required: T; optional?: T | null }; +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKey = Symbol(); +export const nullableKeys = buildNullable<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [nullableKey]: { value: number; next: "ref" }; +}>(); +declare const buildNullableRoot: () => Resolve | null; +export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalRoot: () => Resolve | undefined; +export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); +type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; +export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveOptional = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; +}>; +declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; +export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveNullish = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; +}>; +declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; +export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); +type NonNullable = "shadowed"; +type OptionalNode = (typeof optionalCycle)["Node"] & {}; +type NullableNode = (typeof nullableCycle)["Node"] & {}; +type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; +type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; +type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; +type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; +const copiedValue: number | undefined = optionalCopy.Node?.next.next.value; +const nullableValue: string | undefined = nullableCycle.Node?.next.next.value; +const mixedValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; +const sharedValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; +const quotedValue: string | undefined = nullableKeys["a-b"]?.next.next.value; +const numericValue: boolean | undefined = nullableKeys[0]?.next.next.value; +const symbolValue: number | undefined = nullableKeys[nullableKey]?.next.next.value; +const nullableRootValue: number | undefined = nullableRoot?.next.next.value; +const optionalRootValue: string | undefined = optionalRoot?.next.next.value; +const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; +const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; +const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; +const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; +const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; +const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; +const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; +const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; +const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; +const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; +const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; +const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; +const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; +const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; +const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; +const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; +const invalidNullNext: OptionalNode["next"] = null; +const invalidUndefinedNext: OptionalNode["next"] = undefined; +const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; + +//// [mixedMappedCycle.ts] +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve | false | null }; +export const mixedCycle = build<{ Node: { value: number; next: "ref" } }>(); +if (mixedCycle.Node) { + const value: number = mixedCycle.Node.next.next.value; +} + +//// [anonymousThisReturn.ts] +export function test() { + return { + relyingOnThis() { + return this; + }, + }; +} +test().relyingOnThis(); + +//// [recursiveConditionalAliasUtils.ts] +type Recursive = T extends Array ? Recursive : T; +export const f = (): Recursive => { + return null!; +}; + +//// [recursiveConditionalAliasCopy.ts] +import { f } from "./recursiveConditionalAliasUtils"; +export const a = f; +const numberValue: number = a(); +const stringValue: string = a(); + +//// [anonymousBindings.ts] +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value: T) { + const node = { value, next: () => node, consume: (other: T) => node }; + return node; +} +export function nestedCaptured(outer: T) { + return (inner: U) => { + const node = { + outer, + inner, + next: () => node, + shadow: (value: T) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key: K) { + const node = { value: null! as T[K], next: () => node }; + return node; +} +export function optionalCaptured(value: T) { + type Node = { value: T; next: Node }; + return null! as { node?: Node | false | null }; +} +export function annotatedCaptured(value: T) { + const node: { value: typeof value; next: typeof node } = { value, next: null! }; + return node; +} +export function recursiveTuple(value: T) { + type Tuple = readonly [T, Tuple]; + return null! as Tuple; +} +export function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); +} +export function mappedCaptured() { + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; + return null! as Node; +} +export function freshGeneric(unused: T) { + const recur = (value: U) => recur; + return recur; +} +export function mutualCaptured(left: T, right: U) { + type Left = { left: T; next: Right }; + type Right = { right: U; self: Right; next: Left }; + return { left: null! as Left, right: null! as Right }; +} +export class CapturedClass { + constructor(public value: T) {} + make(inner: U) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value!: T; + next(): Node { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume!: (value: T) => void; + next(): Node { return this; } + }; +} +export namespace Nested { + export function captured(value: T) { + const node = { value, next: () => node }; + return node; + } +} +const capturedValue: string = captured("text").next().consume("other").value; +const nestedValue = nestedCaptured(1)("text").shadow(true).next.next(); +const nestedOuter: number = nestedValue.outer; +const nestedInner: string = nestedValue.inner; +const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; +const annotatedValue: string = annotatedCaptured("text").next.next.value; +const tupleValue: string = recursiveTuple("text")[1][1][0]; +const namespaceValue: number = Nested.captured(1).next().next().value; +const inferredValue: string = inferredCaptured<() => string>().next.next.value; +const mappedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; +const freshValue = freshGeneric(1)("text")(true)(2); +const mutualValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; +const classValue: string = new CapturedClass("text").make("other").next().outer; +const optional = optionalCaptured("text"); +if (optional.node) { + const value: string = optional.node.next.next.value; +} +captured("text").consume(1); +const invalidTupleValue: number = recursiveTuple("text")[1][0]; + +//// [shadowedMappedCycle.ts] +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +export const shadowedCycle = build<{ Node: { value: number; next: "ref" } }>(); +const shadowedValue: number = shadowedCycle.Node.next(1).next("text").value; + +//// [globalRecursiveA.ts] +function makeA() { + return { + value: 1, + self() { return this; }, + }; +} +type makeReserved_recursive = "reserved"; +function makeReserved() { + return { + value: true, + self() { return this; }, + }; +} +class GlobalA { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} + +//// [globalRecursiveB.ts] +function makeB() { + return { + value: "text", + self() { return this; }, + }; +} +class GlobalB { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } +} + //// [script.js] "use strict"; @@ -446,6 +742,230 @@ const restValue = copy.first(1).next.second(2).value; const shadowedValue = copy.shadowed(1).next; export const inferredCopy = inferred; const inferredValue = inferredCopy.next(1).second("text").value; +//// [mappedCycles.js] +export const mappedCycle = build(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build() }; +export const cycleKey = Symbol(); +export const keyedCycles = build(); +export const sharedCycles = { + first: mappedCycle, + second: mappedCycle, +}; +export const broadCycle = mappedCycle; +export const mutualCycle = buildMutual(); +const mappedValue = mappedCycle.Node.next.next.value; +const nestedMappedValue = nestedCycle.wrapped.Node.next.next.value; +const quotedMappedValue = keyedCycles["a-b"].next.next.value; +const numericMappedValue = keyedCycles[0].next.next.value; +const symbolMappedValue = keyedCycles[cycleKey].next.next.value; +const sharedMappedValue = sharedCycles.second.Node.next.next.value; +const mutualFirstValue = mutualCycle.First.next.next.value; +const mutualSecondValue = mutualCycle.First.next.value; +const invalidMappedValue = mappedCycle.Node.next.next.value; +const invalidMutualValue = mutualCycle.First.next.value; +//// [optionalMappedCycle.js] +export const optionalCycle = build(); +const optionalValue = optionalCycle.Node?.next.next.value; +export const optionalCopy = optionalCycle; +export const nullableCycle = buildNullable(); +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKey = Symbol(); +export const nullableKeys = buildNullable(); +export const nullableRoot = buildNullableRoot(); +export const optionalRoot = buildOptionalRoot(); +export const nullableLinks = buildNullableLinks(); +export const optionalNullableLinks = buildOptionalNullableLinks(); +export const nullableOptionalLinks = buildNullableOptionalLinks(); +export const nullishLinks = buildNullishLinks(); +const copiedValue = optionalCopy.Node?.next.next.value; +const nullableValue = nullableCycle.Node?.next.next.value; +const mixedValue = mixedCycles.optional?.Node?.next.next.value; +const sharedValue = sharedOptionalCycles.second.Node?.next.next.value; +const quotedValue = nullableKeys["a-b"]?.next.next.value; +const numericValue = nullableKeys[0]?.next.next.value; +const symbolValue = nullableKeys[nullableKey]?.next.next.value; +const nullableRootValue = nullableRoot?.next.next.value; +const optionalRootValue = optionalRoot?.next.next.value; +const nullableLinkValue = nullableLinks.Node?.next?.next?.value; +const nullishLinkValue = nullishLinks.Node?.next?.next?.value; +const optionalNullableLinkValue = optionalNullableLinks.Node?.next?.next?.value; +const nullableOptionalLinkValue = nullableOptionalLinks.Node?.next?.next?.value; +const optionalNextHasNull = false; +const optionalNextHasUndefined = false; +const nullableNextHasNull = false; +const nullableNextHasUndefined = false; +const nullableLinkHasNull = true; +const nullableLinkHasUndefined = false; +const nullishLinkHasNull = true; +const nullishLinkHasUndefined = true; +const optionalNullableLinkHasNull = true; +const optionalNullableLinkHasUndefined = false; +const nullableOptionalLinkHasNull = false; +const nullableOptionalLinkHasUndefined = true; +const invalidNullNext = null; +const invalidUndefinedNext = undefined; +const invalidNullableLinkValue = nullableLinks.Node.next.value; +const invalidNullishLinkValue = nullishLinks.Node.next.value; +//// [mixedMappedCycle.js] +export const mixedCycle = build(); +if (mixedCycle.Node) { + const value = mixedCycle.Node.next.next.value; +} +//// [anonymousThisReturn.js] +export function test() { + return { + relyingOnThis() { + return this; + }, + }; +} +test().relyingOnThis(); +//// [recursiveConditionalAliasUtils.js] +export const f = () => { + return null; +}; +//// [recursiveConditionalAliasCopy.js] +import { f } from "./recursiveConditionalAliasUtils"; +export const a = f; +const numberValue = a(); +const stringValue = a(); +//// [anonymousBindings.js] +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value) { + const node = { value, next: () => node, consume: (other) => node }; + return node; +} +export function nestedCaptured(outer) { + return (inner) => { + const node = { + outer, + inner, + next: () => node, + shadow: (value) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key) { + const node = { value: null, next: () => node }; + return node; +} +export function optionalCaptured(value) { + return null; +} +export function annotatedCaptured(value) { + const node = { value, next: null }; + return node; +} +export function recursiveTuple(value) { + return null; +} +export function inferredCaptured() { + return null; +} +export function mappedCaptured() { + return null; +} +export function freshGeneric(unused) { + const recur = (value) => recur; + return recur; +} +export function mutualCaptured(left, right) { + return { left: null, right: null }; +} +export class CapturedClass { + value; + constructor(value) { + this.value = value; + } + make(inner) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value; + next() { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume; + next() { return this; } + }; +} +export var Nested; +(function (Nested) { + function captured(value) { + const node = { value, next: () => node }; + return node; + } + Nested.captured = captured; +})(Nested || (Nested = {})); +const capturedValue = captured("text").next().consume("other").value; +const nestedValue = nestedCaptured(1)("text").shadow(true).next.next(); +const nestedOuter = nestedValue.outer; +const nestedInner = nestedValue.inner; +const constrainedValue = constrained("value").next().value; +const annotatedValue = annotatedCaptured("text").next.next.value; +const tupleValue = recursiveTuple("text")[1][1][0]; +const namespaceValue = Nested.captured(1).next().next().value; +const inferredValue = inferredCaptured().next.next.value; +const mappedValue = mappedCaptured().value.next.value.value; +const freshValue = freshGeneric(1)("text")(true)(2); +const mutualValue = mutualCaptured(1, "text").left.next.self.next.next.right; +const classValue = new CapturedClass("text").make("other").next().outer; +const optional = optionalCaptured("text"); +if (optional.node) { + const value = optional.node.next.next.value; +} +captured("text").consume(1); +const invalidTupleValue = recursiveTuple("text")[1][0]; +//// [shadowedMappedCycle.js] +export const shadowedCycle = build(); +const shadowedValue = shadowedCycle.Node.next(1).next("text").value; +//// [globalRecursiveA.js] +"use strict"; +function makeA() { + return { + value: 1, + self() { return this; }, + }; +} +function makeReserved() { + return { + value: true, + self() { return this; }, + }; +} +class GlobalA { + static create(value) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} +//// [globalRecursiveB.js] +"use strict"; +function makeB() { + return { + value: "text", + self() { return this; }, + }; +} +class GlobalB { + static create(value) { + const node = { value, next: () => node }; + return node; + } +} //// [script.d.ts] @@ -493,6 +1013,33 @@ export declare const tupleReturn: () => readonly [typeof tupleReturn]; export declare const shadowed: (shadowed: number) => typeof import("./exported").shadowed; //// [consumer.d.ts] export {}; +//// [recursiveObject.d.ts] +type recursiveObject_recursive = { + call: (arg: U) => recursiveObject_recursive; + consume: (arg: T) => recursiveObject_recursive; +}; +export declare function recursiveObject(): recursiveObject_recursive; +export {}; +//// [nestedNamedFunctions.d.ts] +type factory_recursive = () => factory_recursive; +type local_recursive = () => local_recursive; +export declare const nestedObject: { + recur: () => () => (typeof nestedObject)["recur"]; +}; +export declare const nestedTuple: readonly [() => () => (typeof nestedTuple)[0]]; +export declare const object: { + recur: () => () => (typeof object)["recur"]; +}; +export declare const tuple: readonly [() => () => (typeof tuple)[0]]; +export declare const factory: () => () => factory_recursive; +export declare const method: { + recur(): typeof method; +}; +export declare const accessor: { + readonly recur: typeof accessor; +}; +export declare function local(): local_recursive; +export {}; //// [recursiveStructures.d.ts] export declare const object: { value: number; @@ -529,15 +1076,15 @@ export declare const nested: { }; }; export declare const shadowed: { - next: (shadowed: number) => typeof import("./recursiveStructures").shadowed["next"]; + next: (shadowed: number) => (shadowed: number) => typeof import("./recursiveStructures").shadowed["next"]; }; -export declare const memberTuple: readonly [() => (typeof memberTuple)[0]]; +export declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]]; export declare const memberArray: (() => (typeof memberArray)[0])[]; export declare const quoted: { - "a-b": () => (typeof quoted)["a-b"]; + "a-b": () => () => (typeof quoted)["a-b"]; }; export declare const numeric: { - 0: () => (typeof numeric)[0]; + 0: () => () => (typeof numeric)[0]; }; export declare const key: unique symbol; export declare const computed: { @@ -621,6 +1168,17 @@ export declare class Methods { } export declare function overloaded(value: string): typeof overloaded; export declare function overloaded(value: number): typeof overloaded; +//// [hiddenReferences.d.ts] +type Hidden_expose_recursive = () => Hidden_expose_recursive; +type Hidden_next_recursive = () => Hidden_next_recursive; +type Hidden_expose_recursive_1 = () => Hidden_expose_recursive_1; +export declare class Hidden { + private static recur; + static expose(): Hidden_expose_recursive; + protected next(): Hidden_next_recursive; + expose(): Hidden_expose_recursive_1; +} +export {}; //// [signatureScopes.d.ts] export declare const scoped: { first(outer: T): { @@ -855,12 +1413,12 @@ export declare const nestedString: { nested(inner: U): { outer: T; inner: U; - owner: typeof nestedOwner; + owner: (typeof nestedString)["owner"]; }; constrained(inner: U): { outer: T; inner: U; - owner: typeof nestedOwner; + owner: (typeof nestedString)["owner"]; }; copied(inner: U): { outer: T; @@ -870,7 +1428,7 @@ export declare const nestedString: { rest(values_0: U): { outer: T; inner: U; - owner: typeof nestedOwner; + owner: (typeof nestedString)["owner"]; }; }; }; @@ -883,12 +1441,12 @@ export declare const nestedBoolean: { nested(inner: U): { outer: T; inner: U; - owner: typeof nestedOwner; + owner: (typeof nestedBoolean)["owner"]; }; constrained(inner: U): { outer: T; inner: U; - owner: typeof nestedOwner; + owner: (typeof nestedBoolean)["owner"]; }; copied(inner: U): { outer: T; @@ -898,7 +1456,7 @@ export declare const nestedBoolean: { rest(values_0: U): { outer: T; inner: U; - owner: typeof nestedOwner; + owner: (typeof nestedBoolean)["owner"]; }; }; }; @@ -953,3 +1511,353 @@ export declare const inferredCopy: { }; }; }; +//// [mappedCycles.d.ts] +export declare const mappedCycle: { + Node: { + value: number; + next: (typeof mappedCycle)["Node"]; + }; +}; +export declare const mappedCycleCopy: { + Node: { + value: number; + next: (typeof mappedCycleCopy)["Node"]; + }; +}; +export declare const nestedCycle: { + wrapped: { + Node: { + value: string; + next: (typeof nestedCycle)["wrapped"]["Node"]; + }; + }; +}; +export declare const cycleKey: unique symbol; +export declare const keyedCycles: { + "a-b": { + value: string; + next: (typeof keyedCycles)["a-b"]; + }; + 0: { + value: boolean; + next: (typeof keyedCycles)[0]; + }; + [cycleKey]: { + value: number; + next: (typeof keyedCycles)[typeof cycleKey]; + }; +}; +export declare const sharedCycles: { + first: { + Node: { + value: number; + next: (typeof sharedCycles)["first"]["Node"]; + }; + }; + second: { + Node: { + value: number; + next: (typeof sharedCycles)["second"]["Node"]; + }; + }; +}; +export declare const broadCycle: { + Node: unknown; +}; +export declare const mutualCycle: { + First: { + value: number; + next: { + value: string; + next: (typeof mutualCycle)["First"]; + }; + }; + Second: { + value: string; + next: { + value: number; + next: (typeof mutualCycle)["Second"]; + }; + }; +}; +//// [optionalMappedCycle.d.ts] +type optionalCycle_recursive = { + value: number; + next: optionalCycle_recursive; +}; +type optionalCopy_recursive = { + value: number; + next: optionalCopy_recursive; +}; +type nullableCycle_recursive = { + value: string; + next: nullableCycle_recursive; +}; +type mixedCycles_recursive = { + value: number; + next: mixedCycles_recursive; +}; +type sharedOptionalCycles_recursive = { + value: number; + next: sharedOptionalCycles_recursive; +}; +type nullableKeys_recursive = { + value: string; + next: nullableKeys_recursive; +}; +type nullableKeys_recursive_1 = { + value: boolean; + next: nullableKeys_recursive_1; +}; +type nullableKeys_recursive_2 = { + value: number; + next: nullableKeys_recursive_2; +}; +type nullableRoot_recursive = { + value: number; + next: nullableRoot_recursive; +}; +type optionalRoot_recursive = { + value: string; + next: optionalRoot_recursive; +}; +type optionalNullableLinks_recursive = { + value: number; + next: optionalNullableLinks_recursive | null; +}; +type nullableOptionalLinks_recursive = { + value: number; + next: nullableOptionalLinks_recursive | undefined; +}; +export declare const optionalCycle: { + Node?: optionalCycle_recursive | undefined; +}; +export declare const optionalCopy: { + Node?: optionalCopy_recursive | undefined; +}; +export declare const nullableCycle: { + Node: nullableCycle_recursive | null; +}; +export declare const mixedCycles: { + required: { + Node?: mixedCycles_recursive | undefined; + }; + optional?: { + Node?: mixedCycles_recursive | undefined; + } | null | undefined; +}; +export declare const sharedOptionalCycles: { + first: { + Node?: sharedOptionalCycles_recursive | undefined; + }; + second: { + Node?: sharedOptionalCycles_recursive | undefined; + }; +}; +export declare const nullableKey: unique symbol; +export declare const nullableKeys: { + "a-b": nullableKeys_recursive | null; + 0: nullableKeys_recursive_1 | null; + [nullableKey]: nullableKeys_recursive_2 | null; +}; +export declare const nullableRoot: nullableRoot_recursive | null; +export declare const optionalRoot: optionalRoot_recursive | undefined; +export declare const nullableLinks: { + Node: { + value: number; + next: (typeof nullableLinks)["Node"]; + } | null; +}; +export declare const optionalNullableLinks: { + Node?: optionalNullableLinks_recursive | null | undefined; +}; +export declare const nullableOptionalLinks: { + Node: nullableOptionalLinks_recursive | null; +}; +export declare const nullishLinks: { + Node?: { + value: number; + next: (typeof nullishLinks)["Node"]; + } | null | undefined; +}; +export {}; +//// [mixedMappedCycle.d.ts] +type mixedCycle_recursive = { + value: number; + next: mixedCycle_recursive; +}; +export declare const mixedCycle: { + Node: false | mixedCycle_recursive | null; +}; +export {}; +//// [anonymousThisReturn.d.ts] +type test_recursive = { + relyingOnThis(): test_recursive; +}; +export declare function test(): { + relyingOnThis(): test_recursive; +}; +export {}; +//// [recursiveConditionalAliasUtils.d.ts] +type Recursive = T extends Array ? Recursive : T; +export declare const f: () => Recursive; +export {}; +//// [recursiveConditionalAliasCopy.d.ts] +import { f } from "./recursiveConditionalAliasUtils"; +export declare const a: typeof f; +//// [anonymousBindings.d.ts] +type factory_recursive = () => factory_recursive; +type captured_recursive = { + value: T; + next: () => captured_recursive; + consume: (other: T) => captured_recursive; +}; +type nestedCaptured_recursive = { + outer: T; + inner: U; + next: () => nestedCaptured_recursive; + shadow: (value: T_1) => { + outer: T; + inner: U; + value: T_1; + next: nestedCaptured_recursive; + }; +}; +type constrained_recursive = { + value: T[K]; + next: () => constrained_recursive; +}; +type optionalCaptured_recursive = { + value: T; + next: optionalCaptured_recursive; +}; +type annotatedCaptured_recursive = { + value: T; + next: annotatedCaptured_recursive; +}; +type recursiveTuple_recursive = readonly [T, recursiveTuple_recursive]; +type inferredCaptured_recursive = { + value: U; + next: inferredCaptured_recursive; +}; +type mappedCaptured_recursive = { [K in keyof T]: { + value: T[K]; + next: mappedCaptured_recursive; +}; }; +type freshGeneric_recursive = (value: U) => freshGeneric_recursive; +type mutualCaptured_recursive = { + right: U; + self: mutualCaptured_recursive; + next: mutualCaptured_recursive_1; +}; +type mutualCaptured_recursive_1 = { + left: T; + next: mutualCaptured_recursive; +}; +type CapturedClass_make_recursive = { + outer: T; + inner: U; + next: () => CapturedClass_make_recursive; +}; +type covariantClass_recursive = { + value: T; + next(): covariantClass_recursive; +}; +type contravariantClass_recursive = { + consume: (value: T) => void; + next(): contravariantClass_recursive; +}; +export declare const _recursive = 1; +export declare const factory: () => () => factory_recursive; +export declare function captured(value: T): captured_recursive; +export declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive; +export declare function constrained(key: K): constrained_recursive; +export declare function optionalCaptured(value: T): { + node?: optionalCaptured_recursive | false | null; +}; +export declare function annotatedCaptured(value: T): annotatedCaptured_recursive; +export declare function recursiveTuple(value: T): recursiveTuple_recursive; +export declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never); +export declare function mappedCaptured(): mappedCaptured_recursive; +export declare function freshGeneric(unused: T): freshGeneric_recursive; +export declare function mutualCaptured(left: T, right: U): { + left: mutualCaptured_recursive_1; + right: mutualCaptured_recursive; +}; +export declare class CapturedClass { + value: T; + constructor(value: T); + make(inner: U): CapturedClass_make_recursive; +} +export declare function covariantClass(): { + new (): covariantClass_recursive; +}; +export declare function contravariantClass(): { + new (): contravariantClass_recursive; +}; +export declare namespace Nested { + type captured_recursive_1 = { + value: T; + next: () => captured_recursive_1; + }; + export function captured(value: T): captured_recursive_1; + export {}; +} +export {}; +//// [shadowedMappedCycle.d.ts] +export declare const shadowedCycle: { + Node: { + value: number; + next: (shadowedCycle: T) => typeof import("./shadowedMappedCycle").shadowedCycle["Node"]; + }; +}; +//// [globalRecursiveA.d.ts] +type makeA_recursive = { + value: number; + self(): makeA_recursive; +}; +type makeReserved_recursive_1 = { + value: boolean; + self(): makeReserved_recursive_1; +}; +type GlobalA_create_recursive = { + value: T; + next: () => GlobalA_create_recursive; +}; +type GlobalA_a_b_recursive = { + value: boolean; + next: () => GlobalA_a_b_recursive; +}; +declare function makeA(): { + value: number; + self(): makeA_recursive; +}; +type makeReserved_recursive = "reserved"; +declare function makeReserved(): { + value: boolean; + self(): makeReserved_recursive_1; +}; +declare class GlobalA { + static create(value: T): GlobalA_create_recursive; + static "a-b"(): GlobalA_a_b_recursive; +} +//// [globalRecursiveB.d.ts] +type makeB_recursive = { + value: string; + self(): makeB_recursive; +}; +type GlobalB_create_recursive = { + value: T; + next: () => GlobalB_create_recursive; +}; +declare function makeB(): { + value: string; + self(): makeB_recursive; +}; +declare class GlobalB { + static create(value: T): GlobalB_create_recursive; +} diff --git a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.symbols b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.symbols index 21c1a7c50fbca..ff752decf0c02 100644 --- a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.symbols +++ b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.symbols @@ -1187,3 +1187,1556 @@ const inferredValue: string = inferredCopy.next(1).second("text").value; >second : Symbol(second, Decl(signatureScopes.ts, 47, 64)) >value : Symbol(value, Decl(signatureScopes.ts, 48, 26)) +=== mappedCycles.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : Symbol(Show, Decl(mappedCycles.ts, 0, 0)) +>T : Symbol(T, Decl(mappedCycles.ts, 0, 10)) +>K : Symbol(K, Decl(mappedCycles.ts, 0, 18)) +>T : Symbol(T, Decl(mappedCycles.ts, 0, 10)) +>T : Symbol(T, Decl(mappedCycles.ts, 0, 10)) +>K : Symbol(K, Decl(mappedCycles.ts, 0, 18)) + +type Resolve = Show<{ +>Resolve : Symbol(Resolve, Decl(mappedCycles.ts, 0, 50)) +>M : Symbol(M, Decl(mappedCycles.ts, 1, 13)) +>K : Symbol(K, Decl(mappedCycles.ts, 1, 15)) +>M : Symbol(M, Decl(mappedCycles.ts, 1, 13)) +>Show : Symbol(Show, Decl(mappedCycles.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +>P : Symbol(P, Decl(mappedCycles.ts, 2, 5)) +>M : Symbol(M, Decl(mappedCycles.ts, 1, 13)) +>K : Symbol(K, Decl(mappedCycles.ts, 1, 15)) +>M : Symbol(M, Decl(mappedCycles.ts, 1, 13)) +>K : Symbol(K, Decl(mappedCycles.ts, 1, 15)) +>P : Symbol(P, Decl(mappedCycles.ts, 2, 5)) +>Resolve : Symbol(Resolve, Decl(mappedCycles.ts, 0, 50)) +>M : Symbol(M, Decl(mappedCycles.ts, 1, 13)) +>K : Symbol(K, Decl(mappedCycles.ts, 1, 15)) +>M : Symbol(M, Decl(mappedCycles.ts, 1, 13)) +>K : Symbol(K, Decl(mappedCycles.ts, 1, 15)) +>P : Symbol(P, Decl(mappedCycles.ts, 2, 5)) + +}>; +declare const build: () => { [K in keyof M]: Resolve }; +>build : Symbol(build, Decl(mappedCycles.ts, 4, 13)) +>M : Symbol(M, Decl(mappedCycles.ts, 4, 22)) +>K : Symbol(K, Decl(mappedCycles.ts, 4, 33)) +>M : Symbol(M, Decl(mappedCycles.ts, 4, 22)) +>Resolve : Symbol(Resolve, Decl(mappedCycles.ts, 0, 50)) +>M : Symbol(M, Decl(mappedCycles.ts, 4, 22)) +>K : Symbol(K, Decl(mappedCycles.ts, 4, 33)) + +export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) +>build : Symbol(build, Decl(mappedCycles.ts, 4, 13)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) + +export const mappedCycleCopy = mappedCycle; +>mappedCycleCopy : Symbol(mappedCycleCopy, Decl(mappedCycles.ts, 6, 12)) +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) + +export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; +>nestedCycle : Symbol(nestedCycle, Decl(mappedCycles.ts, 7, 12)) +>wrapped : Symbol(wrapped, Decl(mappedCycles.ts, 7, 28)) +>build : Symbol(build, Decl(mappedCycles.ts, 4, 13)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 7, 45)) +>value : Symbol(value, Decl(mappedCycles.ts, 7, 53)) +>next : Symbol(next, Decl(mappedCycles.ts, 7, 68)) + +export const cycleKey = Symbol(); +>cycleKey : Symbol(cycleKey, Decl(mappedCycles.ts, 8, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +export const keyedCycles = build<{ +>keyedCycles : Symbol(keyedCycles, Decl(mappedCycles.ts, 9, 12)) +>build : Symbol(build, Decl(mappedCycles.ts, 4, 13)) + + "a-b": { value: string; next: "ref" }; +>"a-b" : Symbol("a-b", Decl(mappedCycles.ts, 9, 34)) +>value : Symbol(value, Decl(mappedCycles.ts, 10, 12)) +>next : Symbol(next, Decl(mappedCycles.ts, 10, 27)) + + 0: { value: boolean; next: "ref" }; +>0 : Symbol(0, Decl(mappedCycles.ts, 10, 42)) +>value : Symbol(value, Decl(mappedCycles.ts, 11, 8)) +>next : Symbol(next, Decl(mappedCycles.ts, 11, 24)) + + [cycleKey]: { value: number; next: "ref" }; +>[cycleKey] : Symbol([cycleKey], Decl(mappedCycles.ts, 11, 39)) +>cycleKey : Symbol(cycleKey, Decl(mappedCycles.ts, 8, 12)) +>value : Symbol(value, Decl(mappedCycles.ts, 12, 17)) +>next : Symbol(next, Decl(mappedCycles.ts, 12, 32)) + +}>(); +export const sharedCycles = { +>sharedCycles : Symbol(sharedCycles, Decl(mappedCycles.ts, 14, 12)) + + first: mappedCycle, +>first : Symbol(first, Decl(mappedCycles.ts, 14, 29)) +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) + + second: mappedCycle, +>second : Symbol(second, Decl(mappedCycles.ts, 15, 23)) +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) + +}; +export const broadCycle: { Node: unknown } = mappedCycle; +>broadCycle : Symbol(broadCycle, Decl(mappedCycles.ts, 18, 12)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 18, 26)) +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) + +type ResolveMutual = Show<{ +>ResolveMutual : Symbol(ResolveMutual, Decl(mappedCycles.ts, 18, 57)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>K : Symbol(K, Decl(mappedCycles.ts, 20, 21)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>Show : Symbol(Show, Decl(mappedCycles.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; +>P : Symbol(P, Decl(mappedCycles.ts, 21, 5)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>K : Symbol(K, Decl(mappedCycles.ts, 20, 21)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>K : Symbol(K, Decl(mappedCycles.ts, 20, 21)) +>P : Symbol(P, Decl(mappedCycles.ts, 21, 5)) +>ref : Symbol(ref, Decl(mappedCycles.ts, 21, 40)) +>R : Symbol(R, Decl(mappedCycles.ts, 21, 51)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>ResolveMutual : Symbol(ResolveMutual, Decl(mappedCycles.ts, 18, 57)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>R : Symbol(R, Decl(mappedCycles.ts, 21, 51)) +>M : Symbol(M, Decl(mappedCycles.ts, 20, 19)) +>K : Symbol(K, Decl(mappedCycles.ts, 20, 21)) +>P : Symbol(P, Decl(mappedCycles.ts, 21, 5)) + +}>; +declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; +>buildMutual : Symbol(buildMutual, Decl(mappedCycles.ts, 23, 13)) +>M : Symbol(M, Decl(mappedCycles.ts, 23, 28)) +>K : Symbol(K, Decl(mappedCycles.ts, 23, 39)) +>M : Symbol(M, Decl(mappedCycles.ts, 23, 28)) +>ResolveMutual : Symbol(ResolveMutual, Decl(mappedCycles.ts, 18, 57)) +>M : Symbol(M, Decl(mappedCycles.ts, 23, 28)) +>K : Symbol(K, Decl(mappedCycles.ts, 23, 39)) + +export const mutualCycle = buildMutual<{ +>mutualCycle : Symbol(mutualCycle, Decl(mappedCycles.ts, 24, 12)) +>buildMutual : Symbol(buildMutual, Decl(mappedCycles.ts, 23, 13)) + + First: { value: number; next: { ref: "Second" } }; +>First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>value : Symbol(value, Decl(mappedCycles.ts, 25, 12)) +>next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>ref : Symbol(ref, Decl(mappedCycles.ts, 25, 35)) + + Second: { value: string; next: { ref: "First" } }; +>Second : Symbol(Second, Decl(mappedCycles.ts, 25, 54)) +>value : Symbol(value, Decl(mappedCycles.ts, 26, 13)) +>next : Symbol(next, Decl(mappedCycles.ts, 26, 28)) +>ref : Symbol(ref, Decl(mappedCycles.ts, 26, 36)) + +}>(); + +const mappedValue: number = mappedCycle.Node.next.next.value; +>mappedValue : Symbol(mappedValue, Decl(mappedCycles.ts, 29, 5)) +>mappedCycle.Node.next.next.value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) +>mappedCycle.Node.next.next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>mappedCycle.Node.next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>mappedCycle.Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) + +const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; +>nestedMappedValue : Symbol(nestedMappedValue, Decl(mappedCycles.ts, 30, 5)) +>nestedCycle.wrapped.Node.next.next.value : Symbol(value, Decl(mappedCycles.ts, 7, 53)) +>nestedCycle.wrapped.Node.next.next : Symbol(next, Decl(mappedCycles.ts, 7, 68)) +>nestedCycle.wrapped.Node.next : Symbol(next, Decl(mappedCycles.ts, 7, 68)) +>nestedCycle.wrapped.Node : Symbol(Node, Decl(mappedCycles.ts, 7, 45)) +>nestedCycle.wrapped : Symbol(wrapped, Decl(mappedCycles.ts, 7, 28)) +>nestedCycle : Symbol(nestedCycle, Decl(mappedCycles.ts, 7, 12)) +>wrapped : Symbol(wrapped, Decl(mappedCycles.ts, 7, 28)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 7, 45)) +>next : Symbol(next, Decl(mappedCycles.ts, 7, 68)) +>next : Symbol(next, Decl(mappedCycles.ts, 7, 68)) +>value : Symbol(value, Decl(mappedCycles.ts, 7, 53)) + +const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; +>quotedMappedValue : Symbol(quotedMappedValue, Decl(mappedCycles.ts, 31, 5)) +>keyedCycles["a-b"].next.next.value : Symbol(value, Decl(mappedCycles.ts, 10, 12)) +>keyedCycles["a-b"].next.next : Symbol(next, Decl(mappedCycles.ts, 10, 27)) +>keyedCycles["a-b"].next : Symbol(next, Decl(mappedCycles.ts, 10, 27)) +>keyedCycles : Symbol(keyedCycles, Decl(mappedCycles.ts, 9, 12)) +>"a-b" : Symbol("a-b", Decl(mappedCycles.ts, 9, 34)) +>next : Symbol(next, Decl(mappedCycles.ts, 10, 27)) +>next : Symbol(next, Decl(mappedCycles.ts, 10, 27)) +>value : Symbol(value, Decl(mappedCycles.ts, 10, 12)) + +const numericMappedValue: boolean = keyedCycles[0].next.next.value; +>numericMappedValue : Symbol(numericMappedValue, Decl(mappedCycles.ts, 32, 5)) +>keyedCycles[0].next.next.value : Symbol(value, Decl(mappedCycles.ts, 11, 8)) +>keyedCycles[0].next.next : Symbol(next, Decl(mappedCycles.ts, 11, 24)) +>keyedCycles[0].next : Symbol(next, Decl(mappedCycles.ts, 11, 24)) +>keyedCycles : Symbol(keyedCycles, Decl(mappedCycles.ts, 9, 12)) +>0 : Symbol(0, Decl(mappedCycles.ts, 10, 42)) +>next : Symbol(next, Decl(mappedCycles.ts, 11, 24)) +>next : Symbol(next, Decl(mappedCycles.ts, 11, 24)) +>value : Symbol(value, Decl(mappedCycles.ts, 11, 8)) + +const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; +>symbolMappedValue : Symbol(symbolMappedValue, Decl(mappedCycles.ts, 33, 5)) +>keyedCycles[cycleKey].next.next.value : Symbol(value, Decl(mappedCycles.ts, 12, 17)) +>keyedCycles[cycleKey].next.next : Symbol(next, Decl(mappedCycles.ts, 12, 32)) +>keyedCycles[cycleKey].next : Symbol(next, Decl(mappedCycles.ts, 12, 32)) +>keyedCycles : Symbol(keyedCycles, Decl(mappedCycles.ts, 9, 12)) +>cycleKey : Symbol(cycleKey, Decl(mappedCycles.ts, 8, 12)) +>next : Symbol(next, Decl(mappedCycles.ts, 12, 32)) +>next : Symbol(next, Decl(mappedCycles.ts, 12, 32)) +>value : Symbol(value, Decl(mappedCycles.ts, 12, 17)) + +const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; +>sharedMappedValue : Symbol(sharedMappedValue, Decl(mappedCycles.ts, 34, 5)) +>sharedCycles.second.Node.next.next.value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) +>sharedCycles.second.Node.next.next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>sharedCycles.second.Node.next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>sharedCycles.second.Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>sharedCycles.second : Symbol(second, Decl(mappedCycles.ts, 15, 23)) +>sharedCycles : Symbol(sharedCycles, Decl(mappedCycles.ts, 14, 12)) +>second : Symbol(second, Decl(mappedCycles.ts, 15, 23)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) + +const mutualFirstValue: number = mutualCycle.First.next.next.value; +>mutualFirstValue : Symbol(mutualFirstValue, Decl(mappedCycles.ts, 35, 5)) +>mutualCycle.First.next.next.value : Symbol(value, Decl(mappedCycles.ts, 25, 12)) +>mutualCycle.First.next.next : Symbol(next, Decl(mappedCycles.ts, 26, 28)) +>mutualCycle.First.next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>mutualCycle.First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>mutualCycle : Symbol(mutualCycle, Decl(mappedCycles.ts, 24, 12)) +>First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>next : Symbol(next, Decl(mappedCycles.ts, 26, 28)) +>value : Symbol(value, Decl(mappedCycles.ts, 25, 12)) + +const mutualSecondValue: string = mutualCycle.First.next.value; +>mutualSecondValue : Symbol(mutualSecondValue, Decl(mappedCycles.ts, 36, 5)) +>mutualCycle.First.next.value : Symbol(value, Decl(mappedCycles.ts, 26, 13)) +>mutualCycle.First.next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>mutualCycle.First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>mutualCycle : Symbol(mutualCycle, Decl(mappedCycles.ts, 24, 12)) +>First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>value : Symbol(value, Decl(mappedCycles.ts, 26, 13)) + +const invalidMappedValue: string = mappedCycle.Node.next.next.value; +>invalidMappedValue : Symbol(invalidMappedValue, Decl(mappedCycles.ts, 37, 5)) +>mappedCycle.Node.next.next.value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) +>mappedCycle.Node.next.next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>mappedCycle.Node.next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>mappedCycle.Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>mappedCycle : Symbol(mappedCycle, Decl(mappedCycles.ts, 5, 12)) +>Node : Symbol(Node, Decl(mappedCycles.ts, 5, 34)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>next : Symbol(next, Decl(mappedCycles.ts, 5, 57)) +>value : Symbol(value, Decl(mappedCycles.ts, 5, 42)) + +const invalidMutualValue: number = mutualCycle.First.next.value; +>invalidMutualValue : Symbol(invalidMutualValue, Decl(mappedCycles.ts, 38, 5)) +>mutualCycle.First.next.value : Symbol(value, Decl(mappedCycles.ts, 26, 13)) +>mutualCycle.First.next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>mutualCycle.First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>mutualCycle : Symbol(mutualCycle, Decl(mappedCycles.ts, 24, 12)) +>First : Symbol(First, Decl(mappedCycles.ts, 24, 40)) +>next : Symbol(next, Decl(mappedCycles.ts, 25, 27)) +>value : Symbol(value, Decl(mappedCycles.ts, 26, 13)) + +=== optionalMappedCycle.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : Symbol(Show, Decl(optionalMappedCycle.ts, 0, 0)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 0, 10)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 0, 18)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 0, 10)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 0, 10)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 0, 18)) + +type Resolve = Show<{ +>Resolve : Symbol(Resolve, Decl(optionalMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 1, 13)) +>Show : Symbol(Show, Decl(optionalMappedCycle.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +>P : Symbol(P, Decl(optionalMappedCycle.ts, 2, 5)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 1, 15)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 2, 5)) +>Resolve : Symbol(Resolve, Decl(optionalMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 1, 15)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 2, 5)) + +}>; +declare const build: () => { [K in keyof M]?: Resolve }; +>build : Symbol(build, Decl(optionalMappedCycle.ts, 4, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 4, 22)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 4, 33)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 4, 22)) +>Resolve : Symbol(Resolve, Decl(optionalMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 4, 22)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 4, 33)) + +export const optionalCycle = build<{ Node: { value: number; next: "ref" } }>(); +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) +>build : Symbol(build, Decl(optionalMappedCycle.ts, 4, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) + +const optionalValue: number | undefined = optionalCycle.Node?.next.next.value; +>optionalValue : Symbol(optionalValue, Decl(optionalMappedCycle.ts, 6, 5)) +>optionalCycle.Node?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) +>optionalCycle.Node?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>optionalCycle.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>optionalCycle.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) + +export const optionalCopy = optionalCycle; +>optionalCopy : Symbol(optionalCopy, Decl(optionalMappedCycle.ts, 7, 12)) +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) + +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +>buildNullable : Symbol(buildNullable, Decl(optionalMappedCycle.ts, 8, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 8, 30)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 8, 41)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 8, 30)) +>Resolve : Symbol(Resolve, Decl(optionalMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 8, 30)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 8, 41)) + +export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); +>nullableCycle : Symbol(nullableCycle, Decl(optionalMappedCycle.ts, 9, 12)) +>buildNullable : Symbol(buildNullable, Decl(optionalMappedCycle.ts, 8, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 9, 44)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 9, 52)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 9, 67)) + +declare const wrap: (value: T) => { required: T; optional?: T | null }; +>wrap : Symbol(wrap, Decl(optionalMappedCycle.ts, 10, 13)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 10, 21)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 10, 24)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 10, 21)) +>required : Symbol(required, Decl(optionalMappedCycle.ts, 10, 38)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 10, 21)) +>optional : Symbol(optional, Decl(optionalMappedCycle.ts, 10, 51)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 10, 21)) + +export const mixedCycles = wrap(optionalCycle); +>mixedCycles : Symbol(mixedCycles, Decl(optionalMappedCycle.ts, 11, 12)) +>wrap : Symbol(wrap, Decl(optionalMappedCycle.ts, 10, 13)) +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) + +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +>sharedOptionalCycles : Symbol(sharedOptionalCycles, Decl(optionalMappedCycle.ts, 12, 12)) +>first : Symbol(first, Decl(optionalMappedCycle.ts, 12, 37)) +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) +>second : Symbol(second, Decl(optionalMappedCycle.ts, 12, 59)) +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) + +export const nullableKey = Symbol(); +>nullableKey : Symbol(nullableKey, Decl(optionalMappedCycle.ts, 13, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +export const nullableKeys = buildNullable<{ +>nullableKeys : Symbol(nullableKeys, Decl(optionalMappedCycle.ts, 14, 12)) +>buildNullable : Symbol(buildNullable, Decl(optionalMappedCycle.ts, 8, 13)) + + "a-b": { value: string; next: "ref" }; +>"a-b" : Symbol("a-b", Decl(optionalMappedCycle.ts, 14, 43)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 15, 12)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 15, 27)) + + 0: { value: boolean; next: "ref" }; +>0 : Symbol(0, Decl(optionalMappedCycle.ts, 15, 42)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 16, 8)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 16, 24)) + + [nullableKey]: { value: number; next: "ref" }; +>[nullableKey] : Symbol([nullableKey], Decl(optionalMappedCycle.ts, 16, 39)) +>nullableKey : Symbol(nullableKey, Decl(optionalMappedCycle.ts, 13, 12)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 17, 20)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 17, 35)) + +}>(); +declare const buildNullableRoot: () => Resolve | null; +>buildNullableRoot : Symbol(buildNullableRoot, Decl(optionalMappedCycle.ts, 19, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 19, 34)) +>Resolve : Symbol(Resolve, Decl(optionalMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 19, 34)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 19, 34)) + +export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); +>nullableRoot : Symbol(nullableRoot, Decl(optionalMappedCycle.ts, 20, 12)) +>buildNullableRoot : Symbol(buildNullableRoot, Decl(optionalMappedCycle.ts, 19, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 20, 47)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 20, 55)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 20, 70)) + +declare const buildOptionalRoot: () => Resolve | undefined; +>buildOptionalRoot : Symbol(buildOptionalRoot, Decl(optionalMappedCycle.ts, 21, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 21, 34)) +>Resolve : Symbol(Resolve, Decl(optionalMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 21, 34)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 21, 34)) + +export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); +>optionalRoot : Symbol(optionalRoot, Decl(optionalMappedCycle.ts, 22, 12)) +>buildOptionalRoot : Symbol(buildOptionalRoot, Decl(optionalMappedCycle.ts, 21, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 22, 47)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 22, 55)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 22, 70)) + +type ResolveNullable = Show<{ +>ResolveNullable : Symbol(ResolveNullable, Decl(optionalMappedCycle.ts, 22, 90)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 23, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 23, 23)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 23, 21)) +>Show : Symbol(Show, Decl(optionalMappedCycle.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +>P : Symbol(P, Decl(optionalMappedCycle.ts, 24, 5)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 23, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 23, 23)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 23, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 23, 23)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 24, 5)) +>ResolveNullable : Symbol(ResolveNullable, Decl(optionalMappedCycle.ts, 22, 90)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 23, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 23, 23)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 23, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 23, 23)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 24, 5)) + +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +>buildNullableLinks : Symbol(buildNullableLinks, Decl(optionalMappedCycle.ts, 26, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 26, 35)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 26, 46)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 26, 35)) +>ResolveNullable : Symbol(ResolveNullable, Decl(optionalMappedCycle.ts, 22, 90)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 26, 35)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 26, 46)) + +export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); +>nullableLinks : Symbol(nullableLinks, Decl(optionalMappedCycle.ts, 27, 12)) +>buildNullableLinks : Symbol(buildNullableLinks, Decl(optionalMappedCycle.ts, 26, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 27, 49)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 27, 57)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) + +declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; +>buildOptionalNullableLinks : Symbol(buildOptionalNullableLinks, Decl(optionalMappedCycle.ts, 28, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 28, 43)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 28, 54)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 28, 43)) +>ResolveNullable : Symbol(ResolveNullable, Decl(optionalMappedCycle.ts, 22, 90)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 28, 43)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 28, 54)) + +export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); +>optionalNullableLinks : Symbol(optionalNullableLinks, Decl(optionalMappedCycle.ts, 29, 12)) +>buildOptionalNullableLinks : Symbol(buildOptionalNullableLinks, Decl(optionalMappedCycle.ts, 28, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 29, 65)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 29, 73)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 29, 88)) + +type ResolveOptional = Show<{ +>ResolveOptional : Symbol(ResolveOptional, Decl(optionalMappedCycle.ts, 29, 108)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 30, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 30, 23)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 30, 21)) +>Show : Symbol(Show, Decl(optionalMappedCycle.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; +>P : Symbol(P, Decl(optionalMappedCycle.ts, 31, 5)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 30, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 30, 23)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 30, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 30, 23)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 31, 5)) +>ResolveOptional : Symbol(ResolveOptional, Decl(optionalMappedCycle.ts, 29, 108)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 30, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 30, 23)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 30, 21)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 30, 23)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 31, 5)) + +}>; +declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; +>buildNullableOptionalLinks : Symbol(buildNullableOptionalLinks, Decl(optionalMappedCycle.ts, 33, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 33, 43)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 33, 54)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 33, 43)) +>ResolveOptional : Symbol(ResolveOptional, Decl(optionalMappedCycle.ts, 29, 108)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 33, 43)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 33, 54)) + +export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); +>nullableOptionalLinks : Symbol(nullableOptionalLinks, Decl(optionalMappedCycle.ts, 34, 12)) +>buildNullableOptionalLinks : Symbol(buildNullableOptionalLinks, Decl(optionalMappedCycle.ts, 33, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 34, 65)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 34, 73)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 34, 88)) + +type ResolveNullish = Show<{ +>ResolveNullish : Symbol(ResolveNullish, Decl(optionalMappedCycle.ts, 34, 108)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 35, 20)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 35, 22)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 35, 20)) +>Show : Symbol(Show, Decl(optionalMappedCycle.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; +>P : Symbol(P, Decl(optionalMappedCycle.ts, 36, 5)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 35, 20)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 35, 22)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 35, 20)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 35, 22)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 36, 5)) +>ResolveNullish : Symbol(ResolveNullish, Decl(optionalMappedCycle.ts, 34, 108)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 35, 20)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 35, 22)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 35, 20)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 35, 22)) +>P : Symbol(P, Decl(optionalMappedCycle.ts, 36, 5)) + +}>; +declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; +>buildNullishLinks : Symbol(buildNullishLinks, Decl(optionalMappedCycle.ts, 38, 13)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 38, 34)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 38, 45)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 38, 34)) +>ResolveNullish : Symbol(ResolveNullish, Decl(optionalMappedCycle.ts, 34, 108)) +>M : Symbol(M, Decl(optionalMappedCycle.ts, 38, 34)) +>K : Symbol(K, Decl(optionalMappedCycle.ts, 38, 45)) + +export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); +>nullishLinks : Symbol(nullishLinks, Decl(optionalMappedCycle.ts, 39, 12)) +>buildNullishLinks : Symbol(buildNullishLinks, Decl(optionalMappedCycle.ts, 38, 13)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 39, 47)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 39, 55)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) + +type NonNullable = "shadowed"; +>NonNullable : Symbol(NonNullable, Decl(optionalMappedCycle.ts, 39, 90)) +>T : Symbol(T, Decl(optionalMappedCycle.ts, 40, 17)) + +type OptionalNode = (typeof optionalCycle)["Node"] & {}; +>OptionalNode : Symbol(OptionalNode, Decl(optionalMappedCycle.ts, 40, 33)) +>optionalCycle : Symbol(optionalCycle, Decl(optionalMappedCycle.ts, 5, 12)) + +type NullableNode = (typeof nullableCycle)["Node"] & {}; +>NullableNode : Symbol(NullableNode, Decl(optionalMappedCycle.ts, 41, 56)) +>nullableCycle : Symbol(nullableCycle, Decl(optionalMappedCycle.ts, 9, 12)) + +type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; +>NullableLinkNode : Symbol(NullableLinkNode, Decl(optionalMappedCycle.ts, 42, 56)) +>nullableLinks : Symbol(nullableLinks, Decl(optionalMappedCycle.ts, 27, 12)) + +type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; +>NullishLinkNode : Symbol(NullishLinkNode, Decl(optionalMappedCycle.ts, 43, 60)) +>nullishLinks : Symbol(nullishLinks, Decl(optionalMappedCycle.ts, 39, 12)) + +type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; +>OptionalNullableLinkNode : Symbol(OptionalNullableLinkNode, Decl(optionalMappedCycle.ts, 44, 58)) +>optionalNullableLinks : Symbol(optionalNullableLinks, Decl(optionalMappedCycle.ts, 29, 12)) + +type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; +>NullableOptionalLinkNode : Symbol(NullableOptionalLinkNode, Decl(optionalMappedCycle.ts, 45, 76)) +>nullableOptionalLinks : Symbol(nullableOptionalLinks, Decl(optionalMappedCycle.ts, 34, 12)) + +const copiedValue: number | undefined = optionalCopy.Node?.next.next.value; +>copiedValue : Symbol(copiedValue, Decl(optionalMappedCycle.ts, 47, 5)) +>optionalCopy.Node?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) +>optionalCopy.Node?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>optionalCopy.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>optionalCopy.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>optionalCopy : Symbol(optionalCopy, Decl(optionalMappedCycle.ts, 7, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) + +const nullableValue: string | undefined = nullableCycle.Node?.next.next.value; +>nullableValue : Symbol(nullableValue, Decl(optionalMappedCycle.ts, 48, 5)) +>nullableCycle.Node?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 9, 52)) +>nullableCycle.Node?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 9, 67)) +>nullableCycle.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 9, 67)) +>nullableCycle.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 9, 44)) +>nullableCycle : Symbol(nullableCycle, Decl(optionalMappedCycle.ts, 9, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 9, 44)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 9, 67)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 9, 67)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 9, 52)) + +const mixedValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; +>mixedValue : Symbol(mixedValue, Decl(optionalMappedCycle.ts, 49, 5)) +>mixedCycles.optional?.Node?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) +>mixedCycles.optional?.Node?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>mixedCycles.optional?.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>mixedCycles.optional?.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>mixedCycles.optional : Symbol(optional, Decl(optionalMappedCycle.ts, 10, 51)) +>mixedCycles : Symbol(mixedCycles, Decl(optionalMappedCycle.ts, 11, 12)) +>optional : Symbol(optional, Decl(optionalMappedCycle.ts, 10, 51)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) + +const sharedValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; +>sharedValue : Symbol(sharedValue, Decl(optionalMappedCycle.ts, 50, 5)) +>sharedOptionalCycles.second.Node?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) +>sharedOptionalCycles.second.Node?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>sharedOptionalCycles.second.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>sharedOptionalCycles.second.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>sharedOptionalCycles.second : Symbol(second, Decl(optionalMappedCycle.ts, 12, 59)) +>sharedOptionalCycles : Symbol(sharedOptionalCycles, Decl(optionalMappedCycle.ts, 12, 12)) +>second : Symbol(second, Decl(optionalMappedCycle.ts, 12, 59)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 5, 36)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 5, 59)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 5, 44)) + +const quotedValue: string | undefined = nullableKeys["a-b"]?.next.next.value; +>quotedValue : Symbol(quotedValue, Decl(optionalMappedCycle.ts, 51, 5)) +>nullableKeys["a-b"]?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 15, 12)) +>nullableKeys["a-b"]?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 15, 27)) +>nullableKeys["a-b"]?.next : Symbol(next, Decl(optionalMappedCycle.ts, 15, 27)) +>nullableKeys : Symbol(nullableKeys, Decl(optionalMappedCycle.ts, 14, 12)) +>"a-b" : Symbol("a-b", Decl(optionalMappedCycle.ts, 14, 43)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 15, 27)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 15, 27)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 15, 12)) + +const numericValue: boolean | undefined = nullableKeys[0]?.next.next.value; +>numericValue : Symbol(numericValue, Decl(optionalMappedCycle.ts, 52, 5)) +>nullableKeys[0]?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 16, 8)) +>nullableKeys[0]?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 16, 24)) +>nullableKeys[0]?.next : Symbol(next, Decl(optionalMappedCycle.ts, 16, 24)) +>nullableKeys : Symbol(nullableKeys, Decl(optionalMappedCycle.ts, 14, 12)) +>0 : Symbol(0, Decl(optionalMappedCycle.ts, 15, 42)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 16, 24)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 16, 24)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 16, 8)) + +const symbolValue: number | undefined = nullableKeys[nullableKey]?.next.next.value; +>symbolValue : Symbol(symbolValue, Decl(optionalMappedCycle.ts, 53, 5)) +>nullableKeys[nullableKey]?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 17, 20)) +>nullableKeys[nullableKey]?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 17, 35)) +>nullableKeys[nullableKey]?.next : Symbol(next, Decl(optionalMappedCycle.ts, 17, 35)) +>nullableKeys : Symbol(nullableKeys, Decl(optionalMappedCycle.ts, 14, 12)) +>nullableKey : Symbol(nullableKey, Decl(optionalMappedCycle.ts, 13, 12)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 17, 35)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 17, 35)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 17, 20)) + +const nullableRootValue: number | undefined = nullableRoot?.next.next.value; +>nullableRootValue : Symbol(nullableRootValue, Decl(optionalMappedCycle.ts, 54, 5)) +>nullableRoot?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 20, 55)) +>nullableRoot?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 20, 70)) +>nullableRoot?.next : Symbol(next, Decl(optionalMappedCycle.ts, 20, 70)) +>nullableRoot : Symbol(nullableRoot, Decl(optionalMappedCycle.ts, 20, 12)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 20, 70)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 20, 70)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 20, 55)) + +const optionalRootValue: string | undefined = optionalRoot?.next.next.value; +>optionalRootValue : Symbol(optionalRootValue, Decl(optionalMappedCycle.ts, 55, 5)) +>optionalRoot?.next.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 22, 55)) +>optionalRoot?.next.next : Symbol(next, Decl(optionalMappedCycle.ts, 22, 70)) +>optionalRoot?.next : Symbol(next, Decl(optionalMappedCycle.ts, 22, 70)) +>optionalRoot : Symbol(optionalRoot, Decl(optionalMappedCycle.ts, 22, 12)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 22, 70)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 22, 70)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 22, 55)) + +const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; +>nullableLinkValue : Symbol(nullableLinkValue, Decl(optionalMappedCycle.ts, 56, 5)) +>nullableLinks.Node?.next?.next?.value : Symbol(value, Decl(optionalMappedCycle.ts, 27, 57)) +>nullableLinks.Node?.next?.next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) +>nullableLinks.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) +>nullableLinks.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 27, 49)) +>nullableLinks : Symbol(nullableLinks, Decl(optionalMappedCycle.ts, 27, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 27, 49)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 27, 57)) + +const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; +>nullishLinkValue : Symbol(nullishLinkValue, Decl(optionalMappedCycle.ts, 57, 5)) +>nullishLinks.Node?.next?.next?.value : Symbol(value, Decl(optionalMappedCycle.ts, 39, 55)) +>nullishLinks.Node?.next?.next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) +>nullishLinks.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) +>nullishLinks.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 39, 47)) +>nullishLinks : Symbol(nullishLinks, Decl(optionalMappedCycle.ts, 39, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 39, 47)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 39, 55)) + +const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; +>optionalNullableLinkValue : Symbol(optionalNullableLinkValue, Decl(optionalMappedCycle.ts, 58, 5)) +>optionalNullableLinks.Node?.next?.next?.value : Symbol(value, Decl(optionalMappedCycle.ts, 29, 73)) +>optionalNullableLinks.Node?.next?.next : Symbol(next, Decl(optionalMappedCycle.ts, 29, 88)) +>optionalNullableLinks.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 29, 88)) +>optionalNullableLinks.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 29, 65)) +>optionalNullableLinks : Symbol(optionalNullableLinks, Decl(optionalMappedCycle.ts, 29, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 29, 65)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 29, 88)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 29, 88)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 29, 73)) + +const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; +>nullableOptionalLinkValue : Symbol(nullableOptionalLinkValue, Decl(optionalMappedCycle.ts, 59, 5)) +>nullableOptionalLinks.Node?.next?.next?.value : Symbol(value, Decl(optionalMappedCycle.ts, 34, 73)) +>nullableOptionalLinks.Node?.next?.next : Symbol(next, Decl(optionalMappedCycle.ts, 34, 88)) +>nullableOptionalLinks.Node?.next : Symbol(next, Decl(optionalMappedCycle.ts, 34, 88)) +>nullableOptionalLinks.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 34, 65)) +>nullableOptionalLinks : Symbol(nullableOptionalLinks, Decl(optionalMappedCycle.ts, 34, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 34, 65)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 34, 88)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 34, 88)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 34, 73)) + +const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; +>optionalNextHasNull : Symbol(optionalNextHasNull, Decl(optionalMappedCycle.ts, 60, 5)) +>OptionalNode : Symbol(OptionalNode, Decl(optionalMappedCycle.ts, 40, 33)) + +const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; +>optionalNextHasUndefined : Symbol(optionalNextHasUndefined, Decl(optionalMappedCycle.ts, 61, 5)) +>OptionalNode : Symbol(OptionalNode, Decl(optionalMappedCycle.ts, 40, 33)) + +const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; +>nullableNextHasNull : Symbol(nullableNextHasNull, Decl(optionalMappedCycle.ts, 62, 5)) +>NullableNode : Symbol(NullableNode, Decl(optionalMappedCycle.ts, 41, 56)) + +const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; +>nullableNextHasUndefined : Symbol(nullableNextHasUndefined, Decl(optionalMappedCycle.ts, 63, 5)) +>NullableNode : Symbol(NullableNode, Decl(optionalMappedCycle.ts, 41, 56)) + +const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; +>nullableLinkHasNull : Symbol(nullableLinkHasNull, Decl(optionalMappedCycle.ts, 64, 5)) +>NullableLinkNode : Symbol(NullableLinkNode, Decl(optionalMappedCycle.ts, 42, 56)) + +const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; +>nullableLinkHasUndefined : Symbol(nullableLinkHasUndefined, Decl(optionalMappedCycle.ts, 65, 5)) +>NullableLinkNode : Symbol(NullableLinkNode, Decl(optionalMappedCycle.ts, 42, 56)) + +const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; +>nullishLinkHasNull : Symbol(nullishLinkHasNull, Decl(optionalMappedCycle.ts, 66, 5)) +>NullishLinkNode : Symbol(NullishLinkNode, Decl(optionalMappedCycle.ts, 43, 60)) + +const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; +>nullishLinkHasUndefined : Symbol(nullishLinkHasUndefined, Decl(optionalMappedCycle.ts, 67, 5)) +>NullishLinkNode : Symbol(NullishLinkNode, Decl(optionalMappedCycle.ts, 43, 60)) + +const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; +>optionalNullableLinkHasNull : Symbol(optionalNullableLinkHasNull, Decl(optionalMappedCycle.ts, 68, 5)) +>OptionalNullableLinkNode : Symbol(OptionalNullableLinkNode, Decl(optionalMappedCycle.ts, 44, 58)) + +const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; +>optionalNullableLinkHasUndefined : Symbol(optionalNullableLinkHasUndefined, Decl(optionalMappedCycle.ts, 69, 5)) +>OptionalNullableLinkNode : Symbol(OptionalNullableLinkNode, Decl(optionalMappedCycle.ts, 44, 58)) + +const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; +>nullableOptionalLinkHasNull : Symbol(nullableOptionalLinkHasNull, Decl(optionalMappedCycle.ts, 70, 5)) +>NullableOptionalLinkNode : Symbol(NullableOptionalLinkNode, Decl(optionalMappedCycle.ts, 45, 76)) + +const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; +>nullableOptionalLinkHasUndefined : Symbol(nullableOptionalLinkHasUndefined, Decl(optionalMappedCycle.ts, 71, 5)) +>NullableOptionalLinkNode : Symbol(NullableOptionalLinkNode, Decl(optionalMappedCycle.ts, 45, 76)) + +const invalidNullNext: OptionalNode["next"] = null; +>invalidNullNext : Symbol(invalidNullNext, Decl(optionalMappedCycle.ts, 72, 5)) +>OptionalNode : Symbol(OptionalNode, Decl(optionalMappedCycle.ts, 40, 33)) + +const invalidUndefinedNext: OptionalNode["next"] = undefined; +>invalidUndefinedNext : Symbol(invalidUndefinedNext, Decl(optionalMappedCycle.ts, 73, 5)) +>OptionalNode : Symbol(OptionalNode, Decl(optionalMappedCycle.ts, 40, 33)) +>undefined : Symbol(undefined) + +const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +>invalidNullableLinkValue : Symbol(invalidNullableLinkValue, Decl(optionalMappedCycle.ts, 74, 5)) +>nullableLinks.Node!.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 27, 57)) +>nullableLinks.Node!.next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) +>nullableLinks.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 27, 49)) +>nullableLinks : Symbol(nullableLinks, Decl(optionalMappedCycle.ts, 27, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 27, 49)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 27, 72)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 27, 57)) + +const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +>invalidNullishLinkValue : Symbol(invalidNullishLinkValue, Decl(optionalMappedCycle.ts, 75, 5)) +>nullishLinks.Node!.next.value : Symbol(value, Decl(optionalMappedCycle.ts, 39, 55)) +>nullishLinks.Node!.next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) +>nullishLinks.Node : Symbol(Node, Decl(optionalMappedCycle.ts, 39, 47)) +>nullishLinks : Symbol(nullishLinks, Decl(optionalMappedCycle.ts, 39, 12)) +>Node : Symbol(Node, Decl(optionalMappedCycle.ts, 39, 47)) +>next : Symbol(next, Decl(optionalMappedCycle.ts, 39, 70)) +>value : Symbol(value, Decl(optionalMappedCycle.ts, 39, 55)) + +=== mixedMappedCycle.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : Symbol(Show, Decl(mixedMappedCycle.ts, 0, 0)) +>T : Symbol(T, Decl(mixedMappedCycle.ts, 0, 10)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 0, 18)) +>T : Symbol(T, Decl(mixedMappedCycle.ts, 0, 10)) +>T : Symbol(T, Decl(mixedMappedCycle.ts, 0, 10)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 0, 18)) + +type Resolve = Show<{ +>Resolve : Symbol(Resolve, Decl(mixedMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 1, 13)) +>Show : Symbol(Show, Decl(mixedMappedCycle.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +>P : Symbol(P, Decl(mixedMappedCycle.ts, 2, 5)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 1, 15)) +>P : Symbol(P, Decl(mixedMappedCycle.ts, 2, 5)) +>Resolve : Symbol(Resolve, Decl(mixedMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 1, 15)) +>P : Symbol(P, Decl(mixedMappedCycle.ts, 2, 5)) + +}>; +declare const build: () => { [K in keyof M]: Resolve | false | null }; +>build : Symbol(build, Decl(mixedMappedCycle.ts, 4, 13)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 4, 22)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 4, 33)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 4, 22)) +>Resolve : Symbol(Resolve, Decl(mixedMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(mixedMappedCycle.ts, 4, 22)) +>K : Symbol(K, Decl(mixedMappedCycle.ts, 4, 33)) + +export const mixedCycle = build<{ Node: { value: number; next: "ref" } }>(); +>mixedCycle : Symbol(mixedCycle, Decl(mixedMappedCycle.ts, 5, 12)) +>build : Symbol(build, Decl(mixedMappedCycle.ts, 4, 13)) +>Node : Symbol(Node, Decl(mixedMappedCycle.ts, 5, 33)) +>value : Symbol(value, Decl(mixedMappedCycle.ts, 5, 41)) +>next : Symbol(next, Decl(mixedMappedCycle.ts, 5, 56)) + +if (mixedCycle.Node) { +>mixedCycle.Node : Symbol(Node, Decl(mixedMappedCycle.ts, 5, 33)) +>mixedCycle : Symbol(mixedCycle, Decl(mixedMappedCycle.ts, 5, 12)) +>Node : Symbol(Node, Decl(mixedMappedCycle.ts, 5, 33)) + + const value: number = mixedCycle.Node.next.next.value; +>value : Symbol(value, Decl(mixedMappedCycle.ts, 7, 9)) +>mixedCycle.Node.next.next.value : Symbol(value, Decl(mixedMappedCycle.ts, 5, 41)) +>mixedCycle.Node.next.next : Symbol(next, Decl(mixedMappedCycle.ts, 5, 56)) +>mixedCycle.Node.next : Symbol(next, Decl(mixedMappedCycle.ts, 5, 56)) +>mixedCycle.Node : Symbol(Node, Decl(mixedMappedCycle.ts, 5, 33)) +>mixedCycle : Symbol(mixedCycle, Decl(mixedMappedCycle.ts, 5, 12)) +>Node : Symbol(Node, Decl(mixedMappedCycle.ts, 5, 33)) +>next : Symbol(next, Decl(mixedMappedCycle.ts, 5, 56)) +>next : Symbol(next, Decl(mixedMappedCycle.ts, 5, 56)) +>value : Symbol(value, Decl(mixedMappedCycle.ts, 5, 41)) +} + +=== anonymousThisReturn.ts === +export function test() { +>test : Symbol(test, Decl(anonymousThisReturn.ts, 0, 0)) + + return { + relyingOnThis() { +>relyingOnThis : Symbol(relyingOnThis, Decl(anonymousThisReturn.ts, 1, 12)) + + return this; +>this : Symbol(__object, Decl(anonymousThisReturn.ts, 1, 10)) + + }, + }; +} +test().relyingOnThis(); +>test().relyingOnThis : Symbol(relyingOnThis, Decl(anonymousThisReturn.ts, 1, 12)) +>test : Symbol(test, Decl(anonymousThisReturn.ts, 0, 0)) +>relyingOnThis : Symbol(relyingOnThis, Decl(anonymousThisReturn.ts, 1, 12)) + +=== recursiveConditionalAliasUtils.ts === +type Recursive = T extends Array ? Recursive : T; +>Recursive : Symbol(Recursive, Decl(recursiveConditionalAliasUtils.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveConditionalAliasUtils.ts, 0, 15)) +>T : Symbol(T, Decl(recursiveConditionalAliasUtils.ts, 0, 15)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 4 more) +>V : Symbol(V, Decl(recursiveConditionalAliasUtils.ts, 0, 41)) +>Recursive : Symbol(Recursive, Decl(recursiveConditionalAliasUtils.ts, 0, 0)) +>V : Symbol(V, Decl(recursiveConditionalAliasUtils.ts, 0, 41)) +>T : Symbol(T, Decl(recursiveConditionalAliasUtils.ts, 0, 15)) + +export const f = (): Recursive => { +>f : Symbol(f, Decl(recursiveConditionalAliasUtils.ts, 1, 12)) +>T : Symbol(T, Decl(recursiveConditionalAliasUtils.ts, 1, 18)) +>Recursive : Symbol(Recursive, Decl(recursiveConditionalAliasUtils.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveConditionalAliasUtils.ts, 1, 18)) + + return null!; +}; + +=== recursiveConditionalAliasCopy.ts === +import { f } from "./recursiveConditionalAliasUtils"; +>f : Symbol(f, Decl(recursiveConditionalAliasCopy.ts, 0, 8)) + +export const a = f; +>a : Symbol(a, Decl(recursiveConditionalAliasCopy.ts, 1, 12)) +>f : Symbol(f, Decl(recursiveConditionalAliasCopy.ts, 0, 8)) + +const numberValue: number = a(); +>numberValue : Symbol(numberValue, Decl(recursiveConditionalAliasCopy.ts, 2, 5)) +>a : Symbol(a, Decl(recursiveConditionalAliasCopy.ts, 1, 12)) + +const stringValue: string = a(); +>stringValue : Symbol(stringValue, Decl(recursiveConditionalAliasCopy.ts, 3, 5)) +>a : Symbol(a, Decl(recursiveConditionalAliasCopy.ts, 1, 12)) + +=== anonymousBindings.ts === +export const _recursive = 1; +>_recursive : Symbol(_recursive, Decl(anonymousBindings.ts, 0, 12)) + +export const factory = () => function self() { return self; }; +>factory : Symbol(factory, Decl(anonymousBindings.ts, 1, 12)) +>self : Symbol(self, Decl(anonymousBindings.ts, 1, 28)) +>self : Symbol(self, Decl(anonymousBindings.ts, 1, 28)) + +export function captured(value: T) { +>captured : Symbol(captured, Decl(anonymousBindings.ts, 1, 62)) +>T : Symbol(T, Decl(anonymousBindings.ts, 2, 25)) +>value : Symbol(value, Decl(anonymousBindings.ts, 2, 28)) +>T : Symbol(T, Decl(anonymousBindings.ts, 2, 25)) + + const node = { value, next: () => node, consume: (other: T) => node }; +>node : Symbol(node, Decl(anonymousBindings.ts, 3, 9)) +>value : Symbol(value, Decl(anonymousBindings.ts, 3, 18)) +>next : Symbol(next, Decl(anonymousBindings.ts, 3, 25)) +>node : Symbol(node, Decl(anonymousBindings.ts, 3, 9)) +>consume : Symbol(consume, Decl(anonymousBindings.ts, 3, 43)) +>other : Symbol(other, Decl(anonymousBindings.ts, 3, 54)) +>T : Symbol(T, Decl(anonymousBindings.ts, 2, 25)) +>node : Symbol(node, Decl(anonymousBindings.ts, 3, 9)) + + return node; +>node : Symbol(node, Decl(anonymousBindings.ts, 3, 9)) +} +export function nestedCaptured(outer: T) { +>nestedCaptured : Symbol(nestedCaptured, Decl(anonymousBindings.ts, 5, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 6, 31)) +>outer : Symbol(outer, Decl(anonymousBindings.ts, 6, 34)) +>T : Symbol(T, Decl(anonymousBindings.ts, 6, 31)) + + return (inner: U) => { +>U : Symbol(U, Decl(anonymousBindings.ts, 7, 12)) +>inner : Symbol(inner, Decl(anonymousBindings.ts, 7, 15)) +>U : Symbol(U, Decl(anonymousBindings.ts, 7, 12)) + + const node = { +>node : Symbol(node, Decl(anonymousBindings.ts, 8, 13)) + + outer, +>outer : Symbol(outer, Decl(anonymousBindings.ts, 8, 22)) + + inner, +>inner : Symbol(inner, Decl(anonymousBindings.ts, 9, 18)) + + next: () => node, +>next : Symbol(next, Decl(anonymousBindings.ts, 10, 18)) +>node : Symbol(node, Decl(anonymousBindings.ts, 8, 13)) + + shadow: (value: T) => ({ outer, inner, value, next: node }), +>shadow : Symbol(shadow, Decl(anonymousBindings.ts, 11, 29)) +>T : Symbol(T, Decl(anonymousBindings.ts, 12, 21)) +>value : Symbol(value, Decl(anonymousBindings.ts, 12, 24)) +>T : Symbol(T, Decl(anonymousBindings.ts, 12, 21)) +>outer : Symbol(outer, Decl(anonymousBindings.ts, 12, 39)) +>inner : Symbol(inner, Decl(anonymousBindings.ts, 12, 46)) +>value : Symbol(value, Decl(anonymousBindings.ts, 12, 53)) +>next : Symbol(next, Decl(anonymousBindings.ts, 12, 60)) +>node : Symbol(node, Decl(anonymousBindings.ts, 8, 13)) + + }; + return node; +>node : Symbol(node, Decl(anonymousBindings.ts, 8, 13)) + + }; +} +export function constrained(key: K) { +>constrained : Symbol(constrained, Decl(anonymousBindings.ts, 16, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 17, 28)) +>value : Symbol(value, Decl(anonymousBindings.ts, 17, 39)) +>K : Symbol(K, Decl(anonymousBindings.ts, 17, 56)) +>T : Symbol(T, Decl(anonymousBindings.ts, 17, 28)) +>key : Symbol(key, Decl(anonymousBindings.ts, 17, 76)) +>K : Symbol(K, Decl(anonymousBindings.ts, 17, 56)) + + const node = { value: null! as T[K], next: () => node }; +>node : Symbol(node, Decl(anonymousBindings.ts, 18, 9)) +>value : Symbol(value, Decl(anonymousBindings.ts, 18, 18)) +>T : Symbol(T, Decl(anonymousBindings.ts, 17, 28)) +>K : Symbol(K, Decl(anonymousBindings.ts, 17, 56)) +>next : Symbol(next, Decl(anonymousBindings.ts, 18, 40)) +>node : Symbol(node, Decl(anonymousBindings.ts, 18, 9)) + + return node; +>node : Symbol(node, Decl(anonymousBindings.ts, 18, 9)) +} +export function optionalCaptured(value: T) { +>optionalCaptured : Symbol(optionalCaptured, Decl(anonymousBindings.ts, 20, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 21, 33)) +>value : Symbol(value, Decl(anonymousBindings.ts, 21, 36)) +>T : Symbol(T, Decl(anonymousBindings.ts, 21, 33)) + + type Node = { value: T; next: Node }; +>Node : Symbol(Node, Decl(anonymousBindings.ts, 21, 47)) +>value : Symbol(value, Decl(anonymousBindings.ts, 22, 17)) +>T : Symbol(T, Decl(anonymousBindings.ts, 21, 33)) +>next : Symbol(next, Decl(anonymousBindings.ts, 22, 27)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 21, 47)) + + return null! as { node?: Node | false | null }; +>node : Symbol(node, Decl(anonymousBindings.ts, 23, 21)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 21, 47)) +} +export function annotatedCaptured(value: T) { +>annotatedCaptured : Symbol(annotatedCaptured, Decl(anonymousBindings.ts, 24, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 25, 34)) +>value : Symbol(value, Decl(anonymousBindings.ts, 25, 37)) +>T : Symbol(T, Decl(anonymousBindings.ts, 25, 34)) + + const node: { value: typeof value; next: typeof node } = { value, next: null! }; +>node : Symbol(node, Decl(anonymousBindings.ts, 26, 9)) +>value : Symbol(value, Decl(anonymousBindings.ts, 26, 17)) +>value : Symbol(value, Decl(anonymousBindings.ts, 25, 37)) +>next : Symbol(next, Decl(anonymousBindings.ts, 26, 38)) +>node : Symbol(node, Decl(anonymousBindings.ts, 26, 9)) +>value : Symbol(value, Decl(anonymousBindings.ts, 26, 62)) +>next : Symbol(next, Decl(anonymousBindings.ts, 26, 69)) + + return node; +>node : Symbol(node, Decl(anonymousBindings.ts, 26, 9)) +} +export function recursiveTuple(value: T) { +>recursiveTuple : Symbol(recursiveTuple, Decl(anonymousBindings.ts, 28, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 29, 31)) +>value : Symbol(value, Decl(anonymousBindings.ts, 29, 34)) +>T : Symbol(T, Decl(anonymousBindings.ts, 29, 31)) + + type Tuple = readonly [T, Tuple]; +>Tuple : Symbol(Tuple, Decl(anonymousBindings.ts, 29, 45)) +>T : Symbol(T, Decl(anonymousBindings.ts, 29, 31)) +>Tuple : Symbol(Tuple, Decl(anonymousBindings.ts, 29, 45)) + + return null! as Tuple; +>Tuple : Symbol(Tuple, Decl(anonymousBindings.ts, 29, 45)) +} +export function inferredCaptured() { +>inferredCaptured : Symbol(inferredCaptured, Decl(anonymousBindings.ts, 32, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 33, 33)) + + type Node = { value: V; next: Node }; +>Node : Symbol(Node, Decl(anonymousBindings.ts, 33, 39)) +>V : Symbol(V, Decl(anonymousBindings.ts, 34, 14)) +>value : Symbol(value, Decl(anonymousBindings.ts, 34, 20)) +>V : Symbol(V, Decl(anonymousBindings.ts, 34, 14)) +>next : Symbol(next, Decl(anonymousBindings.ts, 34, 30)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 33, 39)) +>V : Symbol(V, Decl(anonymousBindings.ts, 34, 14)) + + return null! as (T extends () => infer U ? Node : never); +>T : Symbol(T, Decl(anonymousBindings.ts, 33, 33)) +>U : Symbol(U, Decl(anonymousBindings.ts, 35, 42)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 33, 39)) +>U : Symbol(U, Decl(anonymousBindings.ts, 35, 42)) +} +export function mappedCaptured() { +>mappedCaptured : Symbol(mappedCaptured, Decl(anonymousBindings.ts, 36, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 37, 31)) + + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; +>Node : Symbol(Node, Decl(anonymousBindings.ts, 37, 37)) +>K : Symbol(K, Decl(anonymousBindings.ts, 38, 19)) +>T : Symbol(T, Decl(anonymousBindings.ts, 37, 31)) +>value : Symbol(value, Decl(anonymousBindings.ts, 38, 35)) +>T : Symbol(T, Decl(anonymousBindings.ts, 37, 31)) +>K : Symbol(K, Decl(anonymousBindings.ts, 38, 19)) +>next : Symbol(next, Decl(anonymousBindings.ts, 38, 48)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 37, 37)) + + return null! as Node; +>Node : Symbol(Node, Decl(anonymousBindings.ts, 37, 37)) +} +export function freshGeneric(unused: T) { +>freshGeneric : Symbol(freshGeneric, Decl(anonymousBindings.ts, 40, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 41, 29)) +>unused : Symbol(unused, Decl(anonymousBindings.ts, 41, 32)) +>T : Symbol(T, Decl(anonymousBindings.ts, 41, 29)) + + const recur = (value: U) => recur; +>recur : Symbol(recur, Decl(anonymousBindings.ts, 42, 9)) +>U : Symbol(U, Decl(anonymousBindings.ts, 42, 19)) +>value : Symbol(value, Decl(anonymousBindings.ts, 42, 22)) +>U : Symbol(U, Decl(anonymousBindings.ts, 42, 19)) +>recur : Symbol(recur, Decl(anonymousBindings.ts, 42, 9)) + + return recur; +>recur : Symbol(recur, Decl(anonymousBindings.ts, 42, 9)) +} +export function mutualCaptured(left: T, right: U) { +>mutualCaptured : Symbol(mutualCaptured, Decl(anonymousBindings.ts, 44, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 45, 31)) +>U : Symbol(U, Decl(anonymousBindings.ts, 45, 33)) +>left : Symbol(left, Decl(anonymousBindings.ts, 45, 37)) +>T : Symbol(T, Decl(anonymousBindings.ts, 45, 31)) +>right : Symbol(right, Decl(anonymousBindings.ts, 45, 45)) +>U : Symbol(U, Decl(anonymousBindings.ts, 45, 33)) + + type Left = { left: T; next: Right }; +>Left : Symbol(Left, Decl(anonymousBindings.ts, 45, 57)) +>left : Symbol(left, Decl(anonymousBindings.ts, 46, 17)) +>T : Symbol(T, Decl(anonymousBindings.ts, 45, 31)) +>next : Symbol(next, Decl(anonymousBindings.ts, 46, 26)) +>Right : Symbol(Right, Decl(anonymousBindings.ts, 46, 41)) + + type Right = { right: U; self: Right; next: Left }; +>Right : Symbol(Right, Decl(anonymousBindings.ts, 46, 41)) +>right : Symbol(right, Decl(anonymousBindings.ts, 47, 18)) +>U : Symbol(U, Decl(anonymousBindings.ts, 45, 33)) +>self : Symbol(self, Decl(anonymousBindings.ts, 47, 28)) +>Right : Symbol(Right, Decl(anonymousBindings.ts, 46, 41)) +>next : Symbol(next, Decl(anonymousBindings.ts, 47, 41)) +>Left : Symbol(Left, Decl(anonymousBindings.ts, 45, 57)) + + return { left: null! as Left, right: null! as Right }; +>left : Symbol(left, Decl(anonymousBindings.ts, 48, 12)) +>Left : Symbol(Left, Decl(anonymousBindings.ts, 45, 57)) +>right : Symbol(right, Decl(anonymousBindings.ts, 48, 33)) +>Right : Symbol(Right, Decl(anonymousBindings.ts, 46, 41)) +} +export class CapturedClass { +>CapturedClass : Symbol(CapturedClass, Decl(anonymousBindings.ts, 49, 1)) +>T : Symbol(T, Decl(anonymousBindings.ts, 50, 27)) + + constructor(public value: T) {} +>value : Symbol(CapturedClass.value, Decl(anonymousBindings.ts, 51, 16)) +>T : Symbol(T, Decl(anonymousBindings.ts, 50, 27)) + + make(inner: U) { +>make : Symbol(CapturedClass.make, Decl(anonymousBindings.ts, 51, 35)) +>U : Symbol(U, Decl(anonymousBindings.ts, 52, 9)) +>T : Symbol(T, Decl(anonymousBindings.ts, 50, 27)) +>inner : Symbol(inner, Decl(anonymousBindings.ts, 52, 22)) +>U : Symbol(U, Decl(anonymousBindings.ts, 52, 9)) + + const node = { outer: this.value, inner, next: () => node }; +>node : Symbol(node, Decl(anonymousBindings.ts, 53, 13)) +>outer : Symbol(outer, Decl(anonymousBindings.ts, 53, 22)) +>this.value : Symbol(CapturedClass.value, Decl(anonymousBindings.ts, 51, 16)) +>this : Symbol(CapturedClass, Decl(anonymousBindings.ts, 49, 1)) +>value : Symbol(CapturedClass.value, Decl(anonymousBindings.ts, 51, 16)) +>inner : Symbol(inner, Decl(anonymousBindings.ts, 53, 41)) +>next : Symbol(next, Decl(anonymousBindings.ts, 53, 48)) +>node : Symbol(node, Decl(anonymousBindings.ts, 53, 13)) + + return node; +>node : Symbol(node, Decl(anonymousBindings.ts, 53, 13)) + } +} +export function covariantClass() { +>covariantClass : Symbol(covariantClass, Decl(anonymousBindings.ts, 56, 1)) + + return class Node { +>Node : Symbol(Node, Decl(anonymousBindings.ts, 58, 10)) +>T : Symbol(T, Decl(anonymousBindings.ts, 58, 22)) + + value!: T; +>value : Symbol(Node.value, Decl(anonymousBindings.ts, 58, 30)) +>T : Symbol(T, Decl(anonymousBindings.ts, 58, 22)) + + next(): Node { return this; } +>next : Symbol(Node.next, Decl(anonymousBindings.ts, 59, 18)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 58, 10)) +>T : Symbol(T, Decl(anonymousBindings.ts, 58, 22)) +>this : Symbol(Node, Decl(anonymousBindings.ts, 58, 10)) + + }; +} +export function contravariantClass() { +>contravariantClass : Symbol(contravariantClass, Decl(anonymousBindings.ts, 62, 1)) + + return class Node { +>Node : Symbol(Node, Decl(anonymousBindings.ts, 64, 10)) +>T : Symbol(T, Decl(anonymousBindings.ts, 64, 22)) + + consume!: (value: T) => void; +>consume : Symbol(Node.consume, Decl(anonymousBindings.ts, 64, 29)) +>value : Symbol(value, Decl(anonymousBindings.ts, 65, 19)) +>T : Symbol(T, Decl(anonymousBindings.ts, 64, 22)) + + next(): Node { return this; } +>next : Symbol(Node.next, Decl(anonymousBindings.ts, 65, 37)) +>Node : Symbol(Node, Decl(anonymousBindings.ts, 64, 10)) +>T : Symbol(T, Decl(anonymousBindings.ts, 64, 22)) +>this : Symbol(Node, Decl(anonymousBindings.ts, 64, 10)) + + }; +} +export namespace Nested { +>Nested : Symbol(Nested, Decl(anonymousBindings.ts, 68, 1)) + + export function captured(value: T) { +>captured : Symbol(captured, Decl(anonymousBindings.ts, 69, 25)) +>T : Symbol(T, Decl(anonymousBindings.ts, 70, 29)) +>value : Symbol(value, Decl(anonymousBindings.ts, 70, 32)) +>T : Symbol(T, Decl(anonymousBindings.ts, 70, 29)) + + const node = { value, next: () => node }; +>node : Symbol(node, Decl(anonymousBindings.ts, 71, 13)) +>value : Symbol(value, Decl(anonymousBindings.ts, 71, 22)) +>next : Symbol(next, Decl(anonymousBindings.ts, 71, 29)) +>node : Symbol(node, Decl(anonymousBindings.ts, 71, 13)) + + return node; +>node : Symbol(node, Decl(anonymousBindings.ts, 71, 13)) + } +} +const capturedValue: string = captured("text").next().consume("other").value; +>capturedValue : Symbol(capturedValue, Decl(anonymousBindings.ts, 75, 5)) +>captured("text").next().consume("other").value : Symbol(value, Decl(anonymousBindings.ts, 3, 18)) +>captured("text").next().consume : Symbol(consume, Decl(anonymousBindings.ts, 3, 43)) +>captured("text").next : Symbol(next, Decl(anonymousBindings.ts, 3, 25)) +>captured : Symbol(captured, Decl(anonymousBindings.ts, 1, 62)) +>next : Symbol(next, Decl(anonymousBindings.ts, 3, 25)) +>consume : Symbol(consume, Decl(anonymousBindings.ts, 3, 43)) +>value : Symbol(value, Decl(anonymousBindings.ts, 3, 18)) + +const nestedValue = nestedCaptured(1)("text").shadow(true).next.next(); +>nestedValue : Symbol(nestedValue, Decl(anonymousBindings.ts, 76, 5)) +>nestedCaptured(1)("text").shadow(true).next.next : Symbol(next, Decl(anonymousBindings.ts, 10, 18)) +>nestedCaptured(1)("text").shadow(true).next : Symbol(next, Decl(anonymousBindings.ts, 12, 60)) +>nestedCaptured(1)("text").shadow : Symbol(shadow, Decl(anonymousBindings.ts, 11, 29)) +>nestedCaptured : Symbol(nestedCaptured, Decl(anonymousBindings.ts, 5, 1)) +>shadow : Symbol(shadow, Decl(anonymousBindings.ts, 11, 29)) +>next : Symbol(next, Decl(anonymousBindings.ts, 12, 60)) +>next : Symbol(next, Decl(anonymousBindings.ts, 10, 18)) + +const nestedOuter: number = nestedValue.outer; +>nestedOuter : Symbol(nestedOuter, Decl(anonymousBindings.ts, 77, 5)) +>nestedValue.outer : Symbol(outer, Decl(anonymousBindings.ts, 8, 22)) +>nestedValue : Symbol(nestedValue, Decl(anonymousBindings.ts, 76, 5)) +>outer : Symbol(outer, Decl(anonymousBindings.ts, 8, 22)) + +const nestedInner: string = nestedValue.inner; +>nestedInner : Symbol(nestedInner, Decl(anonymousBindings.ts, 78, 5)) +>nestedValue.inner : Symbol(inner, Decl(anonymousBindings.ts, 9, 18)) +>nestedValue : Symbol(nestedValue, Decl(anonymousBindings.ts, 76, 5)) +>inner : Symbol(inner, Decl(anonymousBindings.ts, 9, 18)) + +const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; +>constrainedValue : Symbol(constrainedValue, Decl(anonymousBindings.ts, 79, 5)) +>constrained<{ value: number }, "value">("value").next().value : Symbol(value, Decl(anonymousBindings.ts, 18, 18)) +>constrained<{ value: number }, "value">("value").next : Symbol(next, Decl(anonymousBindings.ts, 18, 40)) +>constrained : Symbol(constrained, Decl(anonymousBindings.ts, 16, 1)) +>value : Symbol(value, Decl(anonymousBindings.ts, 79, 46)) +>next : Symbol(next, Decl(anonymousBindings.ts, 18, 40)) +>value : Symbol(value, Decl(anonymousBindings.ts, 18, 18)) + +const annotatedValue: string = annotatedCaptured("text").next.next.value; +>annotatedValue : Symbol(annotatedValue, Decl(anonymousBindings.ts, 80, 5)) +>annotatedCaptured("text").next.next.value : Symbol(value, Decl(anonymousBindings.ts, 26, 17)) +>annotatedCaptured("text").next.next : Symbol(next, Decl(anonymousBindings.ts, 26, 38)) +>annotatedCaptured("text").next : Symbol(next, Decl(anonymousBindings.ts, 26, 38)) +>annotatedCaptured : Symbol(annotatedCaptured, Decl(anonymousBindings.ts, 24, 1)) +>next : Symbol(next, Decl(anonymousBindings.ts, 26, 38)) +>next : Symbol(next, Decl(anonymousBindings.ts, 26, 38)) +>value : Symbol(value, Decl(anonymousBindings.ts, 26, 17)) + +const tupleValue: string = recursiveTuple("text")[1][1][0]; +>tupleValue : Symbol(tupleValue, Decl(anonymousBindings.ts, 81, 5)) +>recursiveTuple : Symbol(recursiveTuple, Decl(anonymousBindings.ts, 28, 1)) +>1 : Symbol(1) +>1 : Symbol(1) +>0 : Symbol(0) + +const namespaceValue: number = Nested.captured(1).next().next().value; +>namespaceValue : Symbol(namespaceValue, Decl(anonymousBindings.ts, 82, 5)) +>Nested.captured(1).next().next().value : Symbol(value, Decl(anonymousBindings.ts, 71, 22)) +>Nested.captured(1).next().next : Symbol(next, Decl(anonymousBindings.ts, 71, 29)) +>Nested.captured(1).next : Symbol(next, Decl(anonymousBindings.ts, 71, 29)) +>Nested.captured : Symbol(Nested.captured, Decl(anonymousBindings.ts, 69, 25)) +>Nested : Symbol(Nested, Decl(anonymousBindings.ts, 68, 1)) +>captured : Symbol(Nested.captured, Decl(anonymousBindings.ts, 69, 25)) +>next : Symbol(next, Decl(anonymousBindings.ts, 71, 29)) +>next : Symbol(next, Decl(anonymousBindings.ts, 71, 29)) +>value : Symbol(value, Decl(anonymousBindings.ts, 71, 22)) + +const inferredValue: string = inferredCaptured<() => string>().next.next.value; +>inferredValue : Symbol(inferredValue, Decl(anonymousBindings.ts, 83, 5)) +>inferredCaptured<() => string>().next.next.value : Symbol(value, Decl(anonymousBindings.ts, 34, 20)) +>inferredCaptured<() => string>().next.next : Symbol(next, Decl(anonymousBindings.ts, 34, 30)) +>inferredCaptured<() => string>().next : Symbol(next, Decl(anonymousBindings.ts, 34, 30)) +>inferredCaptured : Symbol(inferredCaptured, Decl(anonymousBindings.ts, 32, 1)) +>next : Symbol(next, Decl(anonymousBindings.ts, 34, 30)) +>next : Symbol(next, Decl(anonymousBindings.ts, 34, 30)) +>value : Symbol(value, Decl(anonymousBindings.ts, 34, 20)) + +const mappedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; +>mappedValue : Symbol(mappedValue, Decl(anonymousBindings.ts, 84, 5)) +>mappedCaptured<{ value: number }>().value.next.value.value : Symbol(value, Decl(anonymousBindings.ts, 38, 35)) +>mappedCaptured<{ value: number }>().value.next.value : Symbol(value, Decl(anonymousBindings.ts, 84, 44)) +>mappedCaptured<{ value: number }>().value.next : Symbol(next, Decl(anonymousBindings.ts, 38, 48)) +>mappedCaptured<{ value: number }>().value : Symbol(value, Decl(anonymousBindings.ts, 84, 44)) +>mappedCaptured : Symbol(mappedCaptured, Decl(anonymousBindings.ts, 36, 1)) +>value : Symbol(value, Decl(anonymousBindings.ts, 84, 44)) +>value : Symbol(value, Decl(anonymousBindings.ts, 84, 44)) +>next : Symbol(next, Decl(anonymousBindings.ts, 38, 48)) +>value : Symbol(value, Decl(anonymousBindings.ts, 84, 44)) +>value : Symbol(value, Decl(anonymousBindings.ts, 38, 35)) + +const freshValue = freshGeneric(1)("text")(true)(2); +>freshValue : Symbol(freshValue, Decl(anonymousBindings.ts, 85, 5)) +>freshGeneric : Symbol(freshGeneric, Decl(anonymousBindings.ts, 40, 1)) + +const mutualValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; +>mutualValue : Symbol(mutualValue, Decl(anonymousBindings.ts, 86, 5)) +>mutualCaptured(1, "text").left.next.self.next.next.right : Symbol(right, Decl(anonymousBindings.ts, 47, 18)) +>mutualCaptured(1, "text").left.next.self.next.next : Symbol(next, Decl(anonymousBindings.ts, 46, 26)) +>mutualCaptured(1, "text").left.next.self.next : Symbol(next, Decl(anonymousBindings.ts, 47, 41)) +>mutualCaptured(1, "text").left.next.self : Symbol(self, Decl(anonymousBindings.ts, 47, 28)) +>mutualCaptured(1, "text").left.next : Symbol(next, Decl(anonymousBindings.ts, 46, 26)) +>mutualCaptured(1, "text").left : Symbol(left, Decl(anonymousBindings.ts, 48, 12)) +>mutualCaptured : Symbol(mutualCaptured, Decl(anonymousBindings.ts, 44, 1)) +>left : Symbol(left, Decl(anonymousBindings.ts, 48, 12)) +>next : Symbol(next, Decl(anonymousBindings.ts, 46, 26)) +>self : Symbol(self, Decl(anonymousBindings.ts, 47, 28)) +>next : Symbol(next, Decl(anonymousBindings.ts, 47, 41)) +>next : Symbol(next, Decl(anonymousBindings.ts, 46, 26)) +>right : Symbol(right, Decl(anonymousBindings.ts, 47, 18)) + +const classValue: string = new CapturedClass("text").make("other").next().outer; +>classValue : Symbol(classValue, Decl(anonymousBindings.ts, 87, 5)) +>new CapturedClass("text").make("other").next().outer : Symbol(outer, Decl(anonymousBindings.ts, 53, 22)) +>new CapturedClass("text").make("other").next : Symbol(next, Decl(anonymousBindings.ts, 53, 48)) +>new CapturedClass("text").make : Symbol(CapturedClass.make, Decl(anonymousBindings.ts, 51, 35)) +>CapturedClass : Symbol(CapturedClass, Decl(anonymousBindings.ts, 49, 1)) +>make : Symbol(CapturedClass.make, Decl(anonymousBindings.ts, 51, 35)) +>next : Symbol(next, Decl(anonymousBindings.ts, 53, 48)) +>outer : Symbol(outer, Decl(anonymousBindings.ts, 53, 22)) + +const optional = optionalCaptured("text"); +>optional : Symbol(optional, Decl(anonymousBindings.ts, 88, 5)) +>optionalCaptured : Symbol(optionalCaptured, Decl(anonymousBindings.ts, 20, 1)) + +if (optional.node) { +>optional.node : Symbol(node, Decl(anonymousBindings.ts, 23, 21)) +>optional : Symbol(optional, Decl(anonymousBindings.ts, 88, 5)) +>node : Symbol(node, Decl(anonymousBindings.ts, 23, 21)) + + const value: string = optional.node.next.next.value; +>value : Symbol(value, Decl(anonymousBindings.ts, 90, 9)) +>optional.node.next.next.value : Symbol(value, Decl(anonymousBindings.ts, 22, 17)) +>optional.node.next.next : Symbol(next, Decl(anonymousBindings.ts, 22, 27)) +>optional.node.next : Symbol(next, Decl(anonymousBindings.ts, 22, 27)) +>optional.node : Symbol(node, Decl(anonymousBindings.ts, 23, 21)) +>optional : Symbol(optional, Decl(anonymousBindings.ts, 88, 5)) +>node : Symbol(node, Decl(anonymousBindings.ts, 23, 21)) +>next : Symbol(next, Decl(anonymousBindings.ts, 22, 27)) +>next : Symbol(next, Decl(anonymousBindings.ts, 22, 27)) +>value : Symbol(value, Decl(anonymousBindings.ts, 22, 17)) +} +captured("text").consume(1); +>captured("text").consume : Symbol(consume, Decl(anonymousBindings.ts, 3, 43)) +>captured : Symbol(captured, Decl(anonymousBindings.ts, 1, 62)) +>consume : Symbol(consume, Decl(anonymousBindings.ts, 3, 43)) + +const invalidTupleValue: number = recursiveTuple("text")[1][0]; +>invalidTupleValue : Symbol(invalidTupleValue, Decl(anonymousBindings.ts, 93, 5)) +>recursiveTuple : Symbol(recursiveTuple, Decl(anonymousBindings.ts, 28, 1)) +>1 : Symbol(1) +>0 : Symbol(0) + +=== shadowedMappedCycle.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : Symbol(Show, Decl(shadowedMappedCycle.ts, 0, 0)) +>T : Symbol(T, Decl(shadowedMappedCycle.ts, 0, 10)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 0, 18)) +>T : Symbol(T, Decl(shadowedMappedCycle.ts, 0, 10)) +>T : Symbol(T, Decl(shadowedMappedCycle.ts, 0, 10)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 0, 18)) + +type Resolve = Show<{ +>Resolve : Symbol(Resolve, Decl(shadowedMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 1, 13)) +>Show : Symbol(Show, Decl(shadowedMappedCycle.ts, 0, 0)) + + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => Resolve : M[K][P]; +>P : Symbol(P, Decl(shadowedMappedCycle.ts, 2, 5)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 1, 15)) +>P : Symbol(P, Decl(shadowedMappedCycle.ts, 2, 5)) +>T : Symbol(T, Decl(shadowedMappedCycle.ts, 2, 48)) +>shadowedCycle : Symbol(shadowedCycle, Decl(shadowedMappedCycle.ts, 2, 51)) +>T : Symbol(T, Decl(shadowedMappedCycle.ts, 2, 48)) +>Resolve : Symbol(Resolve, Decl(shadowedMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 1, 15)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 1, 13)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 1, 15)) +>P : Symbol(P, Decl(shadowedMappedCycle.ts, 2, 5)) + +}>; +declare const build: () => { [K in keyof M]: Resolve }; +>build : Symbol(build, Decl(shadowedMappedCycle.ts, 4, 13)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 4, 22)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 4, 33)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 4, 22)) +>Resolve : Symbol(Resolve, Decl(shadowedMappedCycle.ts, 0, 50)) +>M : Symbol(M, Decl(shadowedMappedCycle.ts, 4, 22)) +>K : Symbol(K, Decl(shadowedMappedCycle.ts, 4, 33)) + +export const shadowedCycle = build<{ Node: { value: number; next: "ref" } }>(); +>shadowedCycle : Symbol(shadowedCycle, Decl(shadowedMappedCycle.ts, 5, 12)) +>build : Symbol(build, Decl(shadowedMappedCycle.ts, 4, 13)) +>Node : Symbol(Node, Decl(shadowedMappedCycle.ts, 5, 36)) +>value : Symbol(value, Decl(shadowedMappedCycle.ts, 5, 44)) +>next : Symbol(next, Decl(shadowedMappedCycle.ts, 5, 59)) + +const shadowedValue: number = shadowedCycle.Node.next(1).next("text").value; +>shadowedValue : Symbol(shadowedValue, Decl(shadowedMappedCycle.ts, 6, 5)) +>shadowedCycle.Node.next(1).next("text").value : Symbol(value, Decl(shadowedMappedCycle.ts, 5, 44)) +>shadowedCycle.Node.next(1).next : Symbol(next, Decl(shadowedMappedCycle.ts, 5, 59)) +>shadowedCycle.Node.next : Symbol(next, Decl(shadowedMappedCycle.ts, 5, 59)) +>shadowedCycle.Node : Symbol(Node, Decl(shadowedMappedCycle.ts, 5, 36)) +>shadowedCycle : Symbol(shadowedCycle, Decl(shadowedMappedCycle.ts, 5, 12)) +>Node : Symbol(Node, Decl(shadowedMappedCycle.ts, 5, 36)) +>next : Symbol(next, Decl(shadowedMappedCycle.ts, 5, 59)) +>next : Symbol(next, Decl(shadowedMappedCycle.ts, 5, 59)) +>value : Symbol(value, Decl(shadowedMappedCycle.ts, 5, 44)) + +=== globalRecursiveA.ts === +function makeA() { +>makeA : Symbol(makeA, Decl(globalRecursiveA.ts, 0, 0)) + + return { + value: 1, +>value : Symbol(value, Decl(globalRecursiveA.ts, 1, 12)) + + self() { return this; }, +>self : Symbol(self, Decl(globalRecursiveA.ts, 2, 17)) +>this : Symbol(__object, Decl(globalRecursiveA.ts, 1, 10)) + + }; +} +type makeReserved_recursive = "reserved"; +>makeReserved_recursive : Symbol(makeReserved_recursive, Decl(globalRecursiveA.ts, 5, 1)) + +function makeReserved() { +>makeReserved : Symbol(makeReserved, Decl(globalRecursiveA.ts, 6, 41)) + + return { + value: true, +>value : Symbol(value, Decl(globalRecursiveA.ts, 8, 12)) + + self() { return this; }, +>self : Symbol(self, Decl(globalRecursiveA.ts, 9, 20)) +>this : Symbol(__object, Decl(globalRecursiveA.ts, 8, 10)) + + }; +} +class GlobalA { +>GlobalA : Symbol(GlobalA, Decl(globalRecursiveA.ts, 12, 1)) + + static create(value: T) { +>create : Symbol(GlobalA.create, Decl(globalRecursiveA.ts, 13, 15)) +>T : Symbol(T, Decl(globalRecursiveA.ts, 14, 18)) +>value : Symbol(value, Decl(globalRecursiveA.ts, 14, 21)) +>T : Symbol(T, Decl(globalRecursiveA.ts, 14, 18)) + + const node = { value, next: () => node }; +>node : Symbol(node, Decl(globalRecursiveA.ts, 15, 13)) +>value : Symbol(value, Decl(globalRecursiveA.ts, 15, 22)) +>next : Symbol(next, Decl(globalRecursiveA.ts, 15, 29)) +>node : Symbol(node, Decl(globalRecursiveA.ts, 15, 13)) + + return node; +>node : Symbol(node, Decl(globalRecursiveA.ts, 15, 13)) + } + static "a-b"() { +>"a-b" : Symbol(GlobalA["a-b"], Decl(globalRecursiveA.ts, 17, 5)) + + const node = { value: true, next: () => node }; +>node : Symbol(node, Decl(globalRecursiveA.ts, 19, 13)) +>value : Symbol(value, Decl(globalRecursiveA.ts, 19, 22)) +>next : Symbol(next, Decl(globalRecursiveA.ts, 19, 35)) +>node : Symbol(node, Decl(globalRecursiveA.ts, 19, 13)) + + return node; +>node : Symbol(node, Decl(globalRecursiveA.ts, 19, 13)) + } +} + +=== globalRecursiveB.ts === +function makeB() { +>makeB : Symbol(makeB, Decl(globalRecursiveB.ts, 0, 0)) + + return { + value: "text", +>value : Symbol(value, Decl(globalRecursiveB.ts, 1, 12)) + + self() { return this; }, +>self : Symbol(self, Decl(globalRecursiveB.ts, 2, 22)) +>this : Symbol(__object, Decl(globalRecursiveB.ts, 1, 10)) + + }; +} +class GlobalB { +>GlobalB : Symbol(GlobalB, Decl(globalRecursiveB.ts, 5, 1)) + + static create(value: T) { +>create : Symbol(GlobalB.create, Decl(globalRecursiveB.ts, 6, 15)) +>T : Symbol(T, Decl(globalRecursiveB.ts, 7, 18)) +>value : Symbol(value, Decl(globalRecursiveB.ts, 7, 21)) +>T : Symbol(T, Decl(globalRecursiveB.ts, 7, 18)) + + const node = { value, next: () => node }; +>node : Symbol(node, Decl(globalRecursiveB.ts, 8, 13)) +>value : Symbol(value, Decl(globalRecursiveB.ts, 8, 22)) +>next : Symbol(next, Decl(globalRecursiveB.ts, 8, 29)) +>node : Symbol(node, Decl(globalRecursiveB.ts, 8, 13)) + + return node; +>node : Symbol(node, Decl(globalRecursiveB.ts, 8, 13)) + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.types b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.types index 7f4921e58c412..221fffa2b587d 100644 --- a/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.types +++ b/tsc/testdata/baselines/reference/compiler/recursiveFunctionDeclarationSerialization.types @@ -33,7 +33,7 @@ export function declaration() { return declaration; } export const annotated: () => typeof annotated = () => annotated; >annotated : () => typeof annotated >annotated : () => typeof annotated ->() => annotated : () => () => typeof annotated +>() => annotated : () => typeof annotated >annotated : () => typeof annotated export const first = () => second; @@ -88,8 +88,8 @@ export const contextual: () => unknown = function self() { return self; }; >self : () => typeof self export const specialized = generic; ->specialized : (value: number) => (value: T) => typeof generic ->generic : (value: number) => (value: T) => typeof generic +>specialized : (value: number) => typeof generic +>generic : (value: number) => typeof generic >generic : (value: T) => typeof generic export const annotatedParameter = (value: string | number) => annotatedParameter; @@ -1370,3 +1370,1412 @@ const inferredValue: string = inferredCopy.next(1).second("text").value; >"text" : "text" >value : string +=== mappedCycles.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : { [K in keyof T]: T[K]; } + +type Resolve = Show<{ +>Resolve : { [P in keyof M[K]]: M[K][P] extends "ref" ? any extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +>build : () => { [K in keyof M]: Resolve; } + +export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +>mappedCycle : { Node: { value: number; next: any; }; } +>build<{ Node: { value: number; next: "ref" } }>() : { Node: { value: number; next: any; }; } +>build : () => { [K in keyof M]: Resolve; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +export const mappedCycleCopy = mappedCycle; +>mappedCycleCopy : { Node: { value: number; next: any; }; } +>mappedCycle : { Node: { value: number; next: any; }; } + +export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; +>nestedCycle : { wrapped: { Node: { value: string; next: (typeof nestedCycle)["wrapped"]["Node"]; }; }; } +>{ wrapped: build<{ Node: { value: string; next: "ref" } }>() } : { wrapped: { Node: { value: string; next: (typeof nestedCycle)["wrapped"]["Node"]; }; }; } +>wrapped : { Node: { value: string; next: any; }; } +>build<{ Node: { value: string; next: "ref" } }>() : { Node: { value: string; next: any; }; } +>build : () => { [K in keyof M]: Resolve; } +>Node : { value: string; next: "ref"; } +>value : string +>next : "ref" + +export const cycleKey = Symbol(); +>cycleKey : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +export const keyedCycles = build<{ +>keyedCycles : { "a-b": { value: string; next: any; }; 0: { value: boolean; next: any; }; [cycleKey]: { value: number; next: any; }; } +>build<{ "a-b": { value: string; next: "ref" }; 0: { value: boolean; next: "ref" }; [cycleKey]: { value: number; next: "ref" };}>() : { "a-b": { value: string; next: any; }; 0: { value: boolean; next: any; }; [cycleKey]: { value: number; next: any; }; } +>build : () => { [K in keyof M]: Resolve; } + + "a-b": { value: string; next: "ref" }; +>"a-b" : { value: string; next: "ref"; } +>value : string +>next : "ref" + + 0: { value: boolean; next: "ref" }; +>0 : { value: boolean; next: "ref"; } +>value : boolean +>next : "ref" + + [cycleKey]: { value: number; next: "ref" }; +>[cycleKey] : { value: number; next: "ref"; } +>cycleKey : unique symbol +>value : number +>next : "ref" + +}>(); +export const sharedCycles = { +>sharedCycles : { first: { Node: { value: number; next: (typeof sharedCycles)["first"]["Node"]; }; }; second: { Node: { value: number; next: (typeof sharedCycles)["second"]["Node"]; }; }; } +>{ first: mappedCycle, second: mappedCycle,} : { first: { Node: { value: number; next: (typeof sharedCycles)["first"]["Node"]; }; }; second: { Node: { value: number; next: (typeof sharedCycles)["second"]["Node"]; }; }; } + + first: mappedCycle, +>first : { Node: { value: number; next: any; }; } +>mappedCycle : { Node: { value: number; next: any; }; } + + second: mappedCycle, +>second : { Node: { value: number; next: any; }; } +>mappedCycle : { Node: { value: number; next: any; }; } + +}; +export const broadCycle: { Node: unknown } = mappedCycle; +>broadCycle : { Node: unknown; } +>Node : unknown +>mappedCycle : { Node: { value: number; next: any; }; } + +type ResolveMutual = Show<{ +>ResolveMutual : { [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M; } ? { [P_1 in keyof M[R]]: M[R][P_1] extends { ref: infer R extends keyof M; } ? any : M[R][P_1]; } extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; +>ref : R + +}>; +declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; +>buildMutual : () => { [K in keyof M]: ResolveMutual; } + +export const mutualCycle = buildMutual<{ +>mutualCycle : { First: { value: number; next: { value: string; next: any; }; }; Second: { value: string; next: { value: number; next: any; }; }; } +>buildMutual<{ First: { value: number; next: { ref: "Second" } }; Second: { value: string; next: { ref: "First" } };}>() : { First: { value: number; next: { value: string; next: any; }; }; Second: { value: string; next: { value: number; next: any; }; }; } +>buildMutual : () => { [K in keyof M]: ResolveMutual; } + + First: { value: number; next: { ref: "Second" } }; +>First : { value: number; next: { ref: "Second"; }; } +>value : number +>next : { ref: "Second"; } +>ref : "Second" + + Second: { value: string; next: { ref: "First" } }; +>Second : { value: string; next: { ref: "First"; }; } +>value : string +>next : { ref: "First"; } +>ref : "First" + +}>(); + +const mappedValue: number = mappedCycle.Node.next.next.value; +>mappedValue : number +>mappedCycle.Node.next.next.value : number +>mappedCycle.Node.next.next : { value: number; next: any; } +>mappedCycle.Node.next : { value: number; next: any; } +>mappedCycle.Node : { value: number; next: any; } +>mappedCycle : { Node: { value: number; next: any; }; } +>Node : { value: number; next: any; } +>next : { value: number; next: any; } +>next : { value: number; next: any; } +>value : number + +const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; +>nestedMappedValue : string +>nestedCycle.wrapped.Node.next.next.value : string +>nestedCycle.wrapped.Node.next.next : { value: string; next: any; } +>nestedCycle.wrapped.Node.next : { value: string; next: any; } +>nestedCycle.wrapped.Node : { value: string; next: any; } +>nestedCycle.wrapped : { Node: { value: string; next: any; }; } +>nestedCycle : { wrapped: { Node: { value: string; next: (typeof nestedCycle)["wrapped"]["Node"]; }; }; } +>wrapped : { Node: { value: string; next: any; }; } +>Node : { value: string; next: any; } +>next : { value: string; next: any; } +>next : { value: string; next: any; } +>value : string + +const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; +>quotedMappedValue : string +>keyedCycles["a-b"].next.next.value : string +>keyedCycles["a-b"].next.next : { value: string; next: any; } +>keyedCycles["a-b"].next : { value: string; next: any; } +>keyedCycles["a-b"] : { value: string; next: any; } +>keyedCycles : { "a-b": { value: string; next: any; }; 0: { value: boolean; next: any; }; [cycleKey]: { value: number; next: any; }; } +>"a-b" : "a-b" +>next : { value: string; next: any; } +>next : { value: string; next: any; } +>value : string + +const numericMappedValue: boolean = keyedCycles[0].next.next.value; +>numericMappedValue : boolean +>keyedCycles[0].next.next.value : boolean +>keyedCycles[0].next.next : { value: boolean; next: any; } +>keyedCycles[0].next : { value: boolean; next: any; } +>keyedCycles[0] : { value: boolean; next: any; } +>keyedCycles : { "a-b": { value: string; next: any; }; 0: { value: boolean; next: any; }; [cycleKey]: { value: number; next: any; }; } +>0 : 0 +>next : { value: boolean; next: any; } +>next : { value: boolean; next: any; } +>value : boolean + +const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; +>symbolMappedValue : number +>keyedCycles[cycleKey].next.next.value : number +>keyedCycles[cycleKey].next.next : { value: number; next: any; } +>keyedCycles[cycleKey].next : { value: number; next: any; } +>keyedCycles[cycleKey] : { value: number; next: any; } +>keyedCycles : { "a-b": { value: string; next: any; }; 0: { value: boolean; next: any; }; [cycleKey]: { value: number; next: any; }; } +>cycleKey : unique symbol +>next : { value: number; next: any; } +>next : { value: number; next: any; } +>value : number + +const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; +>sharedMappedValue : number +>sharedCycles.second.Node.next.next.value : number +>sharedCycles.second.Node.next.next : { value: number; next: any; } +>sharedCycles.second.Node.next : { value: number; next: any; } +>sharedCycles.second.Node : { value: number; next: any; } +>sharedCycles.second : { Node: { value: number; next: any; }; } +>sharedCycles : { first: { Node: { value: number; next: (typeof sharedCycles)["first"]["Node"]; }; }; second: { Node: { value: number; next: (typeof sharedCycles)["second"]["Node"]; }; }; } +>second : { Node: { value: number; next: any; }; } +>Node : { value: number; next: any; } +>next : { value: number; next: any; } +>next : { value: number; next: any; } +>value : number + +const mutualFirstValue: number = mutualCycle.First.next.next.value; +>mutualFirstValue : number +>mutualCycle.First.next.next.value : number +>mutualCycle.First.next.next : { value: number; next: { value: string; next: any; }; } +>mutualCycle.First.next : { value: string; next: { value: number; next: any; }; } +>mutualCycle.First : { value: number; next: { value: string; next: any; }; } +>mutualCycle : { First: { value: number; next: { value: string; next: any; }; }; Second: { value: string; next: { value: number; next: any; }; }; } +>First : { value: number; next: { value: string; next: any; }; } +>next : { value: string; next: { value: number; next: any; }; } +>next : { value: number; next: { value: string; next: any; }; } +>value : number + +const mutualSecondValue: string = mutualCycle.First.next.value; +>mutualSecondValue : string +>mutualCycle.First.next.value : string +>mutualCycle.First.next : { value: string; next: { value: number; next: any; }; } +>mutualCycle.First : { value: number; next: { value: string; next: any; }; } +>mutualCycle : { First: { value: number; next: { value: string; next: any; }; }; Second: { value: string; next: { value: number; next: any; }; }; } +>First : { value: number; next: { value: string; next: any; }; } +>next : { value: string; next: { value: number; next: any; }; } +>value : string + +const invalidMappedValue: string = mappedCycle.Node.next.next.value; +>invalidMappedValue : string +>mappedCycle.Node.next.next.value : number +>mappedCycle.Node.next.next : { value: number; next: any; } +>mappedCycle.Node.next : { value: number; next: any; } +>mappedCycle.Node : { value: number; next: any; } +>mappedCycle : { Node: { value: number; next: any; }; } +>Node : { value: number; next: any; } +>next : { value: number; next: any; } +>next : { value: number; next: any; } +>value : number + +const invalidMutualValue: number = mutualCycle.First.next.value; +>invalidMutualValue : number +>mutualCycle.First.next.value : string +>mutualCycle.First.next : { value: string; next: { value: number; next: any; }; } +>mutualCycle.First : { value: number; next: { value: string; next: any; }; } +>mutualCycle : { First: { value: number; next: { value: string; next: any; }; }; Second: { value: string; next: { value: number; next: any; }; }; } +>First : { value: number; next: { value: string; next: any; }; } +>next : { value: string; next: { value: number; next: any; }; } +>value : string + +=== optionalMappedCycle.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : { [K in keyof T]: T[K]; } + +type Resolve = Show<{ +>Resolve : { [P in keyof M[K]]: M[K][P] extends "ref" ? any extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]?: Resolve }; +>build : () => { [K in keyof M]?: Resolve; } + +export const optionalCycle = build<{ Node: { value: number; next: "ref" } }>(); +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } +>build<{ Node: { value: number; next: "ref" } }>() : { Node?: { value: number; next: any; } | undefined; } +>build : () => { [K in keyof M]?: Resolve; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +const optionalValue: number | undefined = optionalCycle.Node?.next.next.value; +>optionalValue : number | undefined +>optionalCycle.Node?.next.next.value : number | undefined +>optionalCycle.Node?.next.next : { value: number; next: any; } | undefined +>optionalCycle.Node?.next : { value: number; next: any; } | undefined +>optionalCycle.Node : { value: number; next: any; } | undefined +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } +>Node : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>value : number | undefined + +export const optionalCopy = optionalCycle; +>optionalCopy : { Node?: { value: number; next: any; } | undefined; } +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } + +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +>buildNullable : () => { [K in keyof M]: Resolve | null; } + +export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); +>nullableCycle : { Node: { value: string; next: any; } | null; } +>buildNullable<{ Node: { value: string; next: "ref" } }>() : { Node: { value: string; next: any; } | null; } +>buildNullable : () => { [K in keyof M]: Resolve | null; } +>Node : { value: string; next: "ref"; } +>value : string +>next : "ref" + +declare const wrap: (value: T) => { required: T; optional?: T | null }; +>wrap : (value: T) => { required: T; optional?: T | null; } +>value : T +>required : T +>optional : T | null | undefined + +export const mixedCycles = wrap(optionalCycle); +>mixedCycles : { required: { Node?: { value: number; next: any; } | undefined; }; optional?: { Node?: { value: number; next: any; } | undefined; } | null | undefined; } +>wrap(optionalCycle) : { required: { Node?: { value: number; next: any; } | undefined; }; optional?: { Node?: { value: number; next: any; } | undefined; } | null | undefined; } +>wrap : (value: T) => { required: T; optional?: T | null; } +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } + +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +>sharedOptionalCycles : { first: { Node?: { value: number; next: any; } | undefined; }; second: { Node?: { value: number; next: any; } | undefined; }; } +>{ first: optionalCycle, second: optionalCycle } : { first: { Node?: { value: number; next: any; } | undefined; }; second: { Node?: { value: number; next: any; } | undefined; }; } +>first : { Node?: { value: number; next: any; } | undefined; } +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } +>second : { Node?: { value: number; next: any; } | undefined; } +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } + +export const nullableKey = Symbol(); +>nullableKey : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +export const nullableKeys = buildNullable<{ +>nullableKeys : { "a-b": { value: string; next: any; } | null; 0: { value: boolean; next: any; } | null; [nullableKey]: { value: number; next: any; } | null; } +>buildNullable<{ "a-b": { value: string; next: "ref" }; 0: { value: boolean; next: "ref" }; [nullableKey]: { value: number; next: "ref" };}>() : { "a-b": { value: string; next: any; } | null; 0: { value: boolean; next: any; } | null; [nullableKey]: { value: number; next: any; } | null; } +>buildNullable : () => { [K in keyof M]: Resolve | null; } + + "a-b": { value: string; next: "ref" }; +>"a-b" : { value: string; next: "ref"; } +>value : string +>next : "ref" + + 0: { value: boolean; next: "ref" }; +>0 : { value: boolean; next: "ref"; } +>value : boolean +>next : "ref" + + [nullableKey]: { value: number; next: "ref" }; +>[nullableKey] : { value: number; next: "ref"; } +>nullableKey : unique symbol +>value : number +>next : "ref" + +}>(); +declare const buildNullableRoot: () => Resolve | null; +>buildNullableRoot : () => Resolve | null + +export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); +>nullableRoot : { value: number; next: any; } | null +>buildNullableRoot<{ Node: { value: number; next: "ref" } }>() : { value: number; next: any; } | null +>buildNullableRoot : () => Resolve | null +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +declare const buildOptionalRoot: () => Resolve | undefined; +>buildOptionalRoot : () => Resolve | undefined + +export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); +>optionalRoot : { value: string; next: any; } | undefined +>buildOptionalRoot<{ Node: { value: string; next: "ref" } }>() : { value: string; next: any; } | undefined +>buildOptionalRoot : () => Resolve | undefined +>Node : { value: string; next: "ref"; } +>value : string +>next : "ref" + +type ResolveNullable = Show<{ +>ResolveNullable : { [P in keyof M[K]]: M[K][P] extends "ref" ? (any extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never) | null : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +>buildNullableLinks : () => { [K in keyof M]: ResolveNullable | null; } + +export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); +>nullableLinks : { Node: { value: number; next: any | null; } | null; } +>buildNullableLinks<{ Node: { value: number; next: "ref" } }>() : { Node: { value: number; next: any | null; } | null; } +>buildNullableLinks : () => { [K in keyof M]: ResolveNullable | null; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; +>buildOptionalNullableLinks : () => { [K in keyof M]?: ResolveNullable | null; } + +export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); +>optionalNullableLinks : { Node?: { value: number; next: any | null; } | null | undefined; } +>buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>() : { Node?: { value: number; next: any | null; } | null | undefined; } +>buildOptionalNullableLinks : () => { [K in keyof M]?: ResolveNullable | null; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +type ResolveOptional = Show<{ +>ResolveOptional : { [P in keyof M[K]]: M[K][P] extends "ref" ? (any extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never) | undefined : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; +}>; +declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; +>buildNullableOptionalLinks : () => { [K in keyof M]: ResolveOptional | null; } + +export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); +>nullableOptionalLinks : { Node: { value: number; next: any | undefined; } | null; } +>buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>() : { Node: { value: number; next: any | undefined; } | null; } +>buildNullableOptionalLinks : () => { [K in keyof M]: ResolveOptional | null; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +type ResolveNullish = Show<{ +>ResolveNullish : { [P in keyof M[K]]: M[K][P] extends "ref" ? (any extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never) | null | undefined : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; +}>; +declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; +>buildNullishLinks : () => { [K in keyof M]?: ResolveNullish | null; } + +export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); +>nullishLinks : { Node?: { value: number; next: any | null | undefined; } | null | undefined; } +>buildNullishLinks<{ Node: { value: number; next: "ref" } }>() : { Node?: { value: number; next: any | null | undefined; } | null | undefined; } +>buildNullishLinks : () => { [K in keyof M]?: ResolveNullish | null; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +type NonNullable = "shadowed"; +>NonNullable : "shadowed" + +type OptionalNode = (typeof optionalCycle)["Node"] & {}; +>OptionalNode : { value: number; next: any; } +>optionalCycle : { Node?: { value: number; next: any; } | undefined; } + +type NullableNode = (typeof nullableCycle)["Node"] & {}; +>NullableNode : { value: string; next: any; } +>nullableCycle : { Node: { value: string; next: any; } | null; } + +type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; +>NullableLinkNode : { value: number; next: any | null; } +>nullableLinks : { Node: { value: number; next: any | null; } | null; } + +type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; +>NullishLinkNode : { value: number; next: any | null | undefined; } +>nullishLinks : { Node?: { value: number; next: any | null | undefined; } | null | undefined; } + +type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; +>OptionalNullableLinkNode : { value: number; next: any | null; } +>optionalNullableLinks : { Node?: { value: number; next: any | null; } | null | undefined; } + +type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; +>NullableOptionalLinkNode : { value: number; next: any | undefined; } +>nullableOptionalLinks : { Node: { value: number; next: any | undefined; } | null; } + +const copiedValue: number | undefined = optionalCopy.Node?.next.next.value; +>copiedValue : number | undefined +>optionalCopy.Node?.next.next.value : number | undefined +>optionalCopy.Node?.next.next : { value: number; next: any; } | undefined +>optionalCopy.Node?.next : { value: number; next: any; } | undefined +>optionalCopy.Node : { value: number; next: any; } | undefined +>optionalCopy : { Node?: { value: number; next: any; } | undefined; } +>Node : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>value : number | undefined + +const nullableValue: string | undefined = nullableCycle.Node?.next.next.value; +>nullableValue : string | undefined +>nullableCycle.Node?.next.next.value : string | undefined +>nullableCycle.Node?.next.next : { value: string; next: any; } | undefined +>nullableCycle.Node?.next : { value: string; next: any; } | undefined +>nullableCycle.Node : { value: string; next: any; } | null +>nullableCycle : { Node: { value: string; next: any; } | null; } +>Node : { value: string; next: any; } | null +>next : { value: string; next: any; } | undefined +>next : { value: string; next: any; } | undefined +>value : string | undefined + +const mixedValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; +>mixedValue : number | undefined +>mixedCycles.optional?.Node?.next.next.value : number | undefined +>mixedCycles.optional?.Node?.next.next : { value: number; next: any; } | undefined +>mixedCycles.optional?.Node?.next : { value: number; next: any; } | undefined +>mixedCycles.optional?.Node : { value: number; next: any; } | undefined +>mixedCycles.optional : { Node?: { value: number; next: any; } | undefined; } | null | undefined +>mixedCycles : { required: { Node?: { value: number; next: any; } | undefined; }; optional?: { Node?: { value: number; next: any; } | undefined; } | null | undefined; } +>optional : { Node?: { value: number; next: any; } | undefined; } | null | undefined +>Node : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>value : number | undefined + +const sharedValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; +>sharedValue : number | undefined +>sharedOptionalCycles.second.Node?.next.next.value : number | undefined +>sharedOptionalCycles.second.Node?.next.next : { value: number; next: any; } | undefined +>sharedOptionalCycles.second.Node?.next : { value: number; next: any; } | undefined +>sharedOptionalCycles.second.Node : { value: number; next: any; } | undefined +>sharedOptionalCycles.second : { Node?: { value: number; next: any; } | undefined; } +>sharedOptionalCycles : { first: { Node?: { value: number; next: any; } | undefined; }; second: { Node?: { value: number; next: any; } | undefined; }; } +>second : { Node?: { value: number; next: any; } | undefined; } +>Node : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>value : number | undefined + +const quotedValue: string | undefined = nullableKeys["a-b"]?.next.next.value; +>quotedValue : string | undefined +>nullableKeys["a-b"]?.next.next.value : string | undefined +>nullableKeys["a-b"]?.next.next : { value: string; next: any; } | undefined +>nullableKeys["a-b"]?.next : { value: string; next: any; } | undefined +>nullableKeys["a-b"] : { value: string; next: any; } | null +>nullableKeys : { "a-b": { value: string; next: any; } | null; 0: { value: boolean; next: any; } | null; [nullableKey]: { value: number; next: any; } | null; } +>"a-b" : "a-b" +>next : { value: string; next: any; } | undefined +>next : { value: string; next: any; } | undefined +>value : string | undefined + +const numericValue: boolean | undefined = nullableKeys[0]?.next.next.value; +>numericValue : boolean | undefined +>nullableKeys[0]?.next.next.value : boolean | undefined +>nullableKeys[0]?.next.next : { value: boolean; next: any; } | undefined +>nullableKeys[0]?.next : { value: boolean; next: any; } | undefined +>nullableKeys[0] : { value: boolean; next: any; } | null +>nullableKeys : { "a-b": { value: string; next: any; } | null; 0: { value: boolean; next: any; } | null; [nullableKey]: { value: number; next: any; } | null; } +>0 : 0 +>next : { value: boolean; next: any; } | undefined +>next : { value: boolean; next: any; } | undefined +>value : boolean | undefined + +const symbolValue: number | undefined = nullableKeys[nullableKey]?.next.next.value; +>symbolValue : number | undefined +>nullableKeys[nullableKey]?.next.next.value : number | undefined +>nullableKeys[nullableKey]?.next.next : { value: number; next: any; } | undefined +>nullableKeys[nullableKey]?.next : { value: number; next: any; } | undefined +>nullableKeys[nullableKey] : { value: number; next: any; } | null +>nullableKeys : { "a-b": { value: string; next: any; } | null; 0: { value: boolean; next: any; } | null; [nullableKey]: { value: number; next: any; } | null; } +>nullableKey : unique symbol +>next : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>value : number | undefined + +const nullableRootValue: number | undefined = nullableRoot?.next.next.value; +>nullableRootValue : number | undefined +>nullableRoot?.next.next.value : number | undefined +>nullableRoot?.next.next : { value: number; next: any; } | undefined +>nullableRoot?.next : { value: number; next: any; } | undefined +>nullableRoot : { value: number; next: any; } | null +>next : { value: number; next: any; } | undefined +>next : { value: number; next: any; } | undefined +>value : number | undefined + +const optionalRootValue: string | undefined = optionalRoot?.next.next.value; +>optionalRootValue : string | undefined +>optionalRoot?.next.next.value : string | undefined +>optionalRoot?.next.next : { value: string; next: any; } | undefined +>optionalRoot?.next : { value: string; next: any; } | undefined +>optionalRoot : { value: string; next: any; } | undefined +>next : { value: string; next: any; } | undefined +>next : { value: string; next: any; } | undefined +>value : string | undefined + +const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; +>nullableLinkValue : number | undefined +>nullableLinks.Node?.next?.next?.value : number | undefined +>nullableLinks.Node?.next?.next : { value: number; next: any | null; } | null | undefined +>nullableLinks.Node?.next : { value: number; next: any | null; } | null | undefined +>nullableLinks.Node : { value: number; next: any | null; } | null +>nullableLinks : { Node: { value: number; next: any | null; } | null; } +>Node : { value: number; next: any | null; } | null +>next : { value: number; next: any | null; } | null | undefined +>next : { value: number; next: any | null; } | null | undefined +>value : number | undefined + +const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; +>nullishLinkValue : number | undefined +>nullishLinks.Node?.next?.next?.value : number | undefined +>nullishLinks.Node?.next?.next : { value: number; next: any | null | undefined; } | null | undefined +>nullishLinks.Node?.next : { value: number; next: any | null | undefined; } | null | undefined +>nullishLinks.Node : { value: number; next: any | null | undefined; } | null | undefined +>nullishLinks : { Node?: { value: number; next: any | null | undefined; } | null | undefined; } +>Node : { value: number; next: any | null | undefined; } | null | undefined +>next : { value: number; next: any | null | undefined; } | null | undefined +>next : { value: number; next: any | null | undefined; } | null | undefined +>value : number | undefined + +const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; +>optionalNullableLinkValue : number | undefined +>optionalNullableLinks.Node?.next?.next?.value : number | undefined +>optionalNullableLinks.Node?.next?.next : { value: number; next: any | null; } | null | undefined +>optionalNullableLinks.Node?.next : { value: number; next: any | null; } | null | undefined +>optionalNullableLinks.Node : { value: number; next: any | null; } | null | undefined +>optionalNullableLinks : { Node?: { value: number; next: any | null; } | null | undefined; } +>Node : { value: number; next: any | null; } | null | undefined +>next : { value: number; next: any | null; } | null | undefined +>next : { value: number; next: any | null; } | null | undefined +>value : number | undefined + +const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; +>nullableOptionalLinkValue : number | undefined +>nullableOptionalLinks.Node?.next?.next?.value : number | undefined +>nullableOptionalLinks.Node?.next?.next : { value: number; next: any | undefined; } | undefined +>nullableOptionalLinks.Node?.next : { value: number; next: any | undefined; } | undefined +>nullableOptionalLinks.Node : { value: number; next: any | undefined; } | null +>nullableOptionalLinks : { Node: { value: number; next: any | undefined; } | null; } +>Node : { value: number; next: any | undefined; } | null +>next : { value: number; next: any | undefined; } | undefined +>next : { value: number; next: any | undefined; } | undefined +>value : number | undefined + +const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; +>optionalNextHasNull : false +>true : true +>false : false +>false : false + +const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; +>optionalNextHasUndefined : false +>true : true +>false : false +>false : false + +const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; +>nullableNextHasNull : false +>true : true +>false : false +>false : false + +const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; +>nullableNextHasUndefined : false +>true : true +>false : false +>false : false + +const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; +>nullableLinkHasNull : true +>true : true +>false : false +>true : true + +const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; +>nullableLinkHasUndefined : false +>true : true +>false : false +>false : false + +const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; +>nullishLinkHasNull : true +>true : true +>false : false +>true : true + +const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; +>nullishLinkHasUndefined : true +>true : true +>false : false +>true : true + +const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; +>optionalNullableLinkHasNull : true +>true : true +>false : false +>true : true + +const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; +>optionalNullableLinkHasUndefined : false +>true : true +>false : false +>false : false + +const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; +>nullableOptionalLinkHasNull : false +>true : true +>false : false +>false : false + +const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; +>nullableOptionalLinkHasUndefined : true +>true : true +>false : false +>true : true + +const invalidNullNext: OptionalNode["next"] = null; +>invalidNullNext : { value: number; next: any; } + +const invalidUndefinedNext: OptionalNode["next"] = undefined; +>invalidUndefinedNext : { value: number; next: any; } +>undefined : undefined + +const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +>invalidNullableLinkValue : number +>nullableLinks.Node!.next.value : number +>nullableLinks.Node!.next : { value: number; next: any | null; } | null +>nullableLinks.Node! : { value: number; next: any | null; } +>nullableLinks.Node : { value: number; next: any | null; } | null +>nullableLinks : { Node: { value: number; next: any | null; } | null; } +>Node : { value: number; next: any | null; } | null +>next : { value: number; next: any | null; } | null +>value : number + +const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +>invalidNullishLinkValue : number +>nullishLinks.Node!.next.value : number +>nullishLinks.Node!.next : { value: number; next: any | null | undefined; } | null | undefined +>nullishLinks.Node! : { value: number; next: any | null | undefined; } +>nullishLinks.Node : { value: number; next: any | null | undefined; } | null | undefined +>nullishLinks : { Node?: { value: number; next: any | null | undefined; } | null | undefined; } +>Node : { value: number; next: any | null | undefined; } | null | undefined +>next : { value: number; next: any | null | undefined; } | null | undefined +>value : number + +=== mixedMappedCycle.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : { [K in keyof T]: T[K]; } + +type Resolve = Show<{ +>Resolve : { [P in keyof M[K]]: M[K][P] extends "ref" ? any extends infer T_1 ? { [K_1 in keyof T_1]: T_1[K_1]; } : never : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve | false | null }; +>build : () => { [K in keyof M]: Resolve | false | null; } +>false : false + +export const mixedCycle = build<{ Node: { value: number; next: "ref" } }>(); +>mixedCycle : { Node: false | { value: number; next: any; } | null; } +>build<{ Node: { value: number; next: "ref" } }>() : { Node: false | { value: number; next: any; } | null; } +>build : () => { [K in keyof M]: Resolve | false | null; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +if (mixedCycle.Node) { +>mixedCycle.Node : false | { value: number; next: any; } | null +>mixedCycle : { Node: false | { value: number; next: any; } | null; } +>Node : false | { value: number; next: any; } | null + + const value: number = mixedCycle.Node.next.next.value; +>value : number +>mixedCycle.Node.next.next.value : number +>mixedCycle.Node.next.next : { value: number; next: any; } +>mixedCycle.Node.next : { value: number; next: any; } +>mixedCycle.Node : { value: number; next: any; } +>mixedCycle : { Node: false | { value: number; next: any; } | null; } +>Node : { value: number; next: any; } +>next : { value: number; next: any; } +>next : { value: number; next: any; } +>value : number +} + +=== anonymousThisReturn.ts === +export function test() { +>test : () => { relyingOnThis(): { relyingOnThis(): any; }; } + + return { +>{ relyingOnThis() { return this; }, } : { relyingOnThis(): any; } + + relyingOnThis() { +>relyingOnThis : () => { relyingOnThis(): any; } + + return this; +>this : { relyingOnThis(): any; } + + }, + }; +} +test().relyingOnThis(); +>test().relyingOnThis() : { relyingOnThis(): any; } +>test().relyingOnThis : () => { relyingOnThis(): any; } +>test() : { relyingOnThis(): any; } +>test : () => { relyingOnThis(): { relyingOnThis(): any; }; } +>relyingOnThis : () => { relyingOnThis(): any; } + +=== recursiveConditionalAliasUtils.ts === +type Recursive = T extends Array ? Recursive : T; +>Recursive : Recursive + +export const f = (): Recursive => { +>f : () => Recursive +>(): Recursive => { return null!;} : () => Recursive + + return null!; +>null! : never + +}; + +=== recursiveConditionalAliasCopy.ts === +import { f } from "./recursiveConditionalAliasUtils"; +>f : () => T extends (infer V)[] ? V extends (infer V)[] ? any : V : T + +export const a = f; +>a : () => T extends (infer V)[] ? V extends (infer V)[] ? any : V : T +>f : () => T extends (infer V)[] ? V extends (infer V)[] ? any : V : T + +const numberValue: number = a(); +>numberValue : number +>a() : number +>a : () => T extends (infer V)[] ? V extends (infer V)[] ? any : V : T + +const stringValue: string = a(); +>stringValue : string +>a() : string +>a : () => T extends (infer V)[] ? V extends (infer V)[] ? any : V : T + +=== anonymousBindings.ts === +export const _recursive = 1; +>_recursive : 1 +>1 : 1 + +export const factory = () => function self() { return self; }; +>factory : () => () => () => any +>() => function self() { return self; } : () => () => () => any +>function self() { return self; } : () => any +>self : () => typeof self +>self : () => typeof self + +export function captured(value: T) { +>captured : (value: T) => { value: T; next: () => typeof node; consume: (other: T) => typeof node; } +>value : T + + const node = { value, next: () => node, consume: (other: T) => node }; +>node : { value: T; next: () => typeof node; consume: (other: T) => typeof node; } +>{ value, next: () => node, consume: (other: T) => node } : { value: T; next: () => typeof node; consume: (other: T) => typeof node; } +>value : T +>next : () => { value: T; next: (typeof node)["next"]; consume: (other: T) => typeof node; } +>() => node : () => { value: T; next: (typeof node)["next"]; consume: (other: T) => typeof node; } +>node : { value: T; next: () => typeof node; consume: (other: T) => typeof node; } +>consume : (other: T) => { value: T; next: () => typeof node; consume: (typeof node)["consume"]; } +>(other: T) => node : (other: T) => { value: T; next: () => typeof node; consume: (typeof node)["consume"]; } +>other : T +>node : { value: T; next: () => typeof node; consume: (other: T) => typeof node; } + + return node; +>node : { value: T; next: () => typeof node; consume: (other: T) => typeof node; } +} +export function nestedCaptured(outer: T) { +>nestedCaptured : (outer: T) => (inner: U) => { outer: T; inner: U; next: () => any; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: any; }; } +>outer : T + + return (inner: U) => { +>(inner: U) => { const node = { outer, inner, next: () => node, shadow: (value: T) => ({ outer, inner, value, next: node }), }; return node; } : (inner: U) => { outer: T; inner: U; next: () => any; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: any; }; } +>inner : U + + const node = { +>node : { outer: T; inner: U; next: () => typeof node; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: typeof node; }; } +>{ outer, inner, next: () => node, shadow: (value: T) => ({ outer, inner, value, next: node }), } : { outer: T; inner: U; next: () => typeof node; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: typeof node; }; } + + outer, +>outer : T + + inner, +>inner : U + + next: () => node, +>next : () => { outer: T; inner: U; next: (typeof node)["next"]; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: typeof node; }; } +>() => node : () => { outer: T; inner: U; next: (typeof node)["next"]; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: typeof node; }; } +>node : { outer: T; inner: U; next: () => typeof node; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: typeof node; }; } + + shadow: (value: T) => ({ outer, inner, value, next: node }), +>shadow : (value: T_1) => { outer: T; inner: U; value: T_1; next: { outer: T; inner: U; next: () => typeof node; shadow: (typeof node)["shadow"]; }; } +>(value: T) => ({ outer, inner, value, next: node }) : (value: T_1) => { outer: T; inner: U; value: T_1; next: { outer: T; inner: U; next: () => typeof node; shadow: (typeof node)["shadow"]; }; } +>value : T +>({ outer, inner, value, next: node }) : { outer: T_1; inner: U; value: T; next: { outer: T_1; inner: U; next: () => typeof node; shadow: (value: T) => any; }; } +>{ outer, inner, value, next: node } : { outer: T_1; inner: U; value: T; next: { outer: T_1; inner: U; next: () => typeof node; shadow: (value: T) => any; }; } +>outer : T_1 +>inner : U +>value : T +>next : { outer: T_1; inner: U; next: () => typeof node; shadow: (value: T) => { outer: T_1; inner: U; value: T; next: typeof node; }; } +>node : { outer: T_1; inner: U; next: () => typeof node; shadow: (value: T) => { outer: T_1; inner: U; value: T; next: typeof node; }; } + + }; + return node; +>node : { outer: T; inner: U; next: () => typeof node; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: typeof node; }; } + + }; +} +export function constrained(key: K) { +>constrained : (key: K) => { value: T[K]; next: () => typeof node; } +>value : number +>key : K + + const node = { value: null! as T[K], next: () => node }; +>node : { value: T[K]; next: () => typeof node; } +>{ value: null! as T[K], next: () => node } : { value: T[K]; next: () => typeof node; } +>value : T[K] +>null! as T[K] : T[K] +>null! : never +>next : () => { value: T[K]; next: (typeof node)["next"]; } +>() => node : () => { value: T[K]; next: (typeof node)["next"]; } +>node : { value: T[K]; next: () => typeof node; } + + return node; +>node : { value: T[K]; next: () => typeof node; } +} +export function optionalCaptured(value: T) { +>optionalCaptured : (value: T) => { node?: { value: T; next: any; } | false | null; } +>value : T + + type Node = { value: T; next: Node }; +>Node : { value: T; next: any; } +>value : T +>next : { value: T; next: any; } + + return null! as { node?: Node | false | null }; +>null! as { node?: Node | false | null } : { node?: { value: T; next: any; } | false | null; } +>null! : never +>node : false | { value: T; next: any; } | null | undefined +>false : false +} +export function annotatedCaptured(value: T) { +>annotatedCaptured : (value: T) => { value: typeof value; next: any; } +>value : T + + const node: { value: typeof value; next: typeof node } = { value, next: null! }; +>node : { value: typeof value; next: any; } +>value : T +>value : T +>next : { value: typeof value; next: any; } +>node : { value: typeof value; next: any; } +>{ value, next: null! } : { value: T; next: never; } +>value : T +>next : never +>null! : never + + return node; +>node : { value: typeof value; next: any; } +} +export function recursiveTuple(value: T) { +>recursiveTuple : (value: T) => readonly [T, any] +>value : T + + type Tuple = readonly [T, Tuple]; +>Tuple : readonly [T, any] + + return null! as Tuple; +>null! as Tuple : readonly [T, any] +>null! : never +} +export function inferredCaptured() { +>inferredCaptured : () => (T extends () => infer U ? { value: U; next: any; } : never) + + type Node = { value: V; next: Node }; +>Node : { value: V; next: any; } +>value : V +>next : { value: V; next: any; } + + return null! as (T extends () => infer U ? Node : never); +>null! as (T extends () => infer U ? Node : never) : T extends () => infer U ? { value: U; next: any; } : never +>null! : never +} +export function mappedCaptured() { +>mappedCaptured : () => { [K in keyof T]: { value: T[K]; next: any; }; } + + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; +>Node : { [K in keyof T]: { value: T[K]; next: any; }; } +>value : T[K] +>next : { [K in keyof T]: { value: T[K]; next: any; }; } + + return null! as Node; +>null! as Node : { [K in keyof T]: { value: T[K]; next: any; }; } +>null! : never +} +export function freshGeneric(unused: T) { +>freshGeneric : (unused: T) => (value: U) => typeof recur +>unused : T + + const recur = (value: U) => recur; +>recur : (value: U) => typeof recur +>(value: U) => recur : (value: U) => typeof recur +>value : U +>recur : (value: U) => typeof recur + + return recur; +>recur : (value: U) => typeof recur +} +export function mutualCaptured(left: T, right: U) { +>mutualCaptured : (left: T, right: U) => { left: { left: T; next: { right: U; self: any; next: any; }; }; right: { right: U; self: any; next: { left: T; next: any; }; }; } +>left : T +>right : U + + type Left = { left: T; next: Right }; +>Left : { left: T; next: { right: U; self: any; next: any; }; } +>left : T +>next : { right: U; self: any; next: { left: T; next: any; }; } + + type Right = { right: U; self: Right; next: Left }; +>Right : { right: U; self: any; next: { left: T; next: any; }; } +>right : U +>self : { right: U; self: any; next: { left: T; next: any; }; } +>next : { left: T; next: { right: U; self: any; next: any; }; } + + return { left: null! as Left, right: null! as Right }; +>{ left: null! as Left, right: null! as Right } : { left: { left: T; next: { right: U; self: any; next: any; }; }; right: { right: U; self: any; next: { left: T; next: any; }; }; } +>left : { left: T; next: { right: U; self: any; next: any; }; } +>null! as Left : { left: T; next: { right: U; self: any; next: any; }; } +>null! : never +>right : { right: U; self: any; next: { left: T; next: any; }; } +>null! as Right : { right: U; self: any; next: { left: T; next: any; }; } +>null! : never +} +export class CapturedClass { +>CapturedClass : CapturedClass + + constructor(public value: T) {} +>value : T + + make(inner: U) { +>make : (inner: U) => { outer: T; inner: U; next: () => typeof node; } +>inner : U + + const node = { outer: this.value, inner, next: () => node }; +>node : { outer: T; inner: U; next: () => typeof node; } +>{ outer: this.value, inner, next: () => node } : { outer: T; inner: U; next: () => typeof node; } +>outer : T +>this.value : T +>this : this +>value : T +>inner : U +>next : () => { outer: T; inner: U; next: (typeof node)["next"]; } +>() => node : () => { outer: T; inner: U; next: (typeof node)["next"]; } +>node : { outer: T; inner: U; next: () => typeof node; } + + return node; +>node : { outer: T; inner: U; next: () => typeof node; } + } +} +export function covariantClass() { +>covariantClass : () => typeof Node + + return class Node { +>class Node { value!: T; next(): Node { return this; } } : typeof Node +>Node : typeof Node + + value!: T; +>value : T + + next(): Node { return this; } +>next : () => Node +>this : this + + }; +} +export function contravariantClass() { +>contravariantClass : () => typeof Node + + return class Node { +>class Node { consume!: (value: T) => void; next(): Node { return this; } } : typeof Node +>Node : typeof Node + + consume!: (value: T) => void; +>consume : (value: T) => void +>value : T + + next(): Node { return this; } +>next : () => Node +>this : this + + }; +} +export namespace Nested { +>Nested : typeof Nested + + export function captured(value: T) { +>captured : (value: T) => { value: T; next: () => typeof node; } +>value : T + + const node = { value, next: () => node }; +>node : { value: T; next: () => typeof node; } +>{ value, next: () => node } : { value: T; next: () => typeof node; } +>value : T +>next : () => { value: T; next: (typeof node)["next"]; } +>() => node : () => { value: T; next: (typeof node)["next"]; } +>node : { value: T; next: () => typeof node; } + + return node; +>node : { value: T; next: () => typeof node; } + } +} +const capturedValue: string = captured("text").next().consume("other").value; +>capturedValue : string +>captured("text").next().consume("other").value : string +>captured("text").next().consume("other") : { value: string; next: () => any; consume: (other: string) => any; } +>captured("text").next().consume : (other: string) => { value: string; next: () => any; consume: any; } +>captured("text").next() : { value: string; next: () => any; consume: (other: string) => any; } +>captured("text").next : () => { value: string; next: any; consume: (other: string) => any; } +>captured("text") : { value: string; next: () => any; consume: (other: string) => any; } +>captured : (value: T) => { value: T; next: () => any; consume: (other: T) => any; } +>"text" : "text" +>next : () => { value: string; next: any; consume: (other: string) => any; } +>consume : (other: string) => { value: string; next: () => any; consume: any; } +>"other" : "other" +>value : string + +const nestedValue = nestedCaptured(1)("text").shadow(true).next.next(); +>nestedValue : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>nestedCaptured(1)("text").shadow(true).next.next() : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>nestedCaptured(1)("text").shadow(true).next.next : () => { outer: number; inner: string; next: any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>nestedCaptured(1)("text").shadow(true).next : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>nestedCaptured(1)("text").shadow(true) : { outer: number; inner: string; value: boolean; next: { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; }; } +>nestedCaptured(1)("text").shadow : (value: T) => { outer: number; inner: string; value: T; next: { outer: number; inner: string; next: () => any; shadow: any; }; } +>nestedCaptured(1)("text") : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>nestedCaptured(1) : (inner: U) => { outer: number; inner: U; next: () => any; shadow: (value: T) => { outer: number; inner: U; value: T; next: any; }; } +>nestedCaptured : (outer: T) => (inner: U) => { outer: T; inner: U; next: () => any; shadow: (value: T_1) => { outer: T; inner: U; value: T_1; next: any; }; } +>1 : 1 +>"text" : "text" +>shadow : (value: T) => { outer: number; inner: string; value: T; next: { outer: number; inner: string; next: () => any; shadow: any; }; } +>true : true +>next : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>next : () => { outer: number; inner: string; next: any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } + +const nestedOuter: number = nestedValue.outer; +>nestedOuter : number +>nestedValue.outer : number +>nestedValue : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>outer : number + +const nestedInner: string = nestedValue.inner; +>nestedInner : string +>nestedValue.inner : string +>nestedValue : { outer: number; inner: string; next: () => any; shadow: (value: T) => { outer: number; inner: string; value: T; next: any; }; } +>inner : string + +const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; +>constrainedValue : number +>constrained<{ value: number }, "value">("value").next().value : number +>constrained<{ value: number }, "value">("value").next() : { value: number; next: () => any; } +>constrained<{ value: number }, "value">("value").next : () => { value: number; next: any; } +>constrained<{ value: number }, "value">("value") : { value: number; next: () => any; } +>constrained : (key: K) => { value: T[K]; next: () => any; } +>value : number +>"value" : "value" +>next : () => { value: number; next: any; } +>value : number + +const annotatedValue: string = annotatedCaptured("text").next.next.value; +>annotatedValue : string +>annotatedCaptured("text").next.next.value : string +>annotatedCaptured("text").next.next : { value: string; next: any; } +>annotatedCaptured("text").next : { value: string; next: any; } +>annotatedCaptured("text") : { value: string; next: any; } +>annotatedCaptured : (value: T) => { value: typeof value; next: any; } +>"text" : "text" +>next : { value: string; next: any; } +>next : { value: string; next: any; } +>value : string + +const tupleValue: string = recursiveTuple("text")[1][1][0]; +>tupleValue : string +>recursiveTuple("text")[1][1][0] : string +>recursiveTuple("text")[1][1] : readonly [string, any] +>recursiveTuple("text")[1] : readonly [string, any] +>recursiveTuple("text") : readonly [string, any] +>recursiveTuple : (value: T) => readonly [T, any] +>"text" : "text" +>1 : 1 +>1 : 1 +>0 : 0 + +const namespaceValue: number = Nested.captured(1).next().next().value; +>namespaceValue : number +>Nested.captured(1).next().next().value : number +>Nested.captured(1).next().next() : { value: number; next: () => any; } +>Nested.captured(1).next().next : () => { value: number; next: any; } +>Nested.captured(1).next() : { value: number; next: () => any; } +>Nested.captured(1).next : () => { value: number; next: any; } +>Nested.captured(1) : { value: number; next: () => any; } +>Nested.captured : (value: T) => { value: T; next: () => any; } +>Nested : typeof Nested +>captured : (value: T) => { value: T; next: () => any; } +>1 : 1 +>next : () => { value: number; next: any; } +>next : () => { value: number; next: any; } +>value : number + +const inferredValue: string = inferredCaptured<() => string>().next.next.value; +>inferredValue : string +>inferredCaptured<() => string>().next.next.value : string +>inferredCaptured<() => string>().next.next : { value: string; next: any; } +>inferredCaptured<() => string>().next : { value: string; next: any; } +>inferredCaptured<() => string>() : { value: string; next: any; } +>inferredCaptured : () => (T extends () => infer U ? { value: U; next: any; } : never) +>next : { value: string; next: any; } +>next : { value: string; next: any; } +>value : string + +const mappedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; +>mappedValue : number +>mappedCaptured<{ value: number }>().value.next.value.value : number +>mappedCaptured<{ value: number }>().value.next.value : { value: number; next: { value: any; }; } +>mappedCaptured<{ value: number }>().value.next : { value: { value: number; next: any; }; } +>mappedCaptured<{ value: number }>().value : { value: number; next: { value: any; }; } +>mappedCaptured<{ value: number }>() : { value: { value: number; next: any; }; } +>mappedCaptured : () => { [K in keyof T]: { value: T[K]; next: any; }; } +>value : number +>value : { value: number; next: { value: any; }; } +>next : { value: { value: number; next: any; }; } +>value : { value: number; next: { value: any; }; } +>value : number + +const freshValue = freshGeneric(1)("text")(true)(2); +>freshValue : (value: U) => any +>freshGeneric(1)("text")(true)(2) : (value: U) => any +>freshGeneric(1)("text")(true) : (value: U) => any +>freshGeneric(1)("text") : (value: U) => any +>freshGeneric(1) : (value: U) => any +>freshGeneric : (unused: T) => (value: U) => any +>1 : 1 +>"text" : "text" +>true : true +>2 : 2 + +const mutualValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; +>mutualValue : string +>mutualCaptured(1, "text").left.next.self.next.next.right : string +>mutualCaptured(1, "text").left.next.self.next.next : { right: string; self: any; next: { left: number; next: any; }; } +>mutualCaptured(1, "text").left.next.self.next : { left: number; next: { right: string; self: any; next: any; }; } +>mutualCaptured(1, "text").left.next.self : { right: string; self: any; next: { left: number; next: any; }; } +>mutualCaptured(1, "text").left.next : { right: string; self: any; next: { left: number; next: any; }; } +>mutualCaptured(1, "text").left : { left: number; next: { right: string; self: any; next: any; }; } +>mutualCaptured(1, "text") : { left: { left: number; next: { right: string; self: any; next: any; }; }; right: { right: string; self: any; next: { left: number; next: any; }; }; } +>mutualCaptured : (left: T, right: U) => { left: { left: T; next: { right: U; self: any; next: any; }; }; right: { right: U; self: any; next: { left: T; next: any; }; }; } +>1 : 1 +>"text" : "text" +>left : { left: number; next: { right: string; self: any; next: any; }; } +>next : { right: string; self: any; next: { left: number; next: any; }; } +>self : { right: string; self: any; next: { left: number; next: any; }; } +>next : { left: number; next: { right: string; self: any; next: any; }; } +>next : { right: string; self: any; next: { left: number; next: any; }; } +>right : string + +const classValue: string = new CapturedClass("text").make("other").next().outer; +>classValue : string +>new CapturedClass("text").make("other").next().outer : string +>new CapturedClass("text").make("other").next() : { outer: string; inner: "other"; next: () => any; } +>new CapturedClass("text").make("other").next : () => { outer: string; inner: "other"; next: any; } +>new CapturedClass("text").make("other") : { outer: string; inner: "other"; next: () => any; } +>new CapturedClass("text").make : (inner: U) => { outer: string; inner: U; next: () => any; } +>new CapturedClass("text") : CapturedClass +>CapturedClass : typeof CapturedClass +>"text" : "text" +>make : (inner: U) => { outer: string; inner: U; next: () => any; } +>"other" : "other" +>next : () => { outer: string; inner: "other"; next: any; } +>outer : string + +const optional = optionalCaptured("text"); +>optional : { node?: false | { value: string; next: any; } | null | undefined; } +>optionalCaptured("text") : { node?: false | { value: string; next: any; } | null | undefined; } +>optionalCaptured : (value: T) => { node?: { value: T; next: any; } | false | null; } +>"text" : "text" + +if (optional.node) { +>optional.node : false | { value: string; next: any; } | null | undefined +>optional : { node?: false | { value: string; next: any; } | null | undefined; } +>node : false | { value: string; next: any; } | null | undefined + + const value: string = optional.node.next.next.value; +>value : string +>optional.node.next.next.value : string +>optional.node.next.next : { value: string; next: any; } +>optional.node.next : { value: string; next: any; } +>optional.node : { value: string; next: any; } +>optional : { node?: false | { value: string; next: any; } | null | undefined; } +>node : { value: string; next: any; } +>next : { value: string; next: any; } +>next : { value: string; next: any; } +>value : string +} +captured("text").consume(1); +>captured("text").consume(1) : { value: string; next: () => any; consume: (other: string) => any; } +>captured("text").consume : (other: string) => { value: string; next: () => any; consume: any; } +>captured("text") : { value: string; next: () => any; consume: (other: string) => any; } +>captured : (value: T) => { value: T; next: () => any; consume: (other: T) => any; } +>"text" : "text" +>consume : (other: string) => { value: string; next: () => any; consume: any; } +>1 : 1 + +const invalidTupleValue: number = recursiveTuple("text")[1][0]; +>invalidTupleValue : number +>recursiveTuple("text")[1][0] : string +>recursiveTuple("text")[1] : readonly [string, any] +>recursiveTuple("text") : readonly [string, any] +>recursiveTuple : (value: T) => readonly [T, any] +>"text" : "text" +>1 : 1 +>0 : 0 + +=== shadowedMappedCycle.ts === +type Show = { [K in keyof T]: T[K] } & unknown; +>Show : { [K in keyof T]: T[K]; } + +type Resolve = Show<{ +>Resolve : { [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T_1) => Resolve : M[K][P]; } extends infer T ? { [K_1 in keyof T]: T[K_1]; } : never + + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => Resolve : M[K][P]; +>shadowedCycle : T + +}>; +declare const build: () => { [K in keyof M]: Resolve }; +>build : () => { [K in keyof M]: Resolve; } + +export const shadowedCycle = build<{ Node: { value: number; next: "ref" } }>(); +>shadowedCycle : { Node: { value: number; next: (shadowedCycle: T) => any; }; } +>build<{ Node: { value: number; next: "ref" } }>() : { Node: { value: number; next: (shadowedCycle: T) => any; }; } +>build : () => { [K in keyof M]: Resolve; } +>Node : { value: number; next: "ref"; } +>value : number +>next : "ref" + +const shadowedValue: number = shadowedCycle.Node.next(1).next("text").value; +>shadowedValue : number +>shadowedCycle.Node.next(1).next("text").value : number +>shadowedCycle.Node.next(1).next("text") : { value: number; next: (shadowedCycle: T) => any; } +>shadowedCycle.Node.next(1).next : (shadowedCycle: T) => { value: number; next: any; } +>shadowedCycle.Node.next(1) : { value: number; next: (shadowedCycle: T) => any; } +>shadowedCycle.Node.next : (shadowedCycle: T) => { value: number; next: any; } +>shadowedCycle.Node : { value: number; next: (shadowedCycle: T) => any; } +>shadowedCycle : { Node: { value: number; next: (shadowedCycle: T) => any; }; } +>Node : { value: number; next: (shadowedCycle: T) => any; } +>next : (shadowedCycle: T) => { value: number; next: any; } +>1 : 1 +>next : (shadowedCycle: T) => { value: number; next: any; } +>"text" : "text" +>value : number + +=== globalRecursiveA.ts === +function makeA() { +>makeA : () => { value: number; self(): { value: number; self(): any; }; } + + return { +>{ value: 1, self() { return this; }, } : { value: number; self(): any; } + + value: 1, +>value : number +>1 : 1 + + self() { return this; }, +>self : () => { value: number; self(): any; } +>this : { value: number; self(): any; } + + }; +} +type makeReserved_recursive = "reserved"; +>makeReserved_recursive : "reserved" + +function makeReserved() { +>makeReserved : () => { value: boolean; self(): { value: boolean; self(): any; }; } + + return { +>{ value: true, self() { return this; }, } : { value: boolean; self(): any; } + + value: true, +>value : boolean +>true : true + + self() { return this; }, +>self : () => { value: boolean; self(): any; } +>this : { value: boolean; self(): any; } + + }; +} +class GlobalA { +>GlobalA : GlobalA + + static create(value: T) { +>create : (value: T) => { value: T; next: () => typeof node; } +>value : T + + const node = { value, next: () => node }; +>node : { value: T; next: () => typeof node; } +>{ value, next: () => node } : { value: T; next: () => typeof node; } +>value : T +>next : () => { value: T; next: (typeof node)["next"]; } +>() => node : () => { value: T; next: (typeof node)["next"]; } +>node : { value: T; next: () => typeof node; } + + return node; +>node : { value: T; next: () => typeof node; } + } + static "a-b"() { +>"a-b" : () => { value: boolean; next: () => typeof node; } + + const node = { value: true, next: () => node }; +>node : { value: boolean; next: () => typeof node; } +>{ value: true, next: () => node } : { value: boolean; next: () => typeof node; } +>value : boolean +>true : true +>next : () => { value: boolean; next: (typeof node)["next"]; } +>() => node : () => { value: boolean; next: (typeof node)["next"]; } +>node : { value: boolean; next: () => typeof node; } + + return node; +>node : { value: boolean; next: () => typeof node; } + } +} + +=== globalRecursiveB.ts === +function makeB() { +>makeB : () => { value: string; self(): { value: string; self(): any; }; } + + return { +>{ value: "text", self() { return this; }, } : { value: string; self(): any; } + + value: "text", +>value : string +>"text" : "text" + + self() { return this; }, +>self : () => { value: string; self(): any; } +>this : { value: string; self(): any; } + + }; +} +class GlobalB { +>GlobalB : GlobalB + + static create(value: T) { +>create : (value: T) => { value: T; next: () => typeof node; } +>value : T + + const node = { value, next: () => node }; +>node : { value: T; next: () => typeof node; } +>{ value, next: () => node } : { value: T; next: () => typeof node; } +>value : T +>next : () => { value: T; next: (typeof node)["next"]; } +>() => node : () => { value: T; next: (typeof node)["next"]; } +>node : { value: T; next: () => typeof node; } + + return node; +>node : { value: T; next: () => typeof node; } + } +} + diff --git a/tsc/testdata/baselines/reference/compiler/reverseMappedDeclarationSerialization.errors.txt b/tsc/testdata/baselines/reference/compiler/reverseMappedDeclarationSerialization.errors.txt index 3d014b41978e9..b8d7e315acc12 100644 --- a/tsc/testdata/baselines/reference/compiler/reverseMappedDeclarationSerialization.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/reverseMappedDeclarationSerialization.errors.txt @@ -1,4 +1,3 @@ -recursive.ts(10,14): error TS5088: The inferred type of 'recursive' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. recursive.ts(17,14): error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. recursive.ts(23,14): error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. @@ -35,7 +34,7 @@ recursive.ts(23,14): error TS7056: The inferred type of this node exceeds the ma export const deepExplicit: { a: { b: { c: { d: string } } } } = decode({ a: { b: { c: { d: stringValidator } } } }); -==== recursive.ts (3 errors) ==== +==== recursive.ts (2 errors) ==== type Validator = ((input: unknown) => T | undefined) | { [K in keyof T]: Validator; }; @@ -46,8 +45,6 @@ recursive.ts(23,14): error TS7056: The inferred type of this node exceeds the ma }; declare const recursiveInput: RecursiveInput; export const recursive = decode(recursiveInput); - ~~~~~~~~~ -!!! error TS5088: The inferred type of 'recursive' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. interface GrowingInput { value: (input: unknown) => T; diff --git a/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.errors.txt b/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.errors.txt index 230158e37d47e..109a57b0b746b 100644 --- a/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.errors.txt @@ -1,5 +1,4 @@ main.js(2,13): error TS2749: 'K' refers to a value, but is being used as a type here. Did you mean 'typeof K'? -mod1.js(7,1): error TS5088: The inferred type of 'K' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. ==== main.js (1 errors) ==== @@ -11,7 +10,7 @@ mod1.js(7,1): error TS5088: The inferred type of 'K' references a type with a cy k.values() } -==== mod1.js (1 errors) ==== +==== mod1.js (0 errors) ==== var NS = {} NS.K =class { values() { @@ -19,6 +18,4 @@ mod1.js(7,1): error TS5088: The inferred type of 'K' references a type with a cy } } exports.K = NS.K; - ~~~~~~~~~~~~~~~~ -!!! error TS5088: The inferred type of 'K' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.js b/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.js index 2e19813a3b123..7c24c1df88d64 100644 --- a/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.js +++ b/tsc/testdata/baselines/reference/conformance/commonJSImportNestedClassTypeReference.js @@ -35,5 +35,13 @@ function f(k) { } +//// [mod1.d.ts] +type K_recursive = { + values(): K_recursive; +}; +export declare var K: { + new (): K_recursive; +}; +export {}; //// [main.d.ts] export {}; diff --git a/tsc/testdata/baselines/reference/conformance/privateClassPropertyAccessibleWithinNestedClass(target=es2015).types b/tsc/testdata/baselines/reference/conformance/privateClassPropertyAccessibleWithinNestedClass(target=es2015).types index 56f726294d255..c07dc8b91c407 100644 --- a/tsc/testdata/baselines/reference/conformance/privateClassPropertyAccessibleWithinNestedClass(target=es2015).types +++ b/tsc/testdata/baselines/reference/conformance/privateClassPropertyAccessibleWithinNestedClass(target=es2015).types @@ -78,10 +78,10 @@ class C { >x : C var x1 = x.foo; ->x1 : () => any ->x.foo : () => any +>x1 : () => C["foo"] +>x.foo : () => C["foo"] >x : C ->foo : () => any +>foo : () => C["foo"] var x2 = x.bar; >x2 : () => void @@ -131,10 +131,10 @@ class C { >C : typeof C var y1 = y.foo; ->y1 : () => any ->y.foo : () => any +>y1 : () => C["foo"] +>y.foo : () => C["foo"] >y : C ->foo : () => any +>foo : () => C["foo"] var y2 = y.bar; >y2 : () => void diff --git a/tsc/testdata/baselines/reference/conformance/protectedClassPropertyAccessibleWithinNestedClass(target=es2015).types b/tsc/testdata/baselines/reference/conformance/protectedClassPropertyAccessibleWithinNestedClass(target=es2015).types index 22b9007a7b0d6..4501ee18e5cac 100644 --- a/tsc/testdata/baselines/reference/conformance/protectedClassPropertyAccessibleWithinNestedClass(target=es2015).types +++ b/tsc/testdata/baselines/reference/conformance/protectedClassPropertyAccessibleWithinNestedClass(target=es2015).types @@ -78,10 +78,10 @@ class C { >x : C var x1 = x.foo; ->x1 : () => any ->x.foo : () => any +>x1 : () => C["foo"] +>x.foo : () => C["foo"] >x : C ->foo : () => any +>foo : () => C["foo"] var x2 = x.bar; >x2 : () => void @@ -131,10 +131,10 @@ class C { >C : typeof C var y1 = y.foo; ->y1 : () => any ->y.foo : () => any +>y1 : () => C["foo"] +>y.foo : () => C["foo"] >y : C ->foo : () => any +>foo : () => C["foo"] var y2 = y.bar; >y2 : () => void diff --git a/tsc/testdata/baselines/reference/conformance/varianceAnnotations.errors.txt b/tsc/testdata/baselines/reference/conformance/varianceAnnotations.errors.txt index b47254c0503e3..c58ce8ee943af 100644 --- a/tsc/testdata/baselines/reference/conformance/varianceAnnotations.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/varianceAnnotations.errors.txt @@ -64,10 +64,9 @@ varianceAnnotations.ts(160,68): error TS2345: Argument of type 'ActionObject<{ t Types of property '_storedEvent' are incompatible. Type '{ type: "PLAY"; value: number; } | { type: "RESET"; }' is not assignable to type '{ type: "PLAY"; value: number; }'. Property 'value' is missing in type '{ type: "RESET"; }' but required in type '{ type: "PLAY"; value: number; }'. -varianceAnnotations.ts(170,5): error TS5088: The inferred type of 'OuterC' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. -==== varianceAnnotations.ts (32 errors) ==== +==== varianceAnnotations.ts (31 errors) ==== type Covariant = { x: T; } @@ -336,8 +335,6 @@ varianceAnnotations.ts(170,5): error TS5088: The inferred type of 'OuterC' refer } let OuterC = class C { - ~~~~~~ -!!! error TS5088: The inferred type of 'OuterC' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary. foo(): C { return this; } diff --git a/tsc/testdata/baselines/reference/conformance/varianceAnnotations.js b/tsc/testdata/baselines/reference/conformance/varianceAnnotations.js index 050275ef773ca..5c01c41f06429 100644 --- a/tsc/testdata/baselines/reference/conformance/varianceAnnotations.js +++ b/tsc/testdata/baselines/reference/conformance/varianceAnnotations.js @@ -212,3 +212,121 @@ let OuterC = class C { return this; } }; + + +//// [varianceAnnotations.d.ts] +type OuterC_recursive = { + foo(): OuterC_recursive; +}; +type Covariant = { + x: T; +}; +declare let super_covariant: Covariant; +declare let sub_covariant: Covariant; +type Contravariant = { + f: (x: T) => void; +}; +declare let super_contravariant: Contravariant; +declare let sub_contravariant: Contravariant; +type Invariant = { + f: (x: T) => T; +}; +declare let super_invariant: Invariant; +declare let sub_invariant: Invariant; +type T10 = T; +type T11 = keyof T; +type T12 = T[K]; +type T13 = T[keyof T]; +type Covariant1 = { + x: T; +}; +type Contravariant1 = keyof T; +type Contravariant2 = { + f: (x: T) => void; +}; +type Invariant1 = { + f: (x: T) => T; +}; +type Invariant2 = { + f: (x: T) => T; +}; +type Foo1 = { + x: T; + f: FooFn1; +}; +type FooFn1 = (foo: Bar1) => void; +type Bar1 = { + value: Foo1; +}; +type Foo2 = { + x: T; + f: FooFn2; +}; +type FooFn2 = (foo: Bar2) => void; +type Bar2 = { + value: Foo2; +}; +type Foo3 = { + x: T; + f: FooFn3; +}; +type FooFn3 = (foo: Bar3) => void; +type Bar3 = { + value: Foo3; +}; +type T20 = T; +type T21 = T; +type T22 = T; +type T23 = T; +declare function f1(x: T): void; +declare function f2(): T; +declare class C { + in a: number; + out b: number; +} +interface Baz { +} +interface Baz { +} +declare let baz1: Baz; +declare let baz2: Baz; +interface Parent { + child: Child | null; + parent: Parent | null; +} +interface Child extends Parent { + readonly a: A; + readonly b: B; +} +declare function fn(inp: Child): void; +declare const pu: Parent; +declare const notString: Parent; +declare class StateNode { + _storedEvent: TEvent; + _action: ActionObject; + _state: StateNode; +} +interface ActionObject { + exec: (meta: StateNode) => void; +} +declare function createMachine(action: ActionObject): StateNode; +declare function interpret(machine: StateNode): void; +declare const machine: StateNode; +declare const qq: ActionObject<{ + type: "PLAY"; + value: number; +}>; +declare let Anon: { + new (): { + foo(): InstanceType<(typeof Anon)>; + }; +}; +declare let OuterC: { + new (): OuterC_recursive; +}; diff --git a/tsc/testdata/baselines/reference/fourslash/quickInfo/recursiveFunctionCallQuickInfo.baseline b/tsc/testdata/baselines/reference/fourslash/quickInfo/recursiveFunctionCallQuickInfo.baseline index 408d47c5c5516..ebe00ea2286a0 100644 --- a/tsc/testdata/baselines/reference/fourslash/quickInfo/recursiveFunctionCallQuickInfo.baseline +++ b/tsc/testdata/baselines/reference/fourslash/quickInfo/recursiveFunctionCallQuickInfo.baseline @@ -107,7 +107,7 @@ // ^^^^^^^ // | ---------------------------------------------------------------------- // | ```typescript -// | const generic: (value: number) => (value: T) => typeof generic +// | const generic: (value: number) => typeof generic // | ``` // | // | (verbosity level: 0) @@ -117,7 +117,7 @@ // ^^^^^^^^^^^ // | ---------------------------------------------------------------------- // | ```typescript -// | const specialized: (value: string) => (value: T) => typeof generic +// | const specialized: (value: string) => typeof generic // | ``` // | // | (verbosity level: 0) @@ -311,7 +311,7 @@ // ^^^^^^^^^^^^^^^ // | ---------------------------------------------------------------------- // | ```typescript -// | function genericFunction(value: number): (value: T) => typeof genericFunction +// | function genericFunction(value: number): typeof genericFunction // | ``` // | // | (verbosity level: 0) @@ -892,6 +892,237 @@ // | // | (verbosity level: 0) // | ---------------------------------------------------------------------- +// type Show = { [K in keyof T]: T[K] } & unknown; +// type Resolve = Show<{ +// [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +// }>; +// declare const build: () => { [K in keyof M]: Resolve }; +// const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +// ^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const mappedCycle: { +// | Node: { +// | value: number; +// | next: ...; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 1) +// | ---------------------------------------------------------------------- +// ^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const mappedCycle: { +// | Node: { +// | value: number; +// | next: ...; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// mappedCycle.Node.next.next.value; +// ^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | (property) Node: { +// | value: number; +// | next: ...; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// ^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | (property) next: { +// | value: number; +// | next: ...; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// const nestedCycle = { wrapped: mappedCycle }; +// ^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const nestedCycle: { +// | wrapped: { +// | Node: { +// | value: number; +// | next: (typeof nestedCycle)["wrapped"]["Node"]; +// | }; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// const sharedCycles = { first: mappedCycle, second: mappedCycle }; +// ^^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const sharedCycles: { +// | first: { +// | Node: { +// | value: number; +// | next: (typeof sharedCycles)["first"]["Node"]; +// | }; +// | }; +// | second: { +// | Node: { +// | value: number; +// | next: (typeof sharedCycles)["second"]["Node"]; +// | }; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// declare const buildOptional: () => { [K in keyof M]?: Resolve }; +// declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +// const optionalBox = { cycle: buildOptional<{ Node: { value: number; next: "ref" } }>() }; +// ^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const optionalBox: { +// | cycle: { +// | Node?: { +// | value: number; +// | next: ...; +// | } | undefined; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 1) +// | ---------------------------------------------------------------------- +// ^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const optionalBox: { +// | cycle: { +// | Node?: { +// | value: number; +// | next: ...; +// | } | undefined; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// const nullableBox = { cycle: buildNullable<{ Node: { value: number; next: "ref" } }>() }; +// ^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const nullableBox: { +// | cycle: { +// | Node: { +// | value: number; +// | next: ...; +// | } | null; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// type ResolveNullable = Show<{ +// [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +// }>; +// declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +// const nullableLinkBox = { cycle: buildNullableLinks<{ Node: { value: number; next: "ref" } }>() }; +// ^^^^^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const nullableLinkBox: { +// | cycle: { +// | Node: { +// | value: number; +// | next: (typeof nullableLinkBox)["cycle"]["Node"]; +// | } | null; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// function captured(value: T) { +// const node = { value, next: () => node }; +// return node; +// } +// const capturedValue = captured(1); +// ^^^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const capturedValue: { +// | value: number; +// | next: () => ...; +// | } +// | ``` +// | +// | (verbosity level: 1) +// | ---------------------------------------------------------------------- +// ^^^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const capturedValue: { +// | value: number; +// | next: () => ...; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// capturedValue.next(); +// ^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | (property) next: () => { +// | value: number; +// | next: () => ...; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// function inferredCaptured() { +// type Node = { value: V; next: Node }; +// return null! as (T extends () => infer U ? Node : never); +// } +// const inferredValue = inferredCaptured<() => string>(); +// ^^^^^^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const inferredValue: Node +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- +// declare const buildMixed: () => { [K in keyof M]?: Resolve | false | null }; +// const mixedBox = { cycle: buildMixed<{ Node: { value: number; next: "ref" } }>() }; +// ^^^^^^^^ +// | ---------------------------------------------------------------------- +// | ```typescript +// | const mixedBox: { +// | cycle: { +// | Node?: false | { +// | value: number; +// | next: ...; +// | } | null | undefined; +// | }; +// | } +// | ``` +// | +// | (verbosity level: 0) +// | ---------------------------------------------------------------------- [ { "marker": { @@ -1267,7 +1498,7 @@ "hover": { "contents": { "kind": "markdown", - "value": "```typescript\nconst generic: (value: number) => (value: T) => typeof generic\n```\n" + "value": "```typescript\nconst generic: (value: number) => typeof generic\n```\n" }, "range": { "start": { @@ -1297,7 +1528,7 @@ "hover": { "contents": { "kind": "markdown", - "value": "```typescript\nconst specialized: (value: string) => (value: T) => typeof generic\n```\n" + "value": "```typescript\nconst specialized: (value: string) => typeof generic\n```\n" }, "range": { "start": { @@ -1957,7 +2188,7 @@ "hover": { "contents": { "kind": "markdown", - "value": "```typescript\nfunction genericFunction(value: number): (value: T) => typeof genericFunction\n```\n" + "value": "```typescript\nfunction genericFunction(value: number): typeof genericFunction\n```\n" }, "range": { "start": { @@ -2692,5 +2923,456 @@ }, "verbosityLevel": 0 } + }, + { + "marker": { + "Position": 2725, + "LSPosition": { + "line": 81, + "character": 17 + }, + "Name": "mappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst mappedCycle: {\n Node: {\n value: number;\n next: ...;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 81, + "character": 6 + }, + "end": { + "line": 81, + "character": 17 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 2725, + "LSPosition": { + "line": 81, + "character": 17 + }, + "Name": "mappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst mappedCycle: {\n Node: {\n value: number;\n next: ...;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 81, + "character": 6 + }, + "end": { + "line": 81, + "character": 17 + } + } + }, + "verbosityLevel": 1 + } + }, + { + "marker": { + "Position": 2795, + "LSPosition": { + "line": 82, + "character": 16 + }, + "Name": "mappedNode", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\n(property) Node: {\n value: number;\n next: ...;\n}\n```\n" + }, + "range": { + "start": { + "line": 82, + "character": 12 + }, + "end": { + "line": 82, + "character": 16 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 2800, + "LSPosition": { + "line": 82, + "character": 21 + }, + "Name": "mappedNext", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\n(property) next: {\n value: number;\n next: ...;\n}\n```\n" + }, + "range": { + "start": { + "line": 82, + "character": 17 + }, + "end": { + "line": 82, + "character": 21 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 2830, + "LSPosition": { + "line": 83, + "character": 17 + }, + "Name": "nestedMappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst nestedCycle: {\n wrapped: {\n Node: {\n value: number;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 83, + "character": 6 + }, + "end": { + "line": 83, + "character": 17 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 2877, + "LSPosition": { + "line": 84, + "character": 18 + }, + "Name": "sharedMappedCycles", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 84, + "character": 6 + }, + "end": { + "line": 84, + "character": 18 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 3096, + "LSPosition": { + "line": 87, + "character": 17 + }, + "Name": "optionalMappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst optionalBox: {\n cycle: {\n Node?: {\n value: number;\n next: ...;\n } | undefined;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 87, + "character": 6 + }, + "end": { + "line": 87, + "character": 17 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 3096, + "LSPosition": { + "line": 87, + "character": 17 + }, + "Name": "optionalMappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst optionalBox: {\n cycle: {\n Node?: {\n value: number;\n next: ...;\n } | undefined;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 87, + "character": 6 + }, + "end": { + "line": 87, + "character": 17 + } + } + }, + "verbosityLevel": 1 + } + }, + { + "marker": { + "Position": 3186, + "LSPosition": { + "line": 88, + "character": 17 + }, + "Name": "nullableMappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst nullableBox: {\n cycle: {\n Node: {\n value: number;\n next: ...;\n } | null;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 88, + "character": 6 + }, + "end": { + "line": 88, + "character": 17 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 3516, + "LSPosition": { + "line": 93, + "character": 21 + }, + "Name": "nullableMappedLinks", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst nullableLinkBox: {\n cycle: {\n Node: {\n value: number;\n next: (typeof nullableLinkBox)[\"cycle\"][\"Node\"];\n } | null;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 93, + "character": 6 + }, + "end": { + "line": 93, + "character": 21 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 3711, + "LSPosition": { + "line": 98, + "character": 19 + }, + "Name": "capturedValue", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst capturedValue: {\n value: number;\n next: () => ...;\n}\n```\n" + }, + "range": { + "start": { + "line": 98, + "character": 6 + }, + "end": { + "line": 98, + "character": 19 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 3711, + "LSPosition": { + "line": 98, + "character": 19 + }, + "Name": "capturedValue", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst capturedValue: {\n value: number;\n next: () => ...;\n}\n```\n" + }, + "range": { + "start": { + "line": 98, + "character": 6 + }, + "end": { + "line": 98, + "character": 19 + } + } + }, + "verbosityLevel": 1 + } + }, + { + "marker": { + "Position": 3745, + "LSPosition": { + "line": 99, + "character": 18 + }, + "Name": "capturedNext", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\n(property) next: () => {\n value: number;\n next: () => ...;\n}\n```\n" + }, + "range": { + "start": { + "line": 99, + "character": 14 + }, + "end": { + "line": 99, + "character": 18 + } + } + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 3916, + "LSPosition": { + "line": 104, + "character": 19 + }, + "Name": "inferredCapturedValue", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst inferredValue: Node\n```\n" + }, + "range": { + "start": { + "line": 104, + "character": 6 + }, + "end": { + "line": 104, + "character": 19 + } + }, + "canIncreaseVerbosity": true + }, + "verbosityLevel": 0 + } + }, + { + "marker": { + "Position": 4053, + "LSPosition": { + "line": 106, + "character": 14 + }, + "Name": "mixedMappedCycle", + "Data": {} + }, + "item": { + "hover": { + "contents": { + "kind": "markdown", + "value": "```typescript\nconst mixedBox: {\n cycle: {\n Node?: false | {\n value: number;\n next: ...;\n } | null | undefined;\n };\n}\n```\n" + }, + "range": { + "start": { + "line": 106, + "character": 6 + }, + "end": { + "line": 106, + "character": 14 + } + } + }, + "verbosityLevel": 0 + } } ] \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-function-declaration-consumption.js b/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-function-declaration-consumption.js index c5570226917f7..bb2229caa2f59 100644 --- a/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-function-declaration-consumption.js +++ b/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-function-declaration-consumption.js @@ -2,6 +2,7 @@ currentDirectory::/home/src/workspaces/project useCaseSensitiveFileNames::true Input:: //// [/home/src/workspaces/project/consumer/index.ts] *new* +import { conditionalAliasCopy, anonymousThisReturn } from "../producer/dist/index.js"; import { arrow, expression, first, generic, objectReturn, tupleReturn, shadowed } from "../producer/dist/index.js"; import { object, method, accessor, tuple, array, nested } from "../producer/dist/index.js"; import { memberTuple, memberArray, quoted, numeric, key, computed, union, specialized } from "../producer/dist/index.js"; @@ -9,6 +10,13 @@ import { indexed, mapped, viaAnnotation } from "../producer/dist/index.js"; import { nextLink, nextCallable, parenthesized, asserted, Methods, overloaded } from "../producer/dist/index.js"; import { hiddenAlias, siblingHiddenAliases } from "../producer/dist/index.js"; import { nestedNumber } from "../producer/dist/index.js"; +import { mappedCycle, mappedCycleCopy, nestedCycle, cycleKey, keyedCycles, sharedCycles, mutualCycle, shadowedCycle } from "../producer/dist/index.js"; +import { optionalCycle, nullableCycle, mixedCycles, sharedOptionalCycles, nullableKeys, nullableRoot, optionalRoot, nullableLinks, nullishLinks } from "../producer/dist/index.js"; +import { optionalNullableLinks, nullableOptionalLinks } from "../producer/dist/index.js"; +import { mixedUnionCycle, factory, captured, nestedCaptured, constrained, optionalCaptured, annotatedCaptured, recursiveTuple, Nested } from "../producer/dist/index.js"; +import { inferredCaptured, mappedCaptured, freshGeneric, mutualCaptured } from "../producer/dist/index.js"; +import { CapturedClass } from "../producer/dist/index.js"; +import { covariantClass, contravariantClass } from "../producer/dist/index.js"; const a: typeof arrow = arrow()()(); const b: typeof expression = expression()()(); const c: typeof first = first()()(); @@ -56,9 +64,109 @@ const copiedOuter: number = nestedNumber.copied("inner").outer; const copiedInner: string = nestedNumber.copied("inner").inner; const restOuter: number = nestedNumber.rest(true).outer; const restInner: boolean = nestedNumber.rest(true).inner; +const mappedCycleValue: number = mappedCycle.Node.next.next.value; +const copiedMappedValue: number = mappedCycleCopy.Node.next.next.value; +const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; +const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; +const numericMappedValue: boolean = keyedCycles[0].next.next.value; +const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; +const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; +const mutualFirstValue: number = mutualCycle.First.next.next.value; +const mutualSecondValue: string = mutualCycle.First.next.value; +const shadowedMappedValue: number = shadowedCycle.Node.next(1).next("text").value; +const optionalCycleValue: number | undefined = optionalCycle.Node?.next.next.value; +const nullableCycleValue: string | undefined = nullableCycle.Node?.next.next.value; +const mixedCycleValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; +const mixedRequiredValue: number | undefined = mixedCycles.required.Node?.next.next.value; +const sharedOptionalValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; +const quotedNullableValue: string | undefined = nullableKeys["a-b"]?.next.next.value; +const numericNullableValue: boolean | undefined = nullableKeys[0]?.next.next.value; +const symbolNullableValue: number | undefined = nullableKeys[cycleKey]?.next.next.value; +const nullableRootValue: number | undefined = nullableRoot?.next.next.value; +const optionalRootValue: string | undefined = optionalRoot?.next.next.value; +const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; +const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; +const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; +const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; +type OptionalNode = (typeof optionalCycle)["Node"] & {}; +type NullableNode = (typeof nullableCycle)["Node"] & {}; +type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; +type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; +type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; +type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; +const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; +const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; +const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; +const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; +const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; +const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; +const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; +const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; +const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; +const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; +const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; +const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; type IsAny = 0 extends (1 & T) ? true : false; +const anonymousThisResult = anonymousThisReturn().relyingOnThis().relyingOnThis(); +const anonymousThisNotAny: IsAny = false; +const anonymousThisMethodNotAny: IsAny = false; +const conditionalAliasResult = conditionalAliasCopy(); +const conditionalNumber: number = conditionalAliasResult; +const conditionalString: string = conditionalAliasCopy(); +const conditionalNotAny: IsAny = false; const result = arrow()()(); const notAny: false = null as unknown as IsAny; +const mappedNotAny: false = null as unknown as IsAny; +const mutualNotAny: false = null as unknown as IsAny; +const shadowedMappedNotAny: false = null as unknown as IsAny; +const optionalNotAny: IsAny = false; +const nullableNotAny: IsAny = false; +const nullableLinkNotAny: IsAny = false; +const nullishLinkNotAny: IsAny = false; +const optionalNullableLinkNotAny: IsAny = false; +const nullableOptionalLinkNotAny: IsAny = false; +const factoryResult = factory()()()(); +const factoryNotAny: IsAny = false; +const capturedValue: string = captured("text").next().consume("other").value; +const capturedResult = captured("text").next(); +const capturedNotAny: IsAny = false; +const nestedCapturedValue = nestedCaptured(1)("text").shadow(true).next.next(); +const capturedOuter: number = nestedCapturedValue.outer; +const capturedInner: string = nestedCapturedValue.inner; +const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; +const annotatedCapturedValue: string = annotatedCaptured("text").next.next.value; +const recursiveTupleValue: string = recursiveTuple("text")[1][1][0]; +const namespaceValue: number = Nested.captured(1).next().next().value; +const inferredCapturedValue: string = inferredCaptured<() => string>().next.next.value; +const mappedCapturedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; +const freshGenericValue = freshGeneric(1)("text")(true)(2); +const freshGenericNotAny: IsAny = false; +const mutualCapturedValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; +const mutualCapturedResult = mutualCaptured(1, "text").right.self.next.left; +const mutualCapturedNotAny: IsAny = false; +const capturedClassResult = new CapturedClass("text").make("other").next(); +const capturedClassOuter: string = capturedClassResult.outer; +const capturedClassInner: string = capturedClassResult.inner; +const capturedClassNotAny: IsAny = false; +const Covariant = covariantClass(); +const covariantString = new Covariant(); +const covariantUnknown = new Covariant(); +const covariantWide: typeof covariantUnknown = covariantString.next(); +const covariantNotAny: IsAny = false; +const Contravariant = contravariantClass(); +const contravariantString = new Contravariant(); +const contravariantUnknown = new Contravariant(); +const contravariantNarrow: typeof contravariantString = contravariantUnknown.next(); +const contravariantNotAny: IsAny = false; +const optionalCapturedValue = optionalCaptured("text"); +if (optionalCapturedValue.node) { + const value: string = optionalCapturedValue.node.next.next.value; + const notAny: IsAny = false; +} +if (mixedUnionCycle.Node) { + const value: number = mixedUnionCycle.Node.next.next.value; + const notAny: IsAny = false; +} const invalid: number = arrow()()(); const invalidExpression: number = expression()()(); const invalidObject: number = objectReturn().call; @@ -77,12 +185,44 @@ const invalidComputedMethod: number = Methods[key]()(); const invalidNestedOuter: boolean = nestedString.outer; const invalidNestedInner: string = nestedString.inner; nestedNumber.constrained("wrong"); +const invalidMappedCycleValue: string = mappedCycle.Node.next.next.value; +const invalidMutualCycleValue: number = mutualCycle.First.next.value; +const invalidShadowedMappedValue: string = shadowedCycle.Node.next(1).next("text").value; +const invalidNullNext: OptionalNode["next"] = null; +const invalidUndefinedNext: OptionalNode["next"] = undefined; +const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +captured("text").consume(1); +const invalidRecursiveTupleValue: number = recursiveTuple("text")[1][0]; +const invalidCapturedOuter: string = nestedCapturedValue.outer; +const invalidCapturedInner: number = nestedCapturedValue.inner; +type WithoutFalseOrNullish = T extends false | null | undefined ? never : T; +const invalidMixedNext: WithoutFalseOrNullish["next"] = false; +const invalidInferredCapturedValue: number = inferredCaptured<() => string>().next.value; +const invalidMappedCapturedValue: string = mappedCaptured<{ value: number }>().value.next.value.value; +const invalidMutualCapturedValue: boolean = mutualCaptured(1, "text").right.self.next.left; +const invalidCapturedClassValue: number = capturedClassResult.outer; +const invalidCovariance: typeof covariantString = covariantUnknown.next(); +const invalidContravariance: typeof contravariantUnknown = contravariantString.next(); +const invalidAnonymousThis: number = anonymousThisResult; +const invalidAnonymousThisMethod: number = anonymousThisResult.relyingOnThis; +const invalidConditionalAlias: string = conditionalAliasResult; +const invalidConditionalAliasArray: number[] = conditionalAliasResult; //// [/home/src/workspaces/project/consumer/tsconfig.json] *new* { - "compilerOptions": { "strict": true, "noEmit": true }, + "compilerOptions": { "strict": true, "exactOptionalPropertyTypes": true, "noEmit": true }, "references": [{ "path": "../producer" }] } //// [/home/src/workspaces/project/producer/index.ts] *new* +import { f } from "./recursive-conditional-utils"; +export const conditionalAliasCopy = f; +export function anonymousThisReturn() { + return { + relyingOnThis() { + return this; + }, + }; +} export const arrow = () => arrow; export const expression = function self() { return self; }; export const first = () => second; @@ -160,106 +300,360 @@ export const nestedOwner = { }, }; export const nestedNumber = nestedOwner.make(1); +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; +export const cycleKey = Symbol(); +export const keyedCycles = build<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; +}>(); +export const sharedCycles = { first: mappedCycle, second: mappedCycle }; +type ResolveMutual = Show<{ + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; +}>; +declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; +export const mutualCycle = buildMutual<{ + First: { value: number; next: { ref: "Second" } }; + Second: { value: string; next: { ref: "First" } }; +}>(); +type ResolveShadowed = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => ResolveShadowed : M[K][P]; +}>; +declare const buildShadowed: () => { [K in keyof M]: ResolveShadowed }; +export const shadowedCycle = buildShadowed<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptional: () => { [K in keyof M]?: Resolve }; +export const optionalCycle = buildOptional<{ Node: { value: number; next: "ref" } }>(); +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); +declare const wrap: (value: T) => { required: T; optional?: T | null }; +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKeys = buildNullable<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; +}>(); +declare const buildNullableRoot: () => Resolve | null; +export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalRoot: () => Resolve | undefined; +export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); +type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; +export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveOptional = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; +}>; +declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; +export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveNullish = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; +}>; +declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; +export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); +declare const buildMixed: () => { [K in keyof M]?: Resolve | false | null }; +export const mixedUnionCycle = buildMixed<{ Node: { value: number; next: "ref" } }>(); +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value: T) { + const node = { value, next: () => node, consume: (other: T) => node }; + return node; +} +export function nestedCaptured(outer: T) { + return (inner: U) => { + const node = { + outer, inner, next: () => node, + shadow: (value: T) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key: K) { + const node = { value: null! as T[K], next: () => node }; + return node; +} +export function optionalCaptured(value: T) { + type Node = { value: T; next: Node }; + return null! as { node?: Node | false | null }; +} +export function annotatedCaptured(value: T) { + const node: { value: typeof value; next: typeof node } = { value, next: null! }; + return node; +} +export function recursiveTuple(value: T) { + type Tuple = readonly [T, Tuple]; + return null! as Tuple; +} +export function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); +} +export function mappedCaptured() { + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; + return null! as Node; +} +export function freshGeneric(unused: T) { + const recur = (value: U) => recur; + return recur; +} +export function mutualCaptured(left: T, right: U) { + type Left = { left: T; next: Right }; + type Right = { right: U; self: Right; next: Left }; + return { left: null! as Left, right: null! as Right }; +} +export class CapturedClass { + constructor(public value: T) {} + make(inner: U) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value!: T; + next(): Node { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume!: (value: T) => void; + next(): Node { return this; } + }; +} +export namespace Nested { + export function captured(value: T) { + const node = { value, next: () => node }; + return node; + } +} +type NonNullable = "shadowed"; +//// [/home/src/workspaces/project/producer/recursive-conditional-utils.ts] *new* +type Recursive = T extends Array ? Recursive : T; +export const f = (): Recursive => { + return null!; +}; //// [/home/src/workspaces/project/producer/tsconfig.json] *new* { - "compilerOptions": { "strict": true, "composite": true, "outDir": "dist" } + "compilerOptions": { "strict": true, "exactOptionalPropertyTypes": true, "composite": true, "outDir": "dist" } } tsgo --build consumer ExitStatus:: DiagnosticsPresent_OutputsGenerated Output:: -consumer/index.ts:58:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +consumer/index.ts:166:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +166 const invalid: number = arrow()()(); +   ~~~~~~~ + +consumer/index.ts:167:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +167 const invalidExpression: number = expression()()(); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:168:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. + +168 const invalidObject: number = objectReturn().call; +   ~~~~~~~~~~~~~ + +consumer/index.ts:169:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. + +169 const invalidTuple: number = tupleReturn()[0]; +   ~~~~~~~~~~~~ + +consumer/index.ts:170:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. + +170 const invalidShadowed: number = shadowed(1); +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:171:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +171 const invalidObjectValue: string = object.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:172:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. + +172 const invalidTupleValue: number = tuple[0](); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:173:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +173 const invalidSpecialized: number = specialized.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:174:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. + +174 const invalidMapped: number = mapped.next; +   ~~~~~~~~~~~~~ + +consumer/index.ts:175:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +175 const invalidAnnotation: number = viaAnnotation.next().value; +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:176:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +176 const invalidLink: number = nextLink.next.value; +   ~~~~~~~~~~~ + +consumer/index.ts:177:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +177 const invalidCallable: string = nextCallable(1).link.value; +   ~~~~~~~~~~~~~~~ -58 const invalid: number = arrow()()(); -   ~~~~~~~ +consumer/index.ts:178:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:59:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +178 const invalidHiddenValue: number = hiddenAlias.next.next.value; +   ~~~~~~~~~~~~~~~~~~ -59 const invalidExpression: number = expression()()(); -   ~~~~~~~~~~~~~~~~~ +consumer/index.ts:179:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. -consumer/index.ts:60:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. +179 const invalidMethod: number = Methods.recur()(); +   ~~~~~~~~~~~~~ -60 const invalidObject: number = objectReturn().call; -   ~~~~~~~~~~~~~ +consumer/index.ts:180:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. -consumer/index.ts:61:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. +180 const invalidComputedMethod: number = Methods[key]()(); +   ~~~~~~~~~~~~~~~~~~~~~ -61 const invalidTuple: number = tupleReturn()[0]; -   ~~~~~~~~~~~~ +consumer/index.ts:181:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. -consumer/index.ts:62:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. +181 const invalidNestedOuter: boolean = nestedString.outer; +   ~~~~~~~~~~~~~~~~~~ -62 const invalidShadowed: number = shadowed(1); -   ~~~~~~~~~~~~~~~ +consumer/index.ts:182:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:63:7 - error TS2322: Type 'number' is not assignable to type 'string'. +182 const invalidNestedInner: string = nestedString.inner; +   ~~~~~~~~~~~~~~~~~~ -63 const invalidObjectValue: string = object.next().value; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:183:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -consumer/index.ts:64:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. +183 nestedNumber.constrained("wrong"); +   ~~~~~~~ -64 const invalidTupleValue: number = tuple[0](); -   ~~~~~~~~~~~~~~~~~ +consumer/index.ts:184:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:65:7 - error TS2322: Type 'string' is not assignable to type 'number'. +184 const invalidMappedCycleValue: string = mappedCycle.Node.next.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -65 const invalidSpecialized: number = specialized.next().value; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:185:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:66:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. +185 const invalidMutualCycleValue: number = mutualCycle.First.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -66 const invalidMapped: number = mapped.next; -   ~~~~~~~~~~~~~ +consumer/index.ts:186:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:67:7 - error TS2322: Type 'string' is not assignable to type 'number'. +186 const invalidShadowedMappedValue: string = shadowedCycle.Node.next(1).next("text").value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -67 const invalidAnnotation: number = viaAnnotation.next().value; -   ~~~~~~~~~~~~~~~~~ +consumer/index.ts:187:7 - error TS2322: Type 'null' is not assignable to type 'optionalCycle_recursive'. -consumer/index.ts:68:7 - error TS2322: Type 'string' is not assignable to type 'number'. +187 const invalidNullNext: OptionalNode["next"] = null; +   ~~~~~~~~~~~~~~~ -68 const invalidLink: number = nextLink.next.value; -   ~~~~~~~~~~~ +consumer/index.ts:188:7 - error TS2322: Type 'undefined' is not assignable to type 'optionalCycle_recursive'. -consumer/index.ts:69:7 - error TS2322: Type 'number' is not assignable to type 'string'. +188 const invalidUndefinedNext: OptionalNode["next"] = undefined; +   ~~~~~~~~~~~~~~~~~~~~ -69 const invalidCallable: string = nextCallable(1).link.value; -   ~~~~~~~~~~~~~~~ +consumer/index.ts:189:42 - error TS2531: Object is possibly 'null'. -consumer/index.ts:70:7 - error TS2322: Type 'string' is not assignable to type 'number'. +189 const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~ -70 const invalidHiddenValue: number = hiddenAlias.next.next.value; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:190:41 - error TS2533: Object is possibly 'null' or 'undefined'. -consumer/index.ts:71:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. +190 const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -71 const invalidMethod: number = Methods.recur()(); -   ~~~~~~~~~~~~~ +consumer/index.ts:191:26 - error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -consumer/index.ts:72:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. +191 captured("text").consume(1); +   ~ -72 const invalidComputedMethod: number = Methods[key]()(); -   ~~~~~~~~~~~~~~~~~~~~~ +consumer/index.ts:192:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:73:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. +192 const invalidRecursiveTupleValue: number = recursiveTuple("text")[1][0]; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -73 const invalidNestedOuter: boolean = nestedString.outer; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:193:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:74:7 - error TS2322: Type 'number' is not assignable to type 'string'. +193 const invalidCapturedOuter: string = nestedCapturedValue.outer; +   ~~~~~~~~~~~~~~~~~~~~ -74 const invalidNestedInner: string = nestedString.inner; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:194:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:75:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +194 const invalidCapturedInner: number = nestedCapturedValue.inner; +   ~~~~~~~~~~~~~~~~~~~~ -75 nestedNumber.constrained("wrong"); -   ~~~~~~~ +consumer/index.ts:196:7 - error TS2322: Type 'boolean' is not assignable to type 'mixedUnionCycle_recursive'. +196 const invalidMixedNext: WithoutFalseOrNullish["next"] = false; +   ~~~~~~~~~~~~~~~~ -Found 18 errors in the same file, starting at: consumer/index.ts:58 +consumer/index.ts:197:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +197 const invalidInferredCapturedValue: number = inferredCaptured<() => string>().next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:198:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +198 const invalidMappedCapturedValue: string = mappedCaptured<{ value: number }>().value.next.value.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:199:7 - error TS2322: Type 'number' is not assignable to type 'boolean'. + +199 const invalidMutualCapturedValue: boolean = mutualCaptured(1, "text").right.self.next.left; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:200:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +200 const invalidCapturedClassValue: number = capturedClassResult.outer; +   ~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:201:7 - error TS2322: Type 'covariantClass_recursive' is not assignable to type 'covariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. + +201 const invalidCovariance: typeof covariantString = covariantUnknown.next(); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:202:7 - error TS2322: Type 'contravariantClass_recursive' is not assignable to type 'contravariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. + +202 const invalidContravariance: typeof contravariantUnknown = contravariantString.next(); +   ~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:203:7 - error TS2322: Type 'anonymousThisReturn_recursive' is not assignable to type 'number'. + +203 const invalidAnonymousThis: number = anonymousThisResult; +   ~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:204:7 - error TS2322: Type '() => anonymousThisReturn_recursive' is not assignable to type 'number'. + +204 const invalidAnonymousThisMethod: number = anonymousThisResult.relyingOnThis; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:205:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +205 const invalidConditionalAlias: string = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:206:7 - error TS2322: Type 'number' is not assignable to type 'number[]'. + +206 const invalidConditionalAliasArray: number[] = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Found 40 errors in the same file, starting at: consumer/index.ts:166 //// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib* /// @@ -301,6 +695,129 @@ declare const console: { log(msg: any): void; }; "semanticErrors": true } //// [/home/src/workspaces/project/producer/dist/index.d.ts] *new* +type anonymousThisReturn_recursive = { + relyingOnThis(): anonymousThisReturn_recursive; +}; +type optionalCycle_recursive = { + value: number; + next: optionalCycle_recursive; +}; +type nullableCycle_recursive = { + value: string; + next: nullableCycle_recursive; +}; +type mixedCycles_recursive = { + value: number; + next: mixedCycles_recursive; +}; +type sharedOptionalCycles_recursive = { + value: number; + next: sharedOptionalCycles_recursive; +}; +type nullableKeys_recursive = { + value: string; + next: nullableKeys_recursive; +}; +type nullableKeys_recursive_1 = { + value: boolean; + next: nullableKeys_recursive_1; +}; +type nullableKeys_recursive_2 = { + value: number; + next: nullableKeys_recursive_2; +}; +type nullableRoot_recursive = { + value: number; + next: nullableRoot_recursive; +}; +type optionalRoot_recursive = { + value: string; + next: optionalRoot_recursive; +}; +type optionalNullableLinks_recursive = { + value: number; + next: optionalNullableLinks_recursive | null; +}; +type nullableOptionalLinks_recursive = { + value: number; + next: nullableOptionalLinks_recursive | undefined; +}; +type nullishLinks_recursive = { + value: number; + next: nullishLinks_recursive | null | undefined; +}; +type mixedUnionCycle_recursive = { + value: number; + next: mixedUnionCycle_recursive; +}; +type factory_recursive = () => factory_recursive; +type captured_recursive = { + value: T; + next: () => captured_recursive; + consume: (other: T) => captured_recursive; +}; +type nestedCaptured_recursive = { + outer: T; + inner: U; + next: () => nestedCaptured_recursive; + shadow: (value: T_1) => { + outer: T; + inner: U; + value: T_1; + next: nestedCaptured_recursive; + }; +}; +type constrained_recursive = { + value: T[K]; + next: () => constrained_recursive; +}; +type optionalCaptured_recursive = { + value: T; + next: optionalCaptured_recursive; +}; +type annotatedCaptured_recursive = { + value: T; + next: annotatedCaptured_recursive; +}; +type recursiveTuple_recursive = readonly [T, recursiveTuple_recursive]; +type inferredCaptured_recursive = { + value: U; + next: inferredCaptured_recursive; +}; +type mappedCaptured_recursive = { [K in keyof T]: { + value: T[K]; + next: mappedCaptured_recursive; +}; }; +type freshGeneric_recursive = (value: U) => freshGeneric_recursive; +type mutualCaptured_recursive = { + right: U; + self: mutualCaptured_recursive; + next: mutualCaptured_recursive_1; +}; +type mutualCaptured_recursive_1 = { + left: T; + next: mutualCaptured_recursive; +}; +type CapturedClass_make_recursive = { + outer: T; + inner: U; + next: () => CapturedClass_make_recursive; +}; +type covariantClass_recursive = { + value: T; + next(): covariantClass_recursive; +}; +type contravariantClass_recursive = { + consume: (value: T) => void; + next(): contravariantClass_recursive; +}; +import { f } from "./recursive-conditional-utils"; +export declare const conditionalAliasCopy: typeof f; +export declare function anonymousThisReturn(): { + relyingOnThis(): anonymousThisReturn_recursive; +}; export declare const arrow: () => typeof arrow; export declare const expression: () => typeof expression; export declare const first: () => typeof second; @@ -332,13 +849,13 @@ export declare const nested: { }; }; }; -export declare const memberTuple: readonly [() => (typeof memberTuple)[0]]; +export declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]]; export declare const memberArray: (() => (typeof memberArray)[0])[]; export declare const quoted: { - "a-b": () => (typeof quoted)["a-b"]; + "a-b": () => () => (typeof quoted)["a-b"]; }; export declare const numeric: { - 0: () => (typeof numeric)[0]; + 0: () => () => (typeof numeric)[0]; }; export declare const key: unique symbol; export declare const computed: { @@ -512,8 +1029,174 @@ export declare const nestedNumber: { }; }; }; +export declare const mappedCycle: { + Node: { + value: number; + next: (typeof mappedCycle)["Node"]; + }; +}; +export declare const mappedCycleCopy: { + Node: { + value: number; + next: (typeof mappedCycleCopy)["Node"]; + }; +}; +export declare const nestedCycle: { + wrapped: { + Node: { + value: string; + next: (typeof nestedCycle)["wrapped"]["Node"]; + }; + }; +}; +export declare const cycleKey: unique symbol; +export declare const keyedCycles: { + "a-b": { + value: string; + next: (typeof keyedCycles)["a-b"]; + }; + 0: { + value: boolean; + next: (typeof keyedCycles)[0]; + }; + [cycleKey]: { + value: number; + next: (typeof keyedCycles)[typeof cycleKey]; + }; +}; +export declare const sharedCycles: { + first: { + Node: { + value: number; + next: (typeof sharedCycles)["first"]["Node"]; + }; + }; + second: { + Node: { + value: number; + next: (typeof sharedCycles)["second"]["Node"]; + }; + }; +}; +export declare const mutualCycle: { + First: { + value: number; + next: { + value: string; + next: (typeof mutualCycle)["First"]; + }; + }; + Second: { + value: string; + next: { + value: number; + next: (typeof mutualCycle)["Second"]; + }; + }; +}; +export declare const shadowedCycle: { + Node: { + value: number; + next: (shadowedCycle: T) => typeof import(".").shadowedCycle["Node"]; + }; +}; +export declare const optionalCycle: { + Node?: optionalCycle_recursive; +}; +export declare const nullableCycle: { + Node: nullableCycle_recursive | null; +}; +export declare const mixedCycles: { + required: { + Node?: mixedCycles_recursive; + }; + optional?: { + Node?: mixedCycles_recursive; + } | null; +}; +export declare const sharedOptionalCycles: { + first: { + Node?: sharedOptionalCycles_recursive; + }; + second: { + Node?: sharedOptionalCycles_recursive; + }; +}; +export declare const nullableKeys: { + "a-b": nullableKeys_recursive | null; + 0: nullableKeys_recursive_1 | null; + [cycleKey]: nullableKeys_recursive_2 | null; +}; +export declare const nullableRoot: nullableRoot_recursive | null; +export declare const optionalRoot: optionalRoot_recursive | undefined; +export declare const nullableLinks: { + Node: { + value: number; + next: (typeof nullableLinks)["Node"]; + } | null; +}; +export declare const optionalNullableLinks: { + Node?: optionalNullableLinks_recursive | null; +}; +export declare const nullableOptionalLinks: { + Node: nullableOptionalLinks_recursive | null; +}; +export declare const nullishLinks: { + Node?: nullishLinks_recursive | null; +}; +export declare const mixedUnionCycle: { + Node?: false | mixedUnionCycle_recursive | null; +}; +export declare const _recursive = 1; +export declare const factory: () => () => factory_recursive; +export declare function captured(value: T): captured_recursive; +export declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive; +export declare function constrained(key: K): constrained_recursive; +export declare function optionalCaptured(value: T): { + node?: optionalCaptured_recursive | false | null; +}; +export declare function annotatedCaptured(value: T): annotatedCaptured_recursive; +export declare function recursiveTuple(value: T): recursiveTuple_recursive; +export declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never); +export declare function mappedCaptured(): mappedCaptured_recursive; +export declare function freshGeneric(unused: T): freshGeneric_recursive; +export declare function mutualCaptured(left: T, right: U): { + left: mutualCaptured_recursive_1; + right: mutualCaptured_recursive; +}; +export declare class CapturedClass { + value: T; + constructor(value: T); + make(inner: U): CapturedClass_make_recursive; +} +export declare function covariantClass(): { + new (): covariantClass_recursive; +}; +export declare function contravariantClass(): { + new (): contravariantClass_recursive; +}; +export declare namespace Nested { + type captured_recursive_1 = { + value: T; + next: () => captured_recursive_1; + }; + export function captured(value: T): captured_recursive_1; + export {}; +} +export {}; //// [/home/src/workspaces/project/producer/dist/index.js] *new* +import { f } from "./recursive-conditional-utils"; +export const conditionalAliasCopy = f; +export function anonymousThisReturn() { + return { + relyingOnThis() { + return this; + }, + }; +} export const arrow = () => arrow; export const expression = function self() { return self; }; export const first = () => second; @@ -584,22 +1267,129 @@ export const nestedOwner = { }, }; export const nestedNumber = nestedOwner.make(1); +export const mappedCycle = build(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build() }; +export const cycleKey = Symbol(); +export const keyedCycles = build(); +export const sharedCycles = { first: mappedCycle, second: mappedCycle }; +export const mutualCycle = buildMutual(); +export const shadowedCycle = buildShadowed(); +export const optionalCycle = buildOptional(); +export const nullableCycle = buildNullable(); +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKeys = buildNullable(); +export const nullableRoot = buildNullableRoot(); +export const optionalRoot = buildOptionalRoot(); +export const nullableLinks = buildNullableLinks(); +export const optionalNullableLinks = buildOptionalNullableLinks(); +export const nullableOptionalLinks = buildNullableOptionalLinks(); +export const nullishLinks = buildNullishLinks(); +export const mixedUnionCycle = buildMixed(); +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value) { + const node = { value, next: () => node, consume: (other) => node }; + return node; +} +export function nestedCaptured(outer) { + return (inner) => { + const node = { + outer, inner, next: () => node, + shadow: (value) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key) { + const node = { value: null, next: () => node }; + return node; +} +export function optionalCaptured(value) { + return null; +} +export function annotatedCaptured(value) { + const node = { value, next: null }; + return node; +} +export function recursiveTuple(value) { + return null; +} +export function inferredCaptured() { + return null; +} +export function mappedCaptured() { + return null; +} +export function freshGeneric(unused) { + const recur = (value) => recur; + return recur; +} +export function mutualCaptured(left, right) { + return { left: null, right: null }; +} +export class CapturedClass { + value; + constructor(value) { + this.value = value; + } + make(inner) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value; + next() { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume; + next() { return this; } + }; +} +export var Nested; +(function (Nested) { + function captured(value) { + const node = { value, next: () => node }; + return node; + } + Nested.captured = captured; +})(Nested || (Nested = {})); + +//// [/home/src/workspaces/project/producer/dist/recursive-conditional-utils.d.ts] *new* +type Recursive = T extends Array ? Recursive : T; +export declare const f: () => Recursive; +export {}; + +//// [/home/src/workspaces/project/producer/dist/recursive-conditional-utils.js] *new* +export const f = () => { + return null; +}; //// [/home/src/workspaces/project/producer/dist/tsconfig.tsbuildinfo] *new* -{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"c50047250d0afa431800786fe8ac0f71-export const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);","signature":"ac680f9630fda193ccd7e95d350590d1-export declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./","strict":true},"latestChangedDtsFile":"./index.d.ts"} +{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","../recursive-conditional-utils.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"5f612a8da522ce136561c99ba028217b-type Recursive = T extends Array ? Recursive : T;\nexport const f = (): Recursive => {\n return null!;\n};","signature":"b7e553848a0db56da7124d58387f207a-type Recursive = T extends Array ? Recursive : T;\nexport declare const f: () => Recursive;\nexport {};\n","impliedNodeFormat":1},{"version":"647cf2affc61d839035c9d49279879e5-import { f } from \"./recursive-conditional-utils\";\nexport const conditionalAliasCopy = f;\nexport function anonymousThisReturn() {\n return {\n relyingOnThis() {\n return this;\n },\n };\n}\nexport const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\ntype Show = { [K in keyof T]: T[K] } & unknown;\ntype Resolve = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? Resolve : M[K][P];\n}>;\ndeclare const build: () => { [K in keyof M]: Resolve };\nexport const mappedCycle = build<{ Node: { value: number; next: \"ref\" } }>();\nexport const mappedCycleCopy = mappedCycle;\nexport const nestedCycle = { wrapped: build<{ Node: { value: string; next: \"ref\" } }>() };\nexport const cycleKey = Symbol();\nexport const keyedCycles = build<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\nexport const sharedCycles = { first: mappedCycle, second: mappedCycle };\ntype ResolveMutual = Show<{\n [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P];\n}>;\ndeclare const buildMutual: () => { [K in keyof M]: ResolveMutual };\nexport const mutualCycle = buildMutual<{\n First: { value: number; next: { ref: \"Second\" } };\n Second: { value: string; next: { ref: \"First\" } };\n}>();\ntype ResolveShadowed = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? (shadowedCycle: T) => ResolveShadowed : M[K][P];\n}>;\ndeclare const buildShadowed: () => { [K in keyof M]: ResolveShadowed };\nexport const shadowedCycle = buildShadowed<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptional: () => { [K in keyof M]?: Resolve };\nexport const optionalCycle = buildOptional<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildNullable: () => { [K in keyof M]: Resolve | null };\nexport const nullableCycle = buildNullable<{ Node: { value: string; next: \"ref\" } }>();\ndeclare const wrap: (value: T) => { required: T; optional?: T | null };\nexport const mixedCycles = wrap(optionalCycle);\nexport const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle };\nexport const nullableKeys = buildNullable<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\ndeclare const buildNullableRoot: () => Resolve | null;\nexport const nullableRoot = buildNullableRoot<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalRoot: () => Resolve | undefined;\nexport const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: \"ref\" } }>();\ntype ResolveNullable = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullable | null : M[K][P];\n}>;\ndeclare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null };\nexport const nullableLinks = buildNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null };\nexport const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveOptional = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveOptional | undefined : M[K][P];\n}>;\ndeclare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null };\nexport const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveNullish = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullish | null | undefined : M[K][P];\n}>;\ndeclare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null };\nexport const nullishLinks = buildNullishLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildMixed: () => { [K in keyof M]?: Resolve | false | null };\nexport const mixedUnionCycle = buildMixed<{ Node: { value: number; next: \"ref\" } }>();\nexport const _recursive = 1;\nexport const factory = () => function self() { return self; };\nexport function captured(value: T) {\n const node = { value, next: () => node, consume: (other: T) => node };\n return node;\n}\nexport function nestedCaptured(outer: T) {\n return (inner: U) => {\n const node = {\n outer, inner, next: () => node,\n shadow: (value: T) => ({ outer, inner, value, next: node }),\n };\n return node;\n };\n}\nexport function constrained(key: K) {\n const node = { value: null! as T[K], next: () => node };\n return node;\n}\nexport function optionalCaptured(value: T) {\n type Node = { value: T; next: Node };\n return null! as { node?: Node | false | null };\n}\nexport function annotatedCaptured(value: T) {\n const node: { value: typeof value; next: typeof node } = { value, next: null! };\n return node;\n}\nexport function recursiveTuple(value: T) {\n type Tuple = readonly [T, Tuple];\n return null! as Tuple;\n}\nexport function inferredCaptured() {\n type Node = { value: V; next: Node };\n return null! as (T extends () => infer U ? Node : never);\n}\nexport function mappedCaptured() {\n type Node = { [K in keyof T]: { value: T[K]; next: Node } };\n return null! as Node;\n}\nexport function freshGeneric(unused: T) {\n const recur = (value: U) => recur;\n return recur;\n}\nexport function mutualCaptured(left: T, right: U) {\n type Left = { left: T; next: Right };\n type Right = { right: U; self: Right; next: Left };\n return { left: null! as Left, right: null! as Right };\n}\nexport class CapturedClass {\n constructor(public value: T) {}\n make(inner: U) {\n const node = { outer: this.value, inner, next: () => node };\n return node;\n }\n}\nexport function covariantClass() {\n return class Node {\n value!: T;\n next(): Node { return this; }\n };\n}\nexport function contravariantClass() {\n return class Node {\n consume!: (value: T) => void;\n next(): Node { return this; }\n };\n}\nexport namespace Nested {\n export function captured(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}\ntype NonNullable = \"shadowed\";","signature":"8fc541a8e5c6c5e8f531954fb3ccef01-type anonymousThisReturn_recursive = {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\ntype optionalCycle_recursive = {\n value: number;\n next: optionalCycle_recursive;\n};\ntype nullableCycle_recursive = {\n value: string;\n next: nullableCycle_recursive;\n};\ntype mixedCycles_recursive = {\n value: number;\n next: mixedCycles_recursive;\n};\ntype sharedOptionalCycles_recursive = {\n value: number;\n next: sharedOptionalCycles_recursive;\n};\ntype nullableKeys_recursive = {\n value: string;\n next: nullableKeys_recursive;\n};\ntype nullableKeys_recursive_1 = {\n value: boolean;\n next: nullableKeys_recursive_1;\n};\ntype nullableKeys_recursive_2 = {\n value: number;\n next: nullableKeys_recursive_2;\n};\ntype nullableRoot_recursive = {\n value: number;\n next: nullableRoot_recursive;\n};\ntype optionalRoot_recursive = {\n value: string;\n next: optionalRoot_recursive;\n};\ntype optionalNullableLinks_recursive = {\n value: number;\n next: optionalNullableLinks_recursive | null;\n};\ntype nullableOptionalLinks_recursive = {\n value: number;\n next: nullableOptionalLinks_recursive | undefined;\n};\ntype nullishLinks_recursive = {\n value: number;\n next: nullishLinks_recursive | null | undefined;\n};\ntype mixedUnionCycle_recursive = {\n value: number;\n next: mixedUnionCycle_recursive;\n};\ntype factory_recursive = () => factory_recursive;\ntype captured_recursive = {\n value: T;\n next: () => captured_recursive;\n consume: (other: T) => captured_recursive;\n};\ntype nestedCaptured_recursive = {\n outer: T;\n inner: U;\n next: () => nestedCaptured_recursive;\n shadow: (value: T_1) => {\n outer: T;\n inner: U;\n value: T_1;\n next: nestedCaptured_recursive;\n };\n};\ntype constrained_recursive = {\n value: T[K];\n next: () => constrained_recursive;\n};\ntype optionalCaptured_recursive = {\n value: T;\n next: optionalCaptured_recursive;\n};\ntype annotatedCaptured_recursive = {\n value: T;\n next: annotatedCaptured_recursive;\n};\ntype recursiveTuple_recursive = readonly [T, recursiveTuple_recursive];\ntype inferredCaptured_recursive = {\n value: U;\n next: inferredCaptured_recursive;\n};\ntype mappedCaptured_recursive = { [K in keyof T]: {\n value: T[K];\n next: mappedCaptured_recursive;\n}; };\ntype freshGeneric_recursive = (value: U) => freshGeneric_recursive;\ntype mutualCaptured_recursive = {\n right: U;\n self: mutualCaptured_recursive;\n next: mutualCaptured_recursive_1;\n};\ntype mutualCaptured_recursive_1 = {\n left: T;\n next: mutualCaptured_recursive;\n};\ntype CapturedClass_make_recursive = {\n outer: T;\n inner: U;\n next: () => CapturedClass_make_recursive;\n};\ntype covariantClass_recursive = {\n value: T;\n next(): covariantClass_recursive;\n};\ntype contravariantClass_recursive = {\n consume: (value: T) => void;\n next(): contravariantClass_recursive;\n};\nimport { f } from \"./recursive-conditional-utils\";\nexport declare const conditionalAliasCopy: typeof f;\nexport declare function anonymousThisReturn(): {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\nexport declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\nexport declare const mappedCycle: {\n Node: {\n value: number;\n next: (typeof mappedCycle)[\"Node\"];\n };\n};\nexport declare const mappedCycleCopy: {\n Node: {\n value: number;\n next: (typeof mappedCycleCopy)[\"Node\"];\n };\n};\nexport declare const nestedCycle: {\n wrapped: {\n Node: {\n value: string;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n};\nexport declare const cycleKey: unique symbol;\nexport declare const keyedCycles: {\n \"a-b\": {\n value: string;\n next: (typeof keyedCycles)[\"a-b\"];\n };\n 0: {\n value: boolean;\n next: (typeof keyedCycles)[0];\n };\n [cycleKey]: {\n value: number;\n next: (typeof keyedCycles)[typeof cycleKey];\n };\n};\nexport declare const sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n};\nexport declare const mutualCycle: {\n First: {\n value: number;\n next: {\n value: string;\n next: (typeof mutualCycle)[\"First\"];\n };\n };\n Second: {\n value: string;\n next: {\n value: number;\n next: (typeof mutualCycle)[\"Second\"];\n };\n };\n};\nexport declare const shadowedCycle: {\n Node: {\n value: number;\n next: (shadowedCycle: T) => typeof import(\".\").shadowedCycle[\"Node\"];\n };\n};\nexport declare const optionalCycle: {\n Node?: optionalCycle_recursive;\n};\nexport declare const nullableCycle: {\n Node: nullableCycle_recursive | null;\n};\nexport declare const mixedCycles: {\n required: {\n Node?: mixedCycles_recursive;\n };\n optional?: {\n Node?: mixedCycles_recursive;\n } | null;\n};\nexport declare const sharedOptionalCycles: {\n first: {\n Node?: sharedOptionalCycles_recursive;\n };\n second: {\n Node?: sharedOptionalCycles_recursive;\n };\n};\nexport declare const nullableKeys: {\n \"a-b\": nullableKeys_recursive | null;\n 0: nullableKeys_recursive_1 | null;\n [cycleKey]: nullableKeys_recursive_2 | null;\n};\nexport declare const nullableRoot: nullableRoot_recursive | null;\nexport declare const optionalRoot: optionalRoot_recursive | undefined;\nexport declare const nullableLinks: {\n Node: {\n value: number;\n next: (typeof nullableLinks)[\"Node\"];\n } | null;\n};\nexport declare const optionalNullableLinks: {\n Node?: optionalNullableLinks_recursive | null;\n};\nexport declare const nullableOptionalLinks: {\n Node: nullableOptionalLinks_recursive | null;\n};\nexport declare const nullishLinks: {\n Node?: nullishLinks_recursive | null;\n};\nexport declare const mixedUnionCycle: {\n Node?: false | mixedUnionCycle_recursive | null;\n};\nexport declare const _recursive = 1;\nexport declare const factory: () => () => factory_recursive;\nexport declare function captured(value: T): captured_recursive;\nexport declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive;\nexport declare function constrained(key: K): constrained_recursive;\nexport declare function optionalCaptured(value: T): {\n node?: optionalCaptured_recursive | false | null;\n};\nexport declare function annotatedCaptured(value: T): annotatedCaptured_recursive;\nexport declare function recursiveTuple(value: T): recursiveTuple_recursive;\nexport declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never);\nexport declare function mappedCaptured(): mappedCaptured_recursive;\nexport declare function freshGeneric(unused: T): freshGeneric_recursive;\nexport declare function mutualCaptured(left: T, right: U): {\n left: mutualCaptured_recursive_1;\n right: mutualCaptured_recursive;\n};\nexport declare class CapturedClass {\n value: T;\n constructor(value: T);\n make(inner: U): CapturedClass_make_recursive;\n}\nexport declare function covariantClass(): {\n new (): covariantClass_recursive;\n};\nexport declare function contravariantClass(): {\n new (): contravariantClass_recursive;\n};\nexport declare namespace Nested {\n type captured_recursive_1 = {\n value: T;\n next: () => captured_recursive_1;\n };\n export function captured(value: T): captured_recursive_1;\n export {};\n}\nexport {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"exactOptionalPropertyTypes":true,"outDir":"./","strict":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./index.d.ts"} //// [/home/src/workspaces/project/producer/dist/tsconfig.tsbuildinfo.readable.baseline.txt] *new* { "version": "FakeTSVersion", "root": [ { "files": [ + "../recursive-conditional-utils.ts", "../index.ts" ], - "original": 2 + "original": [ + 2, + 3 + ] } ], "fileNames": [ "lib.es2026.full.d.ts", + "../recursive-conditional-utils.ts", "../index.ts" ], "fileInfos": [ @@ -615,37 +1405,62 @@ export const nestedNumber = nestedOwner.make(1); "impliedNodeFormat": 1 } }, + { + "fileName": "../recursive-conditional-utils.ts", + "version": "5f612a8da522ce136561c99ba028217b-type Recursive = T extends Array ? Recursive : T;\nexport const f = (): Recursive => {\n return null!;\n};", + "signature": "b7e553848a0db56da7124d58387f207a-type Recursive = T extends Array ? Recursive : T;\nexport declare const f: () => Recursive;\nexport {};\n", + "impliedNodeFormat": "CommonJS", + "original": { + "version": "5f612a8da522ce136561c99ba028217b-type Recursive = T extends Array ? Recursive : T;\nexport const f = (): Recursive => {\n return null!;\n};", + "signature": "b7e553848a0db56da7124d58387f207a-type Recursive = T extends Array ? Recursive : T;\nexport declare const f: () => Recursive;\nexport {};\n", + "impliedNodeFormat": 1 + } + }, { "fileName": "../index.ts", - "version": "c50047250d0afa431800786fe8ac0f71-export const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);", - "signature": "ac680f9630fda193ccd7e95d350590d1-export declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\n", + "version": "647cf2affc61d839035c9d49279879e5-import { f } from \"./recursive-conditional-utils\";\nexport const conditionalAliasCopy = f;\nexport function anonymousThisReturn() {\n return {\n relyingOnThis() {\n return this;\n },\n };\n}\nexport const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\ntype Show = { [K in keyof T]: T[K] } & unknown;\ntype Resolve = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? Resolve : M[K][P];\n}>;\ndeclare const build: () => { [K in keyof M]: Resolve };\nexport const mappedCycle = build<{ Node: { value: number; next: \"ref\" } }>();\nexport const mappedCycleCopy = mappedCycle;\nexport const nestedCycle = { wrapped: build<{ Node: { value: string; next: \"ref\" } }>() };\nexport const cycleKey = Symbol();\nexport const keyedCycles = build<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\nexport const sharedCycles = { first: mappedCycle, second: mappedCycle };\ntype ResolveMutual = Show<{\n [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P];\n}>;\ndeclare const buildMutual: () => { [K in keyof M]: ResolveMutual };\nexport const mutualCycle = buildMutual<{\n First: { value: number; next: { ref: \"Second\" } };\n Second: { value: string; next: { ref: \"First\" } };\n}>();\ntype ResolveShadowed = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? (shadowedCycle: T) => ResolveShadowed : M[K][P];\n}>;\ndeclare const buildShadowed: () => { [K in keyof M]: ResolveShadowed };\nexport const shadowedCycle = buildShadowed<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptional: () => { [K in keyof M]?: Resolve };\nexport const optionalCycle = buildOptional<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildNullable: () => { [K in keyof M]: Resolve | null };\nexport const nullableCycle = buildNullable<{ Node: { value: string; next: \"ref\" } }>();\ndeclare const wrap: (value: T) => { required: T; optional?: T | null };\nexport const mixedCycles = wrap(optionalCycle);\nexport const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle };\nexport const nullableKeys = buildNullable<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\ndeclare const buildNullableRoot: () => Resolve | null;\nexport const nullableRoot = buildNullableRoot<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalRoot: () => Resolve | undefined;\nexport const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: \"ref\" } }>();\ntype ResolveNullable = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullable | null : M[K][P];\n}>;\ndeclare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null };\nexport const nullableLinks = buildNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null };\nexport const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveOptional = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveOptional | undefined : M[K][P];\n}>;\ndeclare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null };\nexport const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveNullish = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullish | null | undefined : M[K][P];\n}>;\ndeclare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null };\nexport const nullishLinks = buildNullishLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildMixed: () => { [K in keyof M]?: Resolve | false | null };\nexport const mixedUnionCycle = buildMixed<{ Node: { value: number; next: \"ref\" } }>();\nexport const _recursive = 1;\nexport const factory = () => function self() { return self; };\nexport function captured(value: T) {\n const node = { value, next: () => node, consume: (other: T) => node };\n return node;\n}\nexport function nestedCaptured(outer: T) {\n return (inner: U) => {\n const node = {\n outer, inner, next: () => node,\n shadow: (value: T) => ({ outer, inner, value, next: node }),\n };\n return node;\n };\n}\nexport function constrained(key: K) {\n const node = { value: null! as T[K], next: () => node };\n return node;\n}\nexport function optionalCaptured(value: T) {\n type Node = { value: T; next: Node };\n return null! as { node?: Node | false | null };\n}\nexport function annotatedCaptured(value: T) {\n const node: { value: typeof value; next: typeof node } = { value, next: null! };\n return node;\n}\nexport function recursiveTuple(value: T) {\n type Tuple = readonly [T, Tuple];\n return null! as Tuple;\n}\nexport function inferredCaptured() {\n type Node = { value: V; next: Node };\n return null! as (T extends () => infer U ? Node : never);\n}\nexport function mappedCaptured() {\n type Node = { [K in keyof T]: { value: T[K]; next: Node } };\n return null! as Node;\n}\nexport function freshGeneric(unused: T) {\n const recur = (value: U) => recur;\n return recur;\n}\nexport function mutualCaptured(left: T, right: U) {\n type Left = { left: T; next: Right };\n type Right = { right: U; self: Right; next: Left };\n return { left: null! as Left, right: null! as Right };\n}\nexport class CapturedClass {\n constructor(public value: T) {}\n make(inner: U) {\n const node = { outer: this.value, inner, next: () => node };\n return node;\n }\n}\nexport function covariantClass() {\n return class Node {\n value!: T;\n next(): Node { return this; }\n };\n}\nexport function contravariantClass() {\n return class Node {\n consume!: (value: T) => void;\n next(): Node { return this; }\n };\n}\nexport namespace Nested {\n export function captured(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}\ntype NonNullable = \"shadowed\";", + "signature": "8fc541a8e5c6c5e8f531954fb3ccef01-type anonymousThisReturn_recursive = {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\ntype optionalCycle_recursive = {\n value: number;\n next: optionalCycle_recursive;\n};\ntype nullableCycle_recursive = {\n value: string;\n next: nullableCycle_recursive;\n};\ntype mixedCycles_recursive = {\n value: number;\n next: mixedCycles_recursive;\n};\ntype sharedOptionalCycles_recursive = {\n value: number;\n next: sharedOptionalCycles_recursive;\n};\ntype nullableKeys_recursive = {\n value: string;\n next: nullableKeys_recursive;\n};\ntype nullableKeys_recursive_1 = {\n value: boolean;\n next: nullableKeys_recursive_1;\n};\ntype nullableKeys_recursive_2 = {\n value: number;\n next: nullableKeys_recursive_2;\n};\ntype nullableRoot_recursive = {\n value: number;\n next: nullableRoot_recursive;\n};\ntype optionalRoot_recursive = {\n value: string;\n next: optionalRoot_recursive;\n};\ntype optionalNullableLinks_recursive = {\n value: number;\n next: optionalNullableLinks_recursive | null;\n};\ntype nullableOptionalLinks_recursive = {\n value: number;\n next: nullableOptionalLinks_recursive | undefined;\n};\ntype nullishLinks_recursive = {\n value: number;\n next: nullishLinks_recursive | null | undefined;\n};\ntype mixedUnionCycle_recursive = {\n value: number;\n next: mixedUnionCycle_recursive;\n};\ntype factory_recursive = () => factory_recursive;\ntype captured_recursive = {\n value: T;\n next: () => captured_recursive;\n consume: (other: T) => captured_recursive;\n};\ntype nestedCaptured_recursive = {\n outer: T;\n inner: U;\n next: () => nestedCaptured_recursive;\n shadow: (value: T_1) => {\n outer: T;\n inner: U;\n value: T_1;\n next: nestedCaptured_recursive;\n };\n};\ntype constrained_recursive = {\n value: T[K];\n next: () => constrained_recursive;\n};\ntype optionalCaptured_recursive = {\n value: T;\n next: optionalCaptured_recursive;\n};\ntype annotatedCaptured_recursive = {\n value: T;\n next: annotatedCaptured_recursive;\n};\ntype recursiveTuple_recursive = readonly [T, recursiveTuple_recursive];\ntype inferredCaptured_recursive = {\n value: U;\n next: inferredCaptured_recursive;\n};\ntype mappedCaptured_recursive = { [K in keyof T]: {\n value: T[K];\n next: mappedCaptured_recursive;\n}; };\ntype freshGeneric_recursive = (value: U) => freshGeneric_recursive;\ntype mutualCaptured_recursive = {\n right: U;\n self: mutualCaptured_recursive;\n next: mutualCaptured_recursive_1;\n};\ntype mutualCaptured_recursive_1 = {\n left: T;\n next: mutualCaptured_recursive;\n};\ntype CapturedClass_make_recursive = {\n outer: T;\n inner: U;\n next: () => CapturedClass_make_recursive;\n};\ntype covariantClass_recursive = {\n value: T;\n next(): covariantClass_recursive;\n};\ntype contravariantClass_recursive = {\n consume: (value: T) => void;\n next(): contravariantClass_recursive;\n};\nimport { f } from \"./recursive-conditional-utils\";\nexport declare const conditionalAliasCopy: typeof f;\nexport declare function anonymousThisReturn(): {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\nexport declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\nexport declare const mappedCycle: {\n Node: {\n value: number;\n next: (typeof mappedCycle)[\"Node\"];\n };\n};\nexport declare const mappedCycleCopy: {\n Node: {\n value: number;\n next: (typeof mappedCycleCopy)[\"Node\"];\n };\n};\nexport declare const nestedCycle: {\n wrapped: {\n Node: {\n value: string;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n};\nexport declare const cycleKey: unique symbol;\nexport declare const keyedCycles: {\n \"a-b\": {\n value: string;\n next: (typeof keyedCycles)[\"a-b\"];\n };\n 0: {\n value: boolean;\n next: (typeof keyedCycles)[0];\n };\n [cycleKey]: {\n value: number;\n next: (typeof keyedCycles)[typeof cycleKey];\n };\n};\nexport declare const sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n};\nexport declare const mutualCycle: {\n First: {\n value: number;\n next: {\n value: string;\n next: (typeof mutualCycle)[\"First\"];\n };\n };\n Second: {\n value: string;\n next: {\n value: number;\n next: (typeof mutualCycle)[\"Second\"];\n };\n };\n};\nexport declare const shadowedCycle: {\n Node: {\n value: number;\n next: (shadowedCycle: T) => typeof import(\".\").shadowedCycle[\"Node\"];\n };\n};\nexport declare const optionalCycle: {\n Node?: optionalCycle_recursive;\n};\nexport declare const nullableCycle: {\n Node: nullableCycle_recursive | null;\n};\nexport declare const mixedCycles: {\n required: {\n Node?: mixedCycles_recursive;\n };\n optional?: {\n Node?: mixedCycles_recursive;\n } | null;\n};\nexport declare const sharedOptionalCycles: {\n first: {\n Node?: sharedOptionalCycles_recursive;\n };\n second: {\n Node?: sharedOptionalCycles_recursive;\n };\n};\nexport declare const nullableKeys: {\n \"a-b\": nullableKeys_recursive | null;\n 0: nullableKeys_recursive_1 | null;\n [cycleKey]: nullableKeys_recursive_2 | null;\n};\nexport declare const nullableRoot: nullableRoot_recursive | null;\nexport declare const optionalRoot: optionalRoot_recursive | undefined;\nexport declare const nullableLinks: {\n Node: {\n value: number;\n next: (typeof nullableLinks)[\"Node\"];\n } | null;\n};\nexport declare const optionalNullableLinks: {\n Node?: optionalNullableLinks_recursive | null;\n};\nexport declare const nullableOptionalLinks: {\n Node: nullableOptionalLinks_recursive | null;\n};\nexport declare const nullishLinks: {\n Node?: nullishLinks_recursive | null;\n};\nexport declare const mixedUnionCycle: {\n Node?: false | mixedUnionCycle_recursive | null;\n};\nexport declare const _recursive = 1;\nexport declare const factory: () => () => factory_recursive;\nexport declare function captured(value: T): captured_recursive;\nexport declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive;\nexport declare function constrained(key: K): constrained_recursive;\nexport declare function optionalCaptured(value: T): {\n node?: optionalCaptured_recursive | false | null;\n};\nexport declare function annotatedCaptured(value: T): annotatedCaptured_recursive;\nexport declare function recursiveTuple(value: T): recursiveTuple_recursive;\nexport declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never);\nexport declare function mappedCaptured(): mappedCaptured_recursive;\nexport declare function freshGeneric(unused: T): freshGeneric_recursive;\nexport declare function mutualCaptured(left: T, right: U): {\n left: mutualCaptured_recursive_1;\n right: mutualCaptured_recursive;\n};\nexport declare class CapturedClass {\n value: T;\n constructor(value: T);\n make(inner: U): CapturedClass_make_recursive;\n}\nexport declare function covariantClass(): {\n new (): covariantClass_recursive;\n};\nexport declare function contravariantClass(): {\n new (): contravariantClass_recursive;\n};\nexport declare namespace Nested {\n type captured_recursive_1 = {\n value: T;\n next: () => captured_recursive_1;\n };\n export function captured(value: T): captured_recursive_1;\n export {};\n}\nexport {};\n", "impliedNodeFormat": "CommonJS", "original": { - "version": "c50047250d0afa431800786fe8ac0f71-export const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);", - "signature": "ac680f9630fda193ccd7e95d350590d1-export declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\n", + "version": "647cf2affc61d839035c9d49279879e5-import { f } from \"./recursive-conditional-utils\";\nexport const conditionalAliasCopy = f;\nexport function anonymousThisReturn() {\n return {\n relyingOnThis() {\n return this;\n },\n };\n}\nexport const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\ntype Show = { [K in keyof T]: T[K] } & unknown;\ntype Resolve = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? Resolve : M[K][P];\n}>;\ndeclare const build: () => { [K in keyof M]: Resolve };\nexport const mappedCycle = build<{ Node: { value: number; next: \"ref\" } }>();\nexport const mappedCycleCopy = mappedCycle;\nexport const nestedCycle = { wrapped: build<{ Node: { value: string; next: \"ref\" } }>() };\nexport const cycleKey = Symbol();\nexport const keyedCycles = build<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\nexport const sharedCycles = { first: mappedCycle, second: mappedCycle };\ntype ResolveMutual = Show<{\n [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P];\n}>;\ndeclare const buildMutual: () => { [K in keyof M]: ResolveMutual };\nexport const mutualCycle = buildMutual<{\n First: { value: number; next: { ref: \"Second\" } };\n Second: { value: string; next: { ref: \"First\" } };\n}>();\ntype ResolveShadowed = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? (shadowedCycle: T) => ResolveShadowed : M[K][P];\n}>;\ndeclare const buildShadowed: () => { [K in keyof M]: ResolveShadowed };\nexport const shadowedCycle = buildShadowed<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptional: () => { [K in keyof M]?: Resolve };\nexport const optionalCycle = buildOptional<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildNullable: () => { [K in keyof M]: Resolve | null };\nexport const nullableCycle = buildNullable<{ Node: { value: string; next: \"ref\" } }>();\ndeclare const wrap: (value: T) => { required: T; optional?: T | null };\nexport const mixedCycles = wrap(optionalCycle);\nexport const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle };\nexport const nullableKeys = buildNullable<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\ndeclare const buildNullableRoot: () => Resolve | null;\nexport const nullableRoot = buildNullableRoot<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalRoot: () => Resolve | undefined;\nexport const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: \"ref\" } }>();\ntype ResolveNullable = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullable | null : M[K][P];\n}>;\ndeclare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null };\nexport const nullableLinks = buildNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null };\nexport const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveOptional = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveOptional | undefined : M[K][P];\n}>;\ndeclare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null };\nexport const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveNullish = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullish | null | undefined : M[K][P];\n}>;\ndeclare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null };\nexport const nullishLinks = buildNullishLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildMixed: () => { [K in keyof M]?: Resolve | false | null };\nexport const mixedUnionCycle = buildMixed<{ Node: { value: number; next: \"ref\" } }>();\nexport const _recursive = 1;\nexport const factory = () => function self() { return self; };\nexport function captured(value: T) {\n const node = { value, next: () => node, consume: (other: T) => node };\n return node;\n}\nexport function nestedCaptured(outer: T) {\n return (inner: U) => {\n const node = {\n outer, inner, next: () => node,\n shadow: (value: T) => ({ outer, inner, value, next: node }),\n };\n return node;\n };\n}\nexport function constrained(key: K) {\n const node = { value: null! as T[K], next: () => node };\n return node;\n}\nexport function optionalCaptured(value: T) {\n type Node = { value: T; next: Node };\n return null! as { node?: Node | false | null };\n}\nexport function annotatedCaptured(value: T) {\n const node: { value: typeof value; next: typeof node } = { value, next: null! };\n return node;\n}\nexport function recursiveTuple(value: T) {\n type Tuple = readonly [T, Tuple];\n return null! as Tuple;\n}\nexport function inferredCaptured() {\n type Node = { value: V; next: Node };\n return null! as (T extends () => infer U ? Node : never);\n}\nexport function mappedCaptured() {\n type Node = { [K in keyof T]: { value: T[K]; next: Node } };\n return null! as Node;\n}\nexport function freshGeneric(unused: T) {\n const recur = (value: U) => recur;\n return recur;\n}\nexport function mutualCaptured(left: T, right: U) {\n type Left = { left: T; next: Right };\n type Right = { right: U; self: Right; next: Left };\n return { left: null! as Left, right: null! as Right };\n}\nexport class CapturedClass {\n constructor(public value: T) {}\n make(inner: U) {\n const node = { outer: this.value, inner, next: () => node };\n return node;\n }\n}\nexport function covariantClass() {\n return class Node {\n value!: T;\n next(): Node { return this; }\n };\n}\nexport function contravariantClass() {\n return class Node {\n consume!: (value: T) => void;\n next(): Node { return this; }\n };\n}\nexport namespace Nested {\n export function captured(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}\ntype NonNullable = \"shadowed\";", + "signature": "8fc541a8e5c6c5e8f531954fb3ccef01-type anonymousThisReturn_recursive = {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\ntype optionalCycle_recursive = {\n value: number;\n next: optionalCycle_recursive;\n};\ntype nullableCycle_recursive = {\n value: string;\n next: nullableCycle_recursive;\n};\ntype mixedCycles_recursive = {\n value: number;\n next: mixedCycles_recursive;\n};\ntype sharedOptionalCycles_recursive = {\n value: number;\n next: sharedOptionalCycles_recursive;\n};\ntype nullableKeys_recursive = {\n value: string;\n next: nullableKeys_recursive;\n};\ntype nullableKeys_recursive_1 = {\n value: boolean;\n next: nullableKeys_recursive_1;\n};\ntype nullableKeys_recursive_2 = {\n value: number;\n next: nullableKeys_recursive_2;\n};\ntype nullableRoot_recursive = {\n value: number;\n next: nullableRoot_recursive;\n};\ntype optionalRoot_recursive = {\n value: string;\n next: optionalRoot_recursive;\n};\ntype optionalNullableLinks_recursive = {\n value: number;\n next: optionalNullableLinks_recursive | null;\n};\ntype nullableOptionalLinks_recursive = {\n value: number;\n next: nullableOptionalLinks_recursive | undefined;\n};\ntype nullishLinks_recursive = {\n value: number;\n next: nullishLinks_recursive | null | undefined;\n};\ntype mixedUnionCycle_recursive = {\n value: number;\n next: mixedUnionCycle_recursive;\n};\ntype factory_recursive = () => factory_recursive;\ntype captured_recursive = {\n value: T;\n next: () => captured_recursive;\n consume: (other: T) => captured_recursive;\n};\ntype nestedCaptured_recursive = {\n outer: T;\n inner: U;\n next: () => nestedCaptured_recursive;\n shadow: (value: T_1) => {\n outer: T;\n inner: U;\n value: T_1;\n next: nestedCaptured_recursive;\n };\n};\ntype constrained_recursive = {\n value: T[K];\n next: () => constrained_recursive;\n};\ntype optionalCaptured_recursive = {\n value: T;\n next: optionalCaptured_recursive;\n};\ntype annotatedCaptured_recursive = {\n value: T;\n next: annotatedCaptured_recursive;\n};\ntype recursiveTuple_recursive = readonly [T, recursiveTuple_recursive];\ntype inferredCaptured_recursive = {\n value: U;\n next: inferredCaptured_recursive;\n};\ntype mappedCaptured_recursive = { [K in keyof T]: {\n value: T[K];\n next: mappedCaptured_recursive;\n}; };\ntype freshGeneric_recursive = (value: U) => freshGeneric_recursive;\ntype mutualCaptured_recursive = {\n right: U;\n self: mutualCaptured_recursive;\n next: mutualCaptured_recursive_1;\n};\ntype mutualCaptured_recursive_1 = {\n left: T;\n next: mutualCaptured_recursive;\n};\ntype CapturedClass_make_recursive = {\n outer: T;\n inner: U;\n next: () => CapturedClass_make_recursive;\n};\ntype covariantClass_recursive = {\n value: T;\n next(): covariantClass_recursive;\n};\ntype contravariantClass_recursive = {\n consume: (value: T) => void;\n next(): contravariantClass_recursive;\n};\nimport { f } from \"./recursive-conditional-utils\";\nexport declare const conditionalAliasCopy: typeof f;\nexport declare function anonymousThisReturn(): {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\nexport declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\nexport declare const mappedCycle: {\n Node: {\n value: number;\n next: (typeof mappedCycle)[\"Node\"];\n };\n};\nexport declare const mappedCycleCopy: {\n Node: {\n value: number;\n next: (typeof mappedCycleCopy)[\"Node\"];\n };\n};\nexport declare const nestedCycle: {\n wrapped: {\n Node: {\n value: string;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n};\nexport declare const cycleKey: unique symbol;\nexport declare const keyedCycles: {\n \"a-b\": {\n value: string;\n next: (typeof keyedCycles)[\"a-b\"];\n };\n 0: {\n value: boolean;\n next: (typeof keyedCycles)[0];\n };\n [cycleKey]: {\n value: number;\n next: (typeof keyedCycles)[typeof cycleKey];\n };\n};\nexport declare const sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n};\nexport declare const mutualCycle: {\n First: {\n value: number;\n next: {\n value: string;\n next: (typeof mutualCycle)[\"First\"];\n };\n };\n Second: {\n value: string;\n next: {\n value: number;\n next: (typeof mutualCycle)[\"Second\"];\n };\n };\n};\nexport declare const shadowedCycle: {\n Node: {\n value: number;\n next: (shadowedCycle: T) => typeof import(\".\").shadowedCycle[\"Node\"];\n };\n};\nexport declare const optionalCycle: {\n Node?: optionalCycle_recursive;\n};\nexport declare const nullableCycle: {\n Node: nullableCycle_recursive | null;\n};\nexport declare const mixedCycles: {\n required: {\n Node?: mixedCycles_recursive;\n };\n optional?: {\n Node?: mixedCycles_recursive;\n } | null;\n};\nexport declare const sharedOptionalCycles: {\n first: {\n Node?: sharedOptionalCycles_recursive;\n };\n second: {\n Node?: sharedOptionalCycles_recursive;\n };\n};\nexport declare const nullableKeys: {\n \"a-b\": nullableKeys_recursive | null;\n 0: nullableKeys_recursive_1 | null;\n [cycleKey]: nullableKeys_recursive_2 | null;\n};\nexport declare const nullableRoot: nullableRoot_recursive | null;\nexport declare const optionalRoot: optionalRoot_recursive | undefined;\nexport declare const nullableLinks: {\n Node: {\n value: number;\n next: (typeof nullableLinks)[\"Node\"];\n } | null;\n};\nexport declare const optionalNullableLinks: {\n Node?: optionalNullableLinks_recursive | null;\n};\nexport declare const nullableOptionalLinks: {\n Node: nullableOptionalLinks_recursive | null;\n};\nexport declare const nullishLinks: {\n Node?: nullishLinks_recursive | null;\n};\nexport declare const mixedUnionCycle: {\n Node?: false | mixedUnionCycle_recursive | null;\n};\nexport declare const _recursive = 1;\nexport declare const factory: () => () => factory_recursive;\nexport declare function captured(value: T): captured_recursive;\nexport declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive;\nexport declare function constrained(key: K): constrained_recursive;\nexport declare function optionalCaptured(value: T): {\n node?: optionalCaptured_recursive | false | null;\n};\nexport declare function annotatedCaptured(value: T): annotatedCaptured_recursive;\nexport declare function recursiveTuple(value: T): recursiveTuple_recursive;\nexport declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never);\nexport declare function mappedCaptured(): mappedCaptured_recursive;\nexport declare function freshGeneric(unused: T): freshGeneric_recursive;\nexport declare function mutualCaptured(left: T, right: U): {\n left: mutualCaptured_recursive_1;\n right: mutualCaptured_recursive;\n};\nexport declare class CapturedClass {\n value: T;\n constructor(value: T);\n make(inner: U): CapturedClass_make_recursive;\n}\nexport declare function covariantClass(): {\n new (): covariantClass_recursive;\n};\nexport declare function contravariantClass(): {\n new (): contravariantClass_recursive;\n};\nexport declare namespace Nested {\n type captured_recursive_1 = {\n value: T;\n next: () => captured_recursive_1;\n };\n export function captured(value: T): captured_recursive_1;\n export {};\n}\nexport {};\n", "impliedNodeFormat": 1 } } ], + "fileIdsList": [ + [ + "../recursive-conditional-utils.ts" + ] + ], "options": { "composite": true, + "exactOptionalPropertyTypes": true, "outDir": "./", "strict": true }, + "referencedMap": { + "../index.ts": [ + "../recursive-conditional-utils.ts" + ] + }, "latestChangedDtsFile": "./index.d.ts", - "size": 11151 + "size": 26562 } producer/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/producer/recursive-conditional-utils.ts *refresh* /home/src/workspaces/project/producer/index.ts Signatures:: +(stored at emit) /home/src/workspaces/project/producer/recursive-conditional-utils.ts (stored at emit) /home/src/workspaces/project/producer/index.ts consumer/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/producer/dist/recursive-conditional-utils.d.ts *refresh* /home/src/workspaces/project/producer/dist/index.d.ts *refresh* /home/src/workspaces/project/consumer/index.ts Signatures:: @@ -656,98 +1471,210 @@ Edit [0]:: no change tsgo --build consumer ExitStatus:: DiagnosticsPresent_OutputsGenerated Output:: -consumer/index.ts:58:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +consumer/index.ts:166:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +166 const invalid: number = arrow()()(); +   ~~~~~~~ + +consumer/index.ts:167:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +167 const invalidExpression: number = expression()()(); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:168:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. + +168 const invalidObject: number = objectReturn().call; +   ~~~~~~~~~~~~~ + +consumer/index.ts:169:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. + +169 const invalidTuple: number = tupleReturn()[0]; +   ~~~~~~~~~~~~ + +consumer/index.ts:170:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. + +170 const invalidShadowed: number = shadowed(1); +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:171:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +171 const invalidObjectValue: string = object.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:172:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. + +172 const invalidTupleValue: number = tuple[0](); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:173:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +173 const invalidSpecialized: number = specialized.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:174:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. + +174 const invalidMapped: number = mapped.next; +   ~~~~~~~~~~~~~ + +consumer/index.ts:175:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +175 const invalidAnnotation: number = viaAnnotation.next().value; +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:176:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +176 const invalidLink: number = nextLink.next.value; +   ~~~~~~~~~~~ + +consumer/index.ts:177:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +177 const invalidCallable: string = nextCallable(1).link.value; +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:178:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +178 const invalidHiddenValue: number = hiddenAlias.next.next.value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:179:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. + +179 const invalidMethod: number = Methods.recur()(); +   ~~~~~~~~~~~~~ + +consumer/index.ts:180:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. + +180 const invalidComputedMethod: number = Methods[key]()(); +   ~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:181:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. + +181 const invalidNestedOuter: boolean = nestedString.outer; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:182:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +182 const invalidNestedInner: string = nestedString.inner; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:183:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + +183 nestedNumber.constrained("wrong"); +   ~~~~~~~ + +consumer/index.ts:184:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +184 const invalidMappedCycleValue: string = mappedCycle.Node.next.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:185:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +185 const invalidMutualCycleValue: number = mutualCycle.First.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:186:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +186 const invalidShadowedMappedValue: string = shadowedCycle.Node.next(1).next("text").value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:187:7 - error TS2322: Type 'null' is not assignable to type 'optionalCycle_recursive'. + +187 const invalidNullNext: OptionalNode["next"] = null; +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:188:7 - error TS2322: Type 'undefined' is not assignable to type 'optionalCycle_recursive'. -58 const invalid: number = arrow()()(); -   ~~~~~~~ +188 const invalidUndefinedNext: OptionalNode["next"] = undefined; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:59:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +consumer/index.ts:189:42 - error TS2531: Object is possibly 'null'. -59 const invalidExpression: number = expression()()(); -   ~~~~~~~~~~~~~~~~~ +189 const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:60:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. +consumer/index.ts:190:41 - error TS2533: Object is possibly 'null' or 'undefined'. -60 const invalidObject: number = objectReturn().call; -   ~~~~~~~~~~~~~ +190 const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:61:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. +consumer/index.ts:191:26 - error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -61 const invalidTuple: number = tupleReturn()[0]; -   ~~~~~~~~~~~~ +191 captured("text").consume(1); +   ~ -consumer/index.ts:62:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. +consumer/index.ts:192:7 - error TS2322: Type 'string' is not assignable to type 'number'. -62 const invalidShadowed: number = shadowed(1); -   ~~~~~~~~~~~~~~~ +192 const invalidRecursiveTupleValue: number = recursiveTuple("text")[1][0]; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:63:7 - error TS2322: Type 'number' is not assignable to type 'string'. +consumer/index.ts:193:7 - error TS2322: Type 'number' is not assignable to type 'string'. -63 const invalidObjectValue: string = object.next().value; -   ~~~~~~~~~~~~~~~~~~ +193 const invalidCapturedOuter: string = nestedCapturedValue.outer; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:64:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. +consumer/index.ts:194:7 - error TS2322: Type 'string' is not assignable to type 'number'. -64 const invalidTupleValue: number = tuple[0](); -   ~~~~~~~~~~~~~~~~~ +194 const invalidCapturedInner: number = nestedCapturedValue.inner; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:65:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:196:7 - error TS2322: Type 'boolean' is not assignable to type 'mixedUnionCycle_recursive'. -65 const invalidSpecialized: number = specialized.next().value; -   ~~~~~~~~~~~~~~~~~~ +196 const invalidMixedNext: WithoutFalseOrNullish["next"] = false; +   ~~~~~~~~~~~~~~~~ -consumer/index.ts:66:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. +consumer/index.ts:197:7 - error TS2322: Type 'string' is not assignable to type 'number'. -66 const invalidMapped: number = mapped.next; -   ~~~~~~~~~~~~~ +197 const invalidInferredCapturedValue: number = inferredCaptured<() => string>().next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:67:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:198:7 - error TS2322: Type 'number' is not assignable to type 'string'. -67 const invalidAnnotation: number = viaAnnotation.next().value; -   ~~~~~~~~~~~~~~~~~ +198 const invalidMappedCapturedValue: string = mappedCaptured<{ value: number }>().value.next.value.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:68:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:199:7 - error TS2322: Type 'number' is not assignable to type 'boolean'. -68 const invalidLink: number = nextLink.next.value; -   ~~~~~~~~~~~ +199 const invalidMutualCapturedValue: boolean = mutualCaptured(1, "text").right.self.next.left; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:69:7 - error TS2322: Type 'number' is not assignable to type 'string'. +consumer/index.ts:200:7 - error TS2322: Type 'string' is not assignable to type 'number'. -69 const invalidCallable: string = nextCallable(1).link.value; -   ~~~~~~~~~~~~~~~ +200 const invalidCapturedClassValue: number = capturedClassResult.outer; +   ~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:70:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:201:7 - error TS2322: Type 'covariantClass_recursive' is not assignable to type 'covariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. -70 const invalidHiddenValue: number = hiddenAlias.next.next.value; -   ~~~~~~~~~~~~~~~~~~ +201 const invalidCovariance: typeof covariantString = covariantUnknown.next(); +   ~~~~~~~~~~~~~~~~~ -consumer/index.ts:71:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. +consumer/index.ts:202:7 - error TS2322: Type 'contravariantClass_recursive' is not assignable to type 'contravariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. -71 const invalidMethod: number = Methods.recur()(); -   ~~~~~~~~~~~~~ +202 const invalidContravariance: typeof contravariantUnknown = contravariantString.next(); +   ~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:72:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. +consumer/index.ts:203:7 - error TS2322: Type 'anonymousThisReturn_recursive' is not assignable to type 'number'. -72 const invalidComputedMethod: number = Methods[key]()(); -   ~~~~~~~~~~~~~~~~~~~~~ +203 const invalidAnonymousThis: number = anonymousThisResult; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:73:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. +consumer/index.ts:204:7 - error TS2322: Type '() => anonymousThisReturn_recursive' is not assignable to type 'number'. -73 const invalidNestedOuter: boolean = nestedString.outer; -   ~~~~~~~~~~~~~~~~~~ +204 const invalidAnonymousThisMethod: number = anonymousThisResult.relyingOnThis; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:74:7 - error TS2322: Type 'number' is not assignable to type 'string'. +consumer/index.ts:205:7 - error TS2322: Type 'number' is not assignable to type 'string'. -74 const invalidNestedInner: string = nestedString.inner; -   ~~~~~~~~~~~~~~~~~~ +205 const invalidConditionalAlias: string = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:75:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +consumer/index.ts:206:7 - error TS2322: Type 'number' is not assignable to type 'number[]'. -75 nestedNumber.constrained("wrong"); -   ~~~~~~~ +206 const invalidConditionalAliasArray: number[] = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Found 18 errors in the same file, starting at: consumer/index.ts:58 +Found 40 errors in the same file, starting at: consumer/index.ts:166 //// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo] *rewrite with same content* //// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo.readable.baseline.txt] *rewrite with same content* @@ -755,6 +1682,7 @@ Found 18 errors in the same file, starting at: consumer/index.ts:58 consumer/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/producer/dist/recursive-conditional-utils.d.ts *refresh* /home/src/workspaces/project/producer/dist/index.d.ts *refresh* /home/src/workspaces/project/consumer/index.ts Signatures:: @@ -762,6 +1690,15 @@ Signatures:: Edit [1]:: add a comment to the producer //// [/home/src/workspaces/project/producer/index.ts] *modified* +import { f } from "./recursive-conditional-utils"; +export const conditionalAliasCopy = f; +export function anonymousThisReturn() { + return { + relyingOnThis() { + return this; + }, + }; +} export const arrow = () => arrow; export const expression = function self() { return self; }; export const first = () => second; @@ -839,108 +1776,366 @@ export const nestedOwner = { }, }; export const nestedNumber = nestedOwner.make(1); +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; +export const cycleKey = Symbol(); +export const keyedCycles = build<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; +}>(); +export const sharedCycles = { first: mappedCycle, second: mappedCycle }; +type ResolveMutual = Show<{ + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; +}>; +declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; +export const mutualCycle = buildMutual<{ + First: { value: number; next: { ref: "Second" } }; + Second: { value: string; next: { ref: "First" } }; +}>(); +type ResolveShadowed = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => ResolveShadowed : M[K][P]; +}>; +declare const buildShadowed: () => { [K in keyof M]: ResolveShadowed }; +export const shadowedCycle = buildShadowed<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptional: () => { [K in keyof M]?: Resolve }; +export const optionalCycle = buildOptional<{ Node: { value: number; next: "ref" } }>(); +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); +declare const wrap: (value: T) => { required: T; optional?: T | null }; +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKeys = buildNullable<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; +}>(); +declare const buildNullableRoot: () => Resolve | null; +export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalRoot: () => Resolve | undefined; +export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); +type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; +export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveOptional = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; +}>; +declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; +export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveNullish = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; +}>; +declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; +export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); +declare const buildMixed: () => { [K in keyof M]?: Resolve | false | null }; +export const mixedUnionCycle = buildMixed<{ Node: { value: number; next: "ref" } }>(); +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value: T) { + const node = { value, next: () => node, consume: (other: T) => node }; + return node; +} +export function nestedCaptured(outer: T) { + return (inner: U) => { + const node = { + outer, inner, next: () => node, + shadow: (value: T) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key: K) { + const node = { value: null! as T[K], next: () => node }; + return node; +} +export function optionalCaptured(value: T) { + type Node = { value: T; next: Node }; + return null! as { node?: Node | false | null }; +} +export function annotatedCaptured(value: T) { + const node: { value: typeof value; next: typeof node } = { value, next: null! }; + return node; +} +export function recursiveTuple(value: T) { + type Tuple = readonly [T, Tuple]; + return null! as Tuple; +} +export function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); +} +export function mappedCaptured() { + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; + return null! as Node; +} +export function freshGeneric(unused: T) { + const recur = (value: U) => recur; + return recur; +} +export function mutualCaptured(left: T, right: U) { + type Left = { left: T; next: Right }; + type Right = { right: U; self: Right; next: Left }; + return { left: null! as Left, right: null! as Right }; +} +export class CapturedClass { + constructor(public value: T) {} + make(inner: U) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value!: T; + next(): Node { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume!: (value: T) => void; + next(): Node { return this; } + }; +} +export namespace Nested { + export function captured(value: T) { + const node = { value, next: () => node }; + return node; + } +} +type NonNullable = "shadowed"; // comment-only edit tsgo --build consumer ExitStatus:: DiagnosticsPresent_OutputsGenerated Output:: -consumer/index.ts:58:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +consumer/index.ts:166:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +166 const invalid: number = arrow()()(); +   ~~~~~~~ + +consumer/index.ts:167:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +167 const invalidExpression: number = expression()()(); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:168:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. + +168 const invalidObject: number = objectReturn().call; +   ~~~~~~~~~~~~~ + +consumer/index.ts:169:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. + +169 const invalidTuple: number = tupleReturn()[0]; +   ~~~~~~~~~~~~ + +consumer/index.ts:170:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. + +170 const invalidShadowed: number = shadowed(1); +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:171:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +171 const invalidObjectValue: string = object.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:172:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. + +172 const invalidTupleValue: number = tuple[0](); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:173:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +173 const invalidSpecialized: number = specialized.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:174:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. + +174 const invalidMapped: number = mapped.next; +   ~~~~~~~~~~~~~ + +consumer/index.ts:175:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +175 const invalidAnnotation: number = viaAnnotation.next().value; +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:176:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +176 const invalidLink: number = nextLink.next.value; +   ~~~~~~~~~~~ + +consumer/index.ts:177:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +177 const invalidCallable: string = nextCallable(1).link.value; +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:178:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +178 const invalidHiddenValue: number = hiddenAlias.next.next.value; +   ~~~~~~~~~~~~~~~~~~ -58 const invalid: number = arrow()()(); -   ~~~~~~~ +consumer/index.ts:179:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. -consumer/index.ts:59:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +179 const invalidMethod: number = Methods.recur()(); +   ~~~~~~~~~~~~~ -59 const invalidExpression: number = expression()()(); -   ~~~~~~~~~~~~~~~~~ +consumer/index.ts:180:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. -consumer/index.ts:60:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. +180 const invalidComputedMethod: number = Methods[key]()(); +   ~~~~~~~~~~~~~~~~~~~~~ -60 const invalidObject: number = objectReturn().call; -   ~~~~~~~~~~~~~ +consumer/index.ts:181:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. -consumer/index.ts:61:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. +181 const invalidNestedOuter: boolean = nestedString.outer; +   ~~~~~~~~~~~~~~~~~~ -61 const invalidTuple: number = tupleReturn()[0]; -   ~~~~~~~~~~~~ +consumer/index.ts:182:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:62:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. +182 const invalidNestedInner: string = nestedString.inner; +   ~~~~~~~~~~~~~~~~~~ -62 const invalidShadowed: number = shadowed(1); -   ~~~~~~~~~~~~~~~ +consumer/index.ts:183:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -consumer/index.ts:63:7 - error TS2322: Type 'number' is not assignable to type 'string'. +183 nestedNumber.constrained("wrong"); +   ~~~~~~~ -63 const invalidObjectValue: string = object.next().value; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:184:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:64:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. +184 const invalidMappedCycleValue: string = mappedCycle.Node.next.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -64 const invalidTupleValue: number = tuple[0](); -   ~~~~~~~~~~~~~~~~~ +consumer/index.ts:185:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:65:7 - error TS2322: Type 'string' is not assignable to type 'number'. +185 const invalidMutualCycleValue: number = mutualCycle.First.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -65 const invalidSpecialized: number = specialized.next().value; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:186:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:66:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. +186 const invalidShadowedMappedValue: string = shadowedCycle.Node.next(1).next("text").value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -66 const invalidMapped: number = mapped.next; -   ~~~~~~~~~~~~~ +consumer/index.ts:187:7 - error TS2322: Type 'null' is not assignable to type 'optionalCycle_recursive'. -consumer/index.ts:67:7 - error TS2322: Type 'string' is not assignable to type 'number'. +187 const invalidNullNext: OptionalNode["next"] = null; +   ~~~~~~~~~~~~~~~ -67 const invalidAnnotation: number = viaAnnotation.next().value; -   ~~~~~~~~~~~~~~~~~ +consumer/index.ts:188:7 - error TS2322: Type 'undefined' is not assignable to type 'optionalCycle_recursive'. -consumer/index.ts:68:7 - error TS2322: Type 'string' is not assignable to type 'number'. +188 const invalidUndefinedNext: OptionalNode["next"] = undefined; +   ~~~~~~~~~~~~~~~~~~~~ -68 const invalidLink: number = nextLink.next.value; -   ~~~~~~~~~~~ +consumer/index.ts:189:42 - error TS2531: Object is possibly 'null'. -consumer/index.ts:69:7 - error TS2322: Type 'number' is not assignable to type 'string'. +189 const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~ -69 const invalidCallable: string = nextCallable(1).link.value; -   ~~~~~~~~~~~~~~~ +consumer/index.ts:190:41 - error TS2533: Object is possibly 'null' or 'undefined'. -consumer/index.ts:70:7 - error TS2322: Type 'string' is not assignable to type 'number'. +190 const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -70 const invalidHiddenValue: number = hiddenAlias.next.next.value; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:191:26 - error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -consumer/index.ts:71:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. +191 captured("text").consume(1); +   ~ -71 const invalidMethod: number = Methods.recur()(); -   ~~~~~~~~~~~~~ +consumer/index.ts:192:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:72:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. +192 const invalidRecursiveTupleValue: number = recursiveTuple("text")[1][0]; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -72 const invalidComputedMethod: number = Methods[key]()(); -   ~~~~~~~~~~~~~~~~~~~~~ +consumer/index.ts:193:7 - error TS2322: Type 'number' is not assignable to type 'string'. -consumer/index.ts:73:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. +193 const invalidCapturedOuter: string = nestedCapturedValue.outer; +   ~~~~~~~~~~~~~~~~~~~~ -73 const invalidNestedOuter: boolean = nestedString.outer; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:194:7 - error TS2322: Type 'string' is not assignable to type 'number'. -consumer/index.ts:74:7 - error TS2322: Type 'number' is not assignable to type 'string'. +194 const invalidCapturedInner: number = nestedCapturedValue.inner; +   ~~~~~~~~~~~~~~~~~~~~ -74 const invalidNestedInner: string = nestedString.inner; -   ~~~~~~~~~~~~~~~~~~ +consumer/index.ts:196:7 - error TS2322: Type 'boolean' is not assignable to type 'mixedUnionCycle_recursive'. -consumer/index.ts:75:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +196 const invalidMixedNext: WithoutFalseOrNullish["next"] = false; +   ~~~~~~~~~~~~~~~~ -75 nestedNumber.constrained("wrong"); -   ~~~~~~~ +consumer/index.ts:197:7 - error TS2322: Type 'string' is not assignable to type 'number'. +197 const invalidInferredCapturedValue: number = inferredCaptured<() => string>().next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Found 18 errors in the same file, starting at: consumer/index.ts:58 +consumer/index.ts:198:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +198 const invalidMappedCapturedValue: string = mappedCaptured<{ value: number }>().value.next.value.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:199:7 - error TS2322: Type 'number' is not assignable to type 'boolean'. + +199 const invalidMutualCapturedValue: boolean = mutualCaptured(1, "text").right.self.next.left; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:200:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +200 const invalidCapturedClassValue: number = capturedClassResult.outer; +   ~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:201:7 - error TS2322: Type 'covariantClass_recursive' is not assignable to type 'covariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. + +201 const invalidCovariance: typeof covariantString = covariantUnknown.next(); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:202:7 - error TS2322: Type 'contravariantClass_recursive' is not assignable to type 'contravariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. + +202 const invalidContravariance: typeof contravariantUnknown = contravariantString.next(); +   ~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:203:7 - error TS2322: Type 'anonymousThisReturn_recursive' is not assignable to type 'number'. + +203 const invalidAnonymousThis: number = anonymousThisResult; +   ~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:204:7 - error TS2322: Type '() => anonymousThisReturn_recursive' is not assignable to type 'number'. + +204 const invalidAnonymousThisMethod: number = anonymousThisResult.relyingOnThis; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:205:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +205 const invalidConditionalAlias: string = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:206:7 - error TS2322: Type 'number' is not assignable to type 'number[]'. + +206 const invalidConditionalAliasArray: number[] = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Found 40 errors in the same file, starting at: consumer/index.ts:166 //// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo] *rewrite with same content* //// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo.readable.baseline.txt] *rewrite with same content* //// [/home/src/workspaces/project/producer/dist/index.js] *modified* +import { f } from "./recursive-conditional-utils"; +export const conditionalAliasCopy = f; +export function anonymousThisReturn() { + return { + relyingOnThis() { + return this; + }, + }; +} export const arrow = () => arrow; export const expression = function self() { return self; }; export const first = () => second; @@ -1011,23 +2206,120 @@ export const nestedOwner = { }, }; export const nestedNumber = nestedOwner.make(1); +export const mappedCycle = build(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build() }; +export const cycleKey = Symbol(); +export const keyedCycles = build(); +export const sharedCycles = { first: mappedCycle, second: mappedCycle }; +export const mutualCycle = buildMutual(); +export const shadowedCycle = buildShadowed(); +export const optionalCycle = buildOptional(); +export const nullableCycle = buildNullable(); +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKeys = buildNullable(); +export const nullableRoot = buildNullableRoot(); +export const optionalRoot = buildOptionalRoot(); +export const nullableLinks = buildNullableLinks(); +export const optionalNullableLinks = buildOptionalNullableLinks(); +export const nullableOptionalLinks = buildNullableOptionalLinks(); +export const nullishLinks = buildNullishLinks(); +export const mixedUnionCycle = buildMixed(); +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value) { + const node = { value, next: () => node, consume: (other) => node }; + return node; +} +export function nestedCaptured(outer) { + return (inner) => { + const node = { + outer, inner, next: () => node, + shadow: (value) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key) { + const node = { value: null, next: () => node }; + return node; +} +export function optionalCaptured(value) { + return null; +} +export function annotatedCaptured(value) { + const node = { value, next: null }; + return node; +} +export function recursiveTuple(value) { + return null; +} +export function inferredCaptured() { + return null; +} +export function mappedCaptured() { + return null; +} +export function freshGeneric(unused) { + const recur = (value) => recur; + return recur; +} +export function mutualCaptured(left, right) { + return { left: null, right: null }; +} +export class CapturedClass { + value; + constructor(value) { + this.value = value; + } + make(inner) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value; + next() { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume; + next() { return this; } + }; +} +export var Nested; +(function (Nested) { + function captured(value) { + const node = { value, next: () => node }; + return node; + } + Nested.captured = captured; +})(Nested || (Nested = {})); // comment-only edit //// [/home/src/workspaces/project/producer/dist/tsconfig.tsbuildinfo] *modified* -{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"633d60bb4cc3a6318b4832fd7a0a90fd-export const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\n// comment-only edit\n","signature":"ac680f9630fda193ccd7e95d350590d1-export declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./","strict":true},"latestChangedDtsFile":"./index.d.ts"} +{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","../recursive-conditional-utils.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"5f612a8da522ce136561c99ba028217b-type Recursive = T extends Array ? Recursive : T;\nexport const f = (): Recursive => {\n return null!;\n};","signature":"b7e553848a0db56da7124d58387f207a-type Recursive = T extends Array ? Recursive : T;\nexport declare const f: () => Recursive;\nexport {};\n","impliedNodeFormat":1},{"version":"90c799933358055d40b311c2862a4ccf-import { f } from \"./recursive-conditional-utils\";\nexport const conditionalAliasCopy = f;\nexport function anonymousThisReturn() {\n return {\n relyingOnThis() {\n return this;\n },\n };\n}\nexport const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\ntype Show = { [K in keyof T]: T[K] } & unknown;\ntype Resolve = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? Resolve : M[K][P];\n}>;\ndeclare const build: () => { [K in keyof M]: Resolve };\nexport const mappedCycle = build<{ Node: { value: number; next: \"ref\" } }>();\nexport const mappedCycleCopy = mappedCycle;\nexport const nestedCycle = { wrapped: build<{ Node: { value: string; next: \"ref\" } }>() };\nexport const cycleKey = Symbol();\nexport const keyedCycles = build<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\nexport const sharedCycles = { first: mappedCycle, second: mappedCycle };\ntype ResolveMutual = Show<{\n [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P];\n}>;\ndeclare const buildMutual: () => { [K in keyof M]: ResolveMutual };\nexport const mutualCycle = buildMutual<{\n First: { value: number; next: { ref: \"Second\" } };\n Second: { value: string; next: { ref: \"First\" } };\n}>();\ntype ResolveShadowed = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? (shadowedCycle: T) => ResolveShadowed : M[K][P];\n}>;\ndeclare const buildShadowed: () => { [K in keyof M]: ResolveShadowed };\nexport const shadowedCycle = buildShadowed<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptional: () => { [K in keyof M]?: Resolve };\nexport const optionalCycle = buildOptional<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildNullable: () => { [K in keyof M]: Resolve | null };\nexport const nullableCycle = buildNullable<{ Node: { value: string; next: \"ref\" } }>();\ndeclare const wrap: (value: T) => { required: T; optional?: T | null };\nexport const mixedCycles = wrap(optionalCycle);\nexport const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle };\nexport const nullableKeys = buildNullable<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\ndeclare const buildNullableRoot: () => Resolve | null;\nexport const nullableRoot = buildNullableRoot<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalRoot: () => Resolve | undefined;\nexport const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: \"ref\" } }>();\ntype ResolveNullable = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullable | null : M[K][P];\n}>;\ndeclare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null };\nexport const nullableLinks = buildNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null };\nexport const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveOptional = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveOptional | undefined : M[K][P];\n}>;\ndeclare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null };\nexport const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveNullish = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullish | null | undefined : M[K][P];\n}>;\ndeclare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null };\nexport const nullishLinks = buildNullishLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildMixed: () => { [K in keyof M]?: Resolve | false | null };\nexport const mixedUnionCycle = buildMixed<{ Node: { value: number; next: \"ref\" } }>();\nexport const _recursive = 1;\nexport const factory = () => function self() { return self; };\nexport function captured(value: T) {\n const node = { value, next: () => node, consume: (other: T) => node };\n return node;\n}\nexport function nestedCaptured(outer: T) {\n return (inner: U) => {\n const node = {\n outer, inner, next: () => node,\n shadow: (value: T) => ({ outer, inner, value, next: node }),\n };\n return node;\n };\n}\nexport function constrained(key: K) {\n const node = { value: null! as T[K], next: () => node };\n return node;\n}\nexport function optionalCaptured(value: T) {\n type Node = { value: T; next: Node };\n return null! as { node?: Node | false | null };\n}\nexport function annotatedCaptured(value: T) {\n const node: { value: typeof value; next: typeof node } = { value, next: null! };\n return node;\n}\nexport function recursiveTuple(value: T) {\n type Tuple = readonly [T, Tuple];\n return null! as Tuple;\n}\nexport function inferredCaptured() {\n type Node = { value: V; next: Node };\n return null! as (T extends () => infer U ? Node : never);\n}\nexport function mappedCaptured() {\n type Node = { [K in keyof T]: { value: T[K]; next: Node } };\n return null! as Node;\n}\nexport function freshGeneric(unused: T) {\n const recur = (value: U) => recur;\n return recur;\n}\nexport function mutualCaptured(left: T, right: U) {\n type Left = { left: T; next: Right };\n type Right = { right: U; self: Right; next: Left };\n return { left: null! as Left, right: null! as Right };\n}\nexport class CapturedClass {\n constructor(public value: T) {}\n make(inner: U) {\n const node = { outer: this.value, inner, next: () => node };\n return node;\n }\n}\nexport function covariantClass() {\n return class Node {\n value!: T;\n next(): Node { return this; }\n };\n}\nexport function contravariantClass() {\n return class Node {\n consume!: (value: T) => void;\n next(): Node { return this; }\n };\n}\nexport namespace Nested {\n export function captured(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}\ntype NonNullable = \"shadowed\";\n// comment-only edit\n","signature":"8fc541a8e5c6c5e8f531954fb3ccef01-type anonymousThisReturn_recursive = {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\ntype optionalCycle_recursive = {\n value: number;\n next: optionalCycle_recursive;\n};\ntype nullableCycle_recursive = {\n value: string;\n next: nullableCycle_recursive;\n};\ntype mixedCycles_recursive = {\n value: number;\n next: mixedCycles_recursive;\n};\ntype sharedOptionalCycles_recursive = {\n value: number;\n next: sharedOptionalCycles_recursive;\n};\ntype nullableKeys_recursive = {\n value: string;\n next: nullableKeys_recursive;\n};\ntype nullableKeys_recursive_1 = {\n value: boolean;\n next: nullableKeys_recursive_1;\n};\ntype nullableKeys_recursive_2 = {\n value: number;\n next: nullableKeys_recursive_2;\n};\ntype nullableRoot_recursive = {\n value: number;\n next: nullableRoot_recursive;\n};\ntype optionalRoot_recursive = {\n value: string;\n next: optionalRoot_recursive;\n};\ntype optionalNullableLinks_recursive = {\n value: number;\n next: optionalNullableLinks_recursive | null;\n};\ntype nullableOptionalLinks_recursive = {\n value: number;\n next: nullableOptionalLinks_recursive | undefined;\n};\ntype nullishLinks_recursive = {\n value: number;\n next: nullishLinks_recursive | null | undefined;\n};\ntype mixedUnionCycle_recursive = {\n value: number;\n next: mixedUnionCycle_recursive;\n};\ntype factory_recursive = () => factory_recursive;\ntype captured_recursive = {\n value: T;\n next: () => captured_recursive;\n consume: (other: T) => captured_recursive;\n};\ntype nestedCaptured_recursive = {\n outer: T;\n inner: U;\n next: () => nestedCaptured_recursive;\n shadow: (value: T_1) => {\n outer: T;\n inner: U;\n value: T_1;\n next: nestedCaptured_recursive;\n };\n};\ntype constrained_recursive = {\n value: T[K];\n next: () => constrained_recursive;\n};\ntype optionalCaptured_recursive = {\n value: T;\n next: optionalCaptured_recursive;\n};\ntype annotatedCaptured_recursive = {\n value: T;\n next: annotatedCaptured_recursive;\n};\ntype recursiveTuple_recursive = readonly [T, recursiveTuple_recursive];\ntype inferredCaptured_recursive = {\n value: U;\n next: inferredCaptured_recursive;\n};\ntype mappedCaptured_recursive = { [K in keyof T]: {\n value: T[K];\n next: mappedCaptured_recursive;\n}; };\ntype freshGeneric_recursive = (value: U) => freshGeneric_recursive;\ntype mutualCaptured_recursive = {\n right: U;\n self: mutualCaptured_recursive;\n next: mutualCaptured_recursive_1;\n};\ntype mutualCaptured_recursive_1 = {\n left: T;\n next: mutualCaptured_recursive;\n};\ntype CapturedClass_make_recursive = {\n outer: T;\n inner: U;\n next: () => CapturedClass_make_recursive;\n};\ntype covariantClass_recursive = {\n value: T;\n next(): covariantClass_recursive;\n};\ntype contravariantClass_recursive = {\n consume: (value: T) => void;\n next(): contravariantClass_recursive;\n};\nimport { f } from \"./recursive-conditional-utils\";\nexport declare const conditionalAliasCopy: typeof f;\nexport declare function anonymousThisReturn(): {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\nexport declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\nexport declare const mappedCycle: {\n Node: {\n value: number;\n next: (typeof mappedCycle)[\"Node\"];\n };\n};\nexport declare const mappedCycleCopy: {\n Node: {\n value: number;\n next: (typeof mappedCycleCopy)[\"Node\"];\n };\n};\nexport declare const nestedCycle: {\n wrapped: {\n Node: {\n value: string;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n};\nexport declare const cycleKey: unique symbol;\nexport declare const keyedCycles: {\n \"a-b\": {\n value: string;\n next: (typeof keyedCycles)[\"a-b\"];\n };\n 0: {\n value: boolean;\n next: (typeof keyedCycles)[0];\n };\n [cycleKey]: {\n value: number;\n next: (typeof keyedCycles)[typeof cycleKey];\n };\n};\nexport declare const sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n};\nexport declare const mutualCycle: {\n First: {\n value: number;\n next: {\n value: string;\n next: (typeof mutualCycle)[\"First\"];\n };\n };\n Second: {\n value: string;\n next: {\n value: number;\n next: (typeof mutualCycle)[\"Second\"];\n };\n };\n};\nexport declare const shadowedCycle: {\n Node: {\n value: number;\n next: (shadowedCycle: T) => typeof import(\".\").shadowedCycle[\"Node\"];\n };\n};\nexport declare const optionalCycle: {\n Node?: optionalCycle_recursive;\n};\nexport declare const nullableCycle: {\n Node: nullableCycle_recursive | null;\n};\nexport declare const mixedCycles: {\n required: {\n Node?: mixedCycles_recursive;\n };\n optional?: {\n Node?: mixedCycles_recursive;\n } | null;\n};\nexport declare const sharedOptionalCycles: {\n first: {\n Node?: sharedOptionalCycles_recursive;\n };\n second: {\n Node?: sharedOptionalCycles_recursive;\n };\n};\nexport declare const nullableKeys: {\n \"a-b\": nullableKeys_recursive | null;\n 0: nullableKeys_recursive_1 | null;\n [cycleKey]: nullableKeys_recursive_2 | null;\n};\nexport declare const nullableRoot: nullableRoot_recursive | null;\nexport declare const optionalRoot: optionalRoot_recursive | undefined;\nexport declare const nullableLinks: {\n Node: {\n value: number;\n next: (typeof nullableLinks)[\"Node\"];\n } | null;\n};\nexport declare const optionalNullableLinks: {\n Node?: optionalNullableLinks_recursive | null;\n};\nexport declare const nullableOptionalLinks: {\n Node: nullableOptionalLinks_recursive | null;\n};\nexport declare const nullishLinks: {\n Node?: nullishLinks_recursive | null;\n};\nexport declare const mixedUnionCycle: {\n Node?: false | mixedUnionCycle_recursive | null;\n};\nexport declare const _recursive = 1;\nexport declare const factory: () => () => factory_recursive;\nexport declare function captured(value: T): captured_recursive;\nexport declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive;\nexport declare function constrained(key: K): constrained_recursive;\nexport declare function optionalCaptured(value: T): {\n node?: optionalCaptured_recursive | false | null;\n};\nexport declare function annotatedCaptured(value: T): annotatedCaptured_recursive;\nexport declare function recursiveTuple(value: T): recursiveTuple_recursive;\nexport declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never);\nexport declare function mappedCaptured(): mappedCaptured_recursive;\nexport declare function freshGeneric(unused: T): freshGeneric_recursive;\nexport declare function mutualCaptured(left: T, right: U): {\n left: mutualCaptured_recursive_1;\n right: mutualCaptured_recursive;\n};\nexport declare class CapturedClass {\n value: T;\n constructor(value: T);\n make(inner: U): CapturedClass_make_recursive;\n}\nexport declare function covariantClass(): {\n new (): covariantClass_recursive;\n};\nexport declare function contravariantClass(): {\n new (): contravariantClass_recursive;\n};\nexport declare namespace Nested {\n type captured_recursive_1 = {\n value: T;\n next: () => captured_recursive_1;\n };\n export function captured(value: T): captured_recursive_1;\n export {};\n}\nexport {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"exactOptionalPropertyTypes":true,"outDir":"./","strict":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./index.d.ts"} //// [/home/src/workspaces/project/producer/dist/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* { "version": "FakeTSVersion", "root": [ { "files": [ + "../recursive-conditional-utils.ts", "../index.ts" ], - "original": 2 + "original": [ + 2, + 3 + ] } ], "fileNames": [ "lib.es2026.full.d.ts", + "../recursive-conditional-utils.ts", "../index.ts" ], "fileInfos": [ @@ -1043,25 +2335,47 @@ export const nestedNumber = nestedOwner.make(1); "impliedNodeFormat": 1 } }, + { + "fileName": "../recursive-conditional-utils.ts", + "version": "5f612a8da522ce136561c99ba028217b-type Recursive = T extends Array ? Recursive : T;\nexport const f = (): Recursive => {\n return null!;\n};", + "signature": "b7e553848a0db56da7124d58387f207a-type Recursive = T extends Array ? Recursive : T;\nexport declare const f: () => Recursive;\nexport {};\n", + "impliedNodeFormat": "CommonJS", + "original": { + "version": "5f612a8da522ce136561c99ba028217b-type Recursive = T extends Array ? Recursive : T;\nexport const f = (): Recursive => {\n return null!;\n};", + "signature": "b7e553848a0db56da7124d58387f207a-type Recursive = T extends Array ? Recursive : T;\nexport declare const f: () => Recursive;\nexport {};\n", + "impliedNodeFormat": 1 + } + }, { "fileName": "../index.ts", - "version": "633d60bb4cc3a6318b4832fd7a0a90fd-export const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\n// comment-only edit\n", - "signature": "ac680f9630fda193ccd7e95d350590d1-export declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\n", + "version": "90c799933358055d40b311c2862a4ccf-import { f } from \"./recursive-conditional-utils\";\nexport const conditionalAliasCopy = f;\nexport function anonymousThisReturn() {\n return {\n relyingOnThis() {\n return this;\n },\n };\n}\nexport const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\ntype Show = { [K in keyof T]: T[K] } & unknown;\ntype Resolve = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? Resolve : M[K][P];\n}>;\ndeclare const build: () => { [K in keyof M]: Resolve };\nexport const mappedCycle = build<{ Node: { value: number; next: \"ref\" } }>();\nexport const mappedCycleCopy = mappedCycle;\nexport const nestedCycle = { wrapped: build<{ Node: { value: string; next: \"ref\" } }>() };\nexport const cycleKey = Symbol();\nexport const keyedCycles = build<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\nexport const sharedCycles = { first: mappedCycle, second: mappedCycle };\ntype ResolveMutual = Show<{\n [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P];\n}>;\ndeclare const buildMutual: () => { [K in keyof M]: ResolveMutual };\nexport const mutualCycle = buildMutual<{\n First: { value: number; next: { ref: \"Second\" } };\n Second: { value: string; next: { ref: \"First\" } };\n}>();\ntype ResolveShadowed = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? (shadowedCycle: T) => ResolveShadowed : M[K][P];\n}>;\ndeclare const buildShadowed: () => { [K in keyof M]: ResolveShadowed };\nexport const shadowedCycle = buildShadowed<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptional: () => { [K in keyof M]?: Resolve };\nexport const optionalCycle = buildOptional<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildNullable: () => { [K in keyof M]: Resolve | null };\nexport const nullableCycle = buildNullable<{ Node: { value: string; next: \"ref\" } }>();\ndeclare const wrap: (value: T) => { required: T; optional?: T | null };\nexport const mixedCycles = wrap(optionalCycle);\nexport const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle };\nexport const nullableKeys = buildNullable<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\ndeclare const buildNullableRoot: () => Resolve | null;\nexport const nullableRoot = buildNullableRoot<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalRoot: () => Resolve | undefined;\nexport const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: \"ref\" } }>();\ntype ResolveNullable = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullable | null : M[K][P];\n}>;\ndeclare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null };\nexport const nullableLinks = buildNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null };\nexport const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveOptional = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveOptional | undefined : M[K][P];\n}>;\ndeclare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null };\nexport const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveNullish = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullish | null | undefined : M[K][P];\n}>;\ndeclare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null };\nexport const nullishLinks = buildNullishLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildMixed: () => { [K in keyof M]?: Resolve | false | null };\nexport const mixedUnionCycle = buildMixed<{ Node: { value: number; next: \"ref\" } }>();\nexport const _recursive = 1;\nexport const factory = () => function self() { return self; };\nexport function captured(value: T) {\n const node = { value, next: () => node, consume: (other: T) => node };\n return node;\n}\nexport function nestedCaptured(outer: T) {\n return (inner: U) => {\n const node = {\n outer, inner, next: () => node,\n shadow: (value: T) => ({ outer, inner, value, next: node }),\n };\n return node;\n };\n}\nexport function constrained(key: K) {\n const node = { value: null! as T[K], next: () => node };\n return node;\n}\nexport function optionalCaptured(value: T) {\n type Node = { value: T; next: Node };\n return null! as { node?: Node | false | null };\n}\nexport function annotatedCaptured(value: T) {\n const node: { value: typeof value; next: typeof node } = { value, next: null! };\n return node;\n}\nexport function recursiveTuple(value: T) {\n type Tuple = readonly [T, Tuple];\n return null! as Tuple;\n}\nexport function inferredCaptured() {\n type Node = { value: V; next: Node };\n return null! as (T extends () => infer U ? Node : never);\n}\nexport function mappedCaptured() {\n type Node = { [K in keyof T]: { value: T[K]; next: Node } };\n return null! as Node;\n}\nexport function freshGeneric(unused: T) {\n const recur = (value: U) => recur;\n return recur;\n}\nexport function mutualCaptured(left: T, right: U) {\n type Left = { left: T; next: Right };\n type Right = { right: U; self: Right; next: Left };\n return { left: null! as Left, right: null! as Right };\n}\nexport class CapturedClass {\n constructor(public value: T) {}\n make(inner: U) {\n const node = { outer: this.value, inner, next: () => node };\n return node;\n }\n}\nexport function covariantClass() {\n return class Node {\n value!: T;\n next(): Node { return this; }\n };\n}\nexport function contravariantClass() {\n return class Node {\n consume!: (value: T) => void;\n next(): Node { return this; }\n };\n}\nexport namespace Nested {\n export function captured(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}\ntype NonNullable = \"shadowed\";\n// comment-only edit\n", + "signature": "8fc541a8e5c6c5e8f531954fb3ccef01-type anonymousThisReturn_recursive = {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\ntype optionalCycle_recursive = {\n value: number;\n next: optionalCycle_recursive;\n};\ntype nullableCycle_recursive = {\n value: string;\n next: nullableCycle_recursive;\n};\ntype mixedCycles_recursive = {\n value: number;\n next: mixedCycles_recursive;\n};\ntype sharedOptionalCycles_recursive = {\n value: number;\n next: sharedOptionalCycles_recursive;\n};\ntype nullableKeys_recursive = {\n value: string;\n next: nullableKeys_recursive;\n};\ntype nullableKeys_recursive_1 = {\n value: boolean;\n next: nullableKeys_recursive_1;\n};\ntype nullableKeys_recursive_2 = {\n value: number;\n next: nullableKeys_recursive_2;\n};\ntype nullableRoot_recursive = {\n value: number;\n next: nullableRoot_recursive;\n};\ntype optionalRoot_recursive = {\n value: string;\n next: optionalRoot_recursive;\n};\ntype optionalNullableLinks_recursive = {\n value: number;\n next: optionalNullableLinks_recursive | null;\n};\ntype nullableOptionalLinks_recursive = {\n value: number;\n next: nullableOptionalLinks_recursive | undefined;\n};\ntype nullishLinks_recursive = {\n value: number;\n next: nullishLinks_recursive | null | undefined;\n};\ntype mixedUnionCycle_recursive = {\n value: number;\n next: mixedUnionCycle_recursive;\n};\ntype factory_recursive = () => factory_recursive;\ntype captured_recursive = {\n value: T;\n next: () => captured_recursive;\n consume: (other: T) => captured_recursive;\n};\ntype nestedCaptured_recursive = {\n outer: T;\n inner: U;\n next: () => nestedCaptured_recursive;\n shadow: (value: T_1) => {\n outer: T;\n inner: U;\n value: T_1;\n next: nestedCaptured_recursive;\n };\n};\ntype constrained_recursive = {\n value: T[K];\n next: () => constrained_recursive;\n};\ntype optionalCaptured_recursive = {\n value: T;\n next: optionalCaptured_recursive;\n};\ntype annotatedCaptured_recursive = {\n value: T;\n next: annotatedCaptured_recursive;\n};\ntype recursiveTuple_recursive = readonly [T, recursiveTuple_recursive];\ntype inferredCaptured_recursive = {\n value: U;\n next: inferredCaptured_recursive;\n};\ntype mappedCaptured_recursive = { [K in keyof T]: {\n value: T[K];\n next: mappedCaptured_recursive;\n}; };\ntype freshGeneric_recursive = (value: U) => freshGeneric_recursive;\ntype mutualCaptured_recursive = {\n right: U;\n self: mutualCaptured_recursive;\n next: mutualCaptured_recursive_1;\n};\ntype mutualCaptured_recursive_1 = {\n left: T;\n next: mutualCaptured_recursive;\n};\ntype CapturedClass_make_recursive = {\n outer: T;\n inner: U;\n next: () => CapturedClass_make_recursive;\n};\ntype covariantClass_recursive = {\n value: T;\n next(): covariantClass_recursive;\n};\ntype contravariantClass_recursive = {\n consume: (value: T) => void;\n next(): contravariantClass_recursive;\n};\nimport { f } from \"./recursive-conditional-utils\";\nexport declare const conditionalAliasCopy: typeof f;\nexport declare function anonymousThisReturn(): {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\nexport declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\nexport declare const mappedCycle: {\n Node: {\n value: number;\n next: (typeof mappedCycle)[\"Node\"];\n };\n};\nexport declare const mappedCycleCopy: {\n Node: {\n value: number;\n next: (typeof mappedCycleCopy)[\"Node\"];\n };\n};\nexport declare const nestedCycle: {\n wrapped: {\n Node: {\n value: string;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n};\nexport declare const cycleKey: unique symbol;\nexport declare const keyedCycles: {\n \"a-b\": {\n value: string;\n next: (typeof keyedCycles)[\"a-b\"];\n };\n 0: {\n value: boolean;\n next: (typeof keyedCycles)[0];\n };\n [cycleKey]: {\n value: number;\n next: (typeof keyedCycles)[typeof cycleKey];\n };\n};\nexport declare const sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n};\nexport declare const mutualCycle: {\n First: {\n value: number;\n next: {\n value: string;\n next: (typeof mutualCycle)[\"First\"];\n };\n };\n Second: {\n value: string;\n next: {\n value: number;\n next: (typeof mutualCycle)[\"Second\"];\n };\n };\n};\nexport declare const shadowedCycle: {\n Node: {\n value: number;\n next: (shadowedCycle: T) => typeof import(\".\").shadowedCycle[\"Node\"];\n };\n};\nexport declare const optionalCycle: {\n Node?: optionalCycle_recursive;\n};\nexport declare const nullableCycle: {\n Node: nullableCycle_recursive | null;\n};\nexport declare const mixedCycles: {\n required: {\n Node?: mixedCycles_recursive;\n };\n optional?: {\n Node?: mixedCycles_recursive;\n } | null;\n};\nexport declare const sharedOptionalCycles: {\n first: {\n Node?: sharedOptionalCycles_recursive;\n };\n second: {\n Node?: sharedOptionalCycles_recursive;\n };\n};\nexport declare const nullableKeys: {\n \"a-b\": nullableKeys_recursive | null;\n 0: nullableKeys_recursive_1 | null;\n [cycleKey]: nullableKeys_recursive_2 | null;\n};\nexport declare const nullableRoot: nullableRoot_recursive | null;\nexport declare const optionalRoot: optionalRoot_recursive | undefined;\nexport declare const nullableLinks: {\n Node: {\n value: number;\n next: (typeof nullableLinks)[\"Node\"];\n } | null;\n};\nexport declare const optionalNullableLinks: {\n Node?: optionalNullableLinks_recursive | null;\n};\nexport declare const nullableOptionalLinks: {\n Node: nullableOptionalLinks_recursive | null;\n};\nexport declare const nullishLinks: {\n Node?: nullishLinks_recursive | null;\n};\nexport declare const mixedUnionCycle: {\n Node?: false | mixedUnionCycle_recursive | null;\n};\nexport declare const _recursive = 1;\nexport declare const factory: () => () => factory_recursive;\nexport declare function captured(value: T): captured_recursive;\nexport declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive;\nexport declare function constrained(key: K): constrained_recursive;\nexport declare function optionalCaptured(value: T): {\n node?: optionalCaptured_recursive | false | null;\n};\nexport declare function annotatedCaptured(value: T): annotatedCaptured_recursive;\nexport declare function recursiveTuple(value: T): recursiveTuple_recursive;\nexport declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never);\nexport declare function mappedCaptured(): mappedCaptured_recursive;\nexport declare function freshGeneric(unused: T): freshGeneric_recursive;\nexport declare function mutualCaptured(left: T, right: U): {\n left: mutualCaptured_recursive_1;\n right: mutualCaptured_recursive;\n};\nexport declare class CapturedClass {\n value: T;\n constructor(value: T);\n make(inner: U): CapturedClass_make_recursive;\n}\nexport declare function covariantClass(): {\n new (): covariantClass_recursive;\n};\nexport declare function contravariantClass(): {\n new (): contravariantClass_recursive;\n};\nexport declare namespace Nested {\n type captured_recursive_1 = {\n value: T;\n next: () => captured_recursive_1;\n };\n export function captured(value: T): captured_recursive_1;\n export {};\n}\nexport {};\n", "impliedNodeFormat": "CommonJS", "original": { - "version": "633d60bb4cc3a6318b4832fd7a0a90fd-export const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\n// comment-only edit\n", - "signature": "ac680f9630fda193ccd7e95d350590d1-export declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\n", + "version": "90c799933358055d40b311c2862a4ccf-import { f } from \"./recursive-conditional-utils\";\nexport const conditionalAliasCopy = f;\nexport function anonymousThisReturn() {\n return {\n relyingOnThis() {\n return this;\n },\n };\n}\nexport const arrow = () => arrow;\nexport const expression = function self() { return self; };\nexport const first = () => second;\nexport const second = () => first;\nexport const generic = (value: T) => generic;\nexport const objectReturn = () => ({ call: objectReturn });\nexport const tupleReturn = () => [tupleReturn] as const;\nexport const shadowed = function self(shadowed: number) { return self; };\nexport const object = { value: 1, next: () => object };\nexport const method = { value: 1, next() { return method; } };\nexport const accessor = { value: 1, get next() { return accessor; } };\nexport const tuple = [() => tuple] as const;\nexport const array = [() => array];\nexport const nested = { inner: { next() { return nested.inner; } } };\nexport const memberTuple = [function self() { return self; }] as const;\nexport const memberArray = [function self() { return self; }];\nexport const quoted = { \"a-b\": function self() { return self; } };\nexport const numeric = { 0: function self() { return self; } };\nexport const key = Symbol();\nexport const computed = { [key]: function self() { return self; } };\nexport const union = true as boolean ? { next: () => union } : undefined;\nfunction create(value: T) {\n const result = { value, next: () => result };\n return result;\n}\nexport const specialized = create(\"text\");\nfunction createIndexed() {\n const value: { [key: string]: typeof value } = {};\n return value;\n}\nexport const indexed = createIndexed();\nfunction createMapped() {\n const value: { [K in keyof T]: typeof value } = null!;\n return value;\n}\nexport const mapped = createMapped<{ next: unknown }>();\nfunction createAnnotated(value: T) {\n const node: { value: T; next: () => typeof node } = { value, next: () => node };\n return node;\n}\nexport const viaAnnotation = createAnnotated(\"text\");\nexport type Link = { value: T; next: Link };\nexport type Callable = { (value: T): Callable; link: Link };\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport const nextLink = link.next;\nexport const nextCallable = callable(1);\nfunction createHidden(value: T) {\n type Hidden = { value: T; next: Hidden };\n return null! as Hidden;\n}\nexport const hiddenAlias = createHidden(\"text\");\nexport const siblingHiddenAliases = { first: hiddenAlias, second: hiddenAlias };\nexport const parenthesized = (function self() { return self; });\nexport const asserted = (function self() { return self; }) satisfies () => unknown;\nexport class Methods {\n static recur() { return Methods.recur; }\n static \"a-b\"() { return Methods[\"a-b\"]; }\n static [key]() { return Methods[key]; }\n recur() { return this.recur; }\n}\nexport function overloaded(value: string): typeof overloaded;\nexport function overloaded(value: number): typeof overloaded;\nexport function overloaded(value: string | number) { return overloaded; }\nexport const nestedOwner = {\n make(outer: T) {\n return {\n nested(inner: U) { return { outer, inner, owner: nestedOwner }; },\n constrained(inner: U) { return { outer, inner, owner: nestedOwner }; },\n copied(inner: U): { outer: T; inner: U; owner: typeof nestedOwner } {\n return { outer, inner, owner: nestedOwner };\n },\n rest(...values: [U]) { return { outer, inner: values[0], owner: nestedOwner }; },\n };\n },\n};\nexport const nestedNumber = nestedOwner.make(1);\ntype Show = { [K in keyof T]: T[K] } & unknown;\ntype Resolve = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? Resolve : M[K][P];\n}>;\ndeclare const build: () => { [K in keyof M]: Resolve };\nexport const mappedCycle = build<{ Node: { value: number; next: \"ref\" } }>();\nexport const mappedCycleCopy = mappedCycle;\nexport const nestedCycle = { wrapped: build<{ Node: { value: string; next: \"ref\" } }>() };\nexport const cycleKey = Symbol();\nexport const keyedCycles = build<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\nexport const sharedCycles = { first: mappedCycle, second: mappedCycle };\ntype ResolveMutual = Show<{\n [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P];\n}>;\ndeclare const buildMutual: () => { [K in keyof M]: ResolveMutual };\nexport const mutualCycle = buildMutual<{\n First: { value: number; next: { ref: \"Second\" } };\n Second: { value: string; next: { ref: \"First\" } };\n}>();\ntype ResolveShadowed = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? (shadowedCycle: T) => ResolveShadowed : M[K][P];\n}>;\ndeclare const buildShadowed: () => { [K in keyof M]: ResolveShadowed };\nexport const shadowedCycle = buildShadowed<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptional: () => { [K in keyof M]?: Resolve };\nexport const optionalCycle = buildOptional<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildNullable: () => { [K in keyof M]: Resolve | null };\nexport const nullableCycle = buildNullable<{ Node: { value: string; next: \"ref\" } }>();\ndeclare const wrap: (value: T) => { required: T; optional?: T | null };\nexport const mixedCycles = wrap(optionalCycle);\nexport const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle };\nexport const nullableKeys = buildNullable<{\n \"a-b\": { value: string; next: \"ref\" };\n 0: { value: boolean; next: \"ref\" };\n [cycleKey]: { value: number; next: \"ref\" };\n}>();\ndeclare const buildNullableRoot: () => Resolve | null;\nexport const nullableRoot = buildNullableRoot<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalRoot: () => Resolve | undefined;\nexport const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: \"ref\" } }>();\ntype ResolveNullable = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullable | null : M[K][P];\n}>;\ndeclare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null };\nexport const nullableLinks = buildNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null };\nexport const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveOptional = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveOptional | undefined : M[K][P];\n}>;\ndeclare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null };\nexport const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: \"ref\" } }>();\ntype ResolveNullish = Show<{\n [P in keyof M[K]]: M[K][P] extends \"ref\" ? ResolveNullish | null | undefined : M[K][P];\n}>;\ndeclare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null };\nexport const nullishLinks = buildNullishLinks<{ Node: { value: number; next: \"ref\" } }>();\ndeclare const buildMixed: () => { [K in keyof M]?: Resolve | false | null };\nexport const mixedUnionCycle = buildMixed<{ Node: { value: number; next: \"ref\" } }>();\nexport const _recursive = 1;\nexport const factory = () => function self() { return self; };\nexport function captured(value: T) {\n const node = { value, next: () => node, consume: (other: T) => node };\n return node;\n}\nexport function nestedCaptured(outer: T) {\n return (inner: U) => {\n const node = {\n outer, inner, next: () => node,\n shadow: (value: T) => ({ outer, inner, value, next: node }),\n };\n return node;\n };\n}\nexport function constrained(key: K) {\n const node = { value: null! as T[K], next: () => node };\n return node;\n}\nexport function optionalCaptured(value: T) {\n type Node = { value: T; next: Node };\n return null! as { node?: Node | false | null };\n}\nexport function annotatedCaptured(value: T) {\n const node: { value: typeof value; next: typeof node } = { value, next: null! };\n return node;\n}\nexport function recursiveTuple(value: T) {\n type Tuple = readonly [T, Tuple];\n return null! as Tuple;\n}\nexport function inferredCaptured() {\n type Node = { value: V; next: Node };\n return null! as (T extends () => infer U ? Node : never);\n}\nexport function mappedCaptured() {\n type Node = { [K in keyof T]: { value: T[K]; next: Node } };\n return null! as Node;\n}\nexport function freshGeneric(unused: T) {\n const recur = (value: U) => recur;\n return recur;\n}\nexport function mutualCaptured(left: T, right: U) {\n type Left = { left: T; next: Right };\n type Right = { right: U; self: Right; next: Left };\n return { left: null! as Left, right: null! as Right };\n}\nexport class CapturedClass {\n constructor(public value: T) {}\n make(inner: U) {\n const node = { outer: this.value, inner, next: () => node };\n return node;\n }\n}\nexport function covariantClass() {\n return class Node {\n value!: T;\n next(): Node { return this; }\n };\n}\nexport function contravariantClass() {\n return class Node {\n consume!: (value: T) => void;\n next(): Node { return this; }\n };\n}\nexport namespace Nested {\n export function captured(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}\ntype NonNullable = \"shadowed\";\n// comment-only edit\n", + "signature": "8fc541a8e5c6c5e8f531954fb3ccef01-type anonymousThisReturn_recursive = {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\ntype optionalCycle_recursive = {\n value: number;\n next: optionalCycle_recursive;\n};\ntype nullableCycle_recursive = {\n value: string;\n next: nullableCycle_recursive;\n};\ntype mixedCycles_recursive = {\n value: number;\n next: mixedCycles_recursive;\n};\ntype sharedOptionalCycles_recursive = {\n value: number;\n next: sharedOptionalCycles_recursive;\n};\ntype nullableKeys_recursive = {\n value: string;\n next: nullableKeys_recursive;\n};\ntype nullableKeys_recursive_1 = {\n value: boolean;\n next: nullableKeys_recursive_1;\n};\ntype nullableKeys_recursive_2 = {\n value: number;\n next: nullableKeys_recursive_2;\n};\ntype nullableRoot_recursive = {\n value: number;\n next: nullableRoot_recursive;\n};\ntype optionalRoot_recursive = {\n value: string;\n next: optionalRoot_recursive;\n};\ntype optionalNullableLinks_recursive = {\n value: number;\n next: optionalNullableLinks_recursive | null;\n};\ntype nullableOptionalLinks_recursive = {\n value: number;\n next: nullableOptionalLinks_recursive | undefined;\n};\ntype nullishLinks_recursive = {\n value: number;\n next: nullishLinks_recursive | null | undefined;\n};\ntype mixedUnionCycle_recursive = {\n value: number;\n next: mixedUnionCycle_recursive;\n};\ntype factory_recursive = () => factory_recursive;\ntype captured_recursive = {\n value: T;\n next: () => captured_recursive;\n consume: (other: T) => captured_recursive;\n};\ntype nestedCaptured_recursive = {\n outer: T;\n inner: U;\n next: () => nestedCaptured_recursive;\n shadow: (value: T_1) => {\n outer: T;\n inner: U;\n value: T_1;\n next: nestedCaptured_recursive;\n };\n};\ntype constrained_recursive = {\n value: T[K];\n next: () => constrained_recursive;\n};\ntype optionalCaptured_recursive = {\n value: T;\n next: optionalCaptured_recursive;\n};\ntype annotatedCaptured_recursive = {\n value: T;\n next: annotatedCaptured_recursive;\n};\ntype recursiveTuple_recursive = readonly [T, recursiveTuple_recursive];\ntype inferredCaptured_recursive = {\n value: U;\n next: inferredCaptured_recursive;\n};\ntype mappedCaptured_recursive = { [K in keyof T]: {\n value: T[K];\n next: mappedCaptured_recursive;\n}; };\ntype freshGeneric_recursive = (value: U) => freshGeneric_recursive;\ntype mutualCaptured_recursive = {\n right: U;\n self: mutualCaptured_recursive;\n next: mutualCaptured_recursive_1;\n};\ntype mutualCaptured_recursive_1 = {\n left: T;\n next: mutualCaptured_recursive;\n};\ntype CapturedClass_make_recursive = {\n outer: T;\n inner: U;\n next: () => CapturedClass_make_recursive;\n};\ntype covariantClass_recursive = {\n value: T;\n next(): covariantClass_recursive;\n};\ntype contravariantClass_recursive = {\n consume: (value: T) => void;\n next(): contravariantClass_recursive;\n};\nimport { f } from \"./recursive-conditional-utils\";\nexport declare const conditionalAliasCopy: typeof f;\nexport declare function anonymousThisReturn(): {\n relyingOnThis(): anonymousThisReturn_recursive;\n};\nexport declare const arrow: () => typeof arrow;\nexport declare const expression: () => typeof expression;\nexport declare const first: () => typeof second;\nexport declare const second: () => typeof first;\nexport declare const generic: (value: T) => typeof generic;\nexport declare const objectReturn: () => {\n call: typeof objectReturn;\n};\nexport declare const tupleReturn: () => readonly [typeof tupleReturn];\nexport declare const shadowed: (shadowed: number) => typeof import(\".\").shadowed;\nexport declare const object: {\n value: number;\n next: () => typeof object;\n};\nexport declare const method: {\n value: number;\n next(): typeof method;\n};\nexport declare const accessor: {\n value: number;\n readonly next: typeof accessor;\n};\nexport declare const tuple: readonly [() => typeof tuple];\nexport declare const array: (() => typeof array)[];\nexport declare const nested: {\n inner: {\n next(): {\n next(): (typeof nested)[\"inner\"];\n };\n };\n};\nexport declare const memberTuple: readonly [() => () => (typeof memberTuple)[0]];\nexport declare const memberArray: (() => (typeof memberArray)[0])[];\nexport declare const quoted: {\n \"a-b\": () => () => (typeof quoted)[\"a-b\"];\n};\nexport declare const numeric: {\n 0: () => () => (typeof numeric)[0];\n};\nexport declare const key: unique symbol;\nexport declare const computed: {\n [key]: () => (typeof computed)[typeof key];\n};\nexport declare const union: {\n next: () => typeof union;\n} | undefined;\nexport declare const specialized: {\n value: string;\n next: () => typeof specialized;\n};\nexport declare const indexed: {\n [key: string]: typeof indexed;\n};\nexport declare const mapped: {\n next: typeof mapped;\n};\nexport declare const viaAnnotation: {\n value: string;\n next: () => typeof viaAnnotation;\n};\nexport type Link = {\n value: T;\n next: Link;\n};\nexport type Callable = {\n (value: T): Callable;\n link: Link;\n};\nexport declare const link: Link;\nexport declare const callable: Callable;\nexport declare const nextLink: Link;\nexport declare const nextCallable: Callable;\nexport declare const hiddenAlias: {\n value: string;\n next: typeof hiddenAlias;\n};\nexport declare const siblingHiddenAliases: {\n first: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"first\"];\n };\n second: {\n value: string;\n next: (typeof siblingHiddenAliases)[\"second\"];\n };\n};\nexport declare const parenthesized: () => typeof parenthesized;\nexport declare const asserted: () => typeof asserted;\nexport declare class Methods {\n static recur(): (typeof Methods)[\"recur\"];\n static \"a-b\"(): (typeof Methods)[\"a-b\"];\n static [key](): (typeof Methods)[typeof key];\n recur(): Methods[\"recur\"];\n}\nexport declare function overloaded(value: string): typeof overloaded;\nexport declare function overloaded(value: number): typeof overloaded;\nexport declare const nestedOwner: {\n make(outer: T): {\n nested(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n constrained(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n copied(inner: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: T;\n inner: U;\n owner: typeof nestedOwner;\n };\n };\n};\nexport declare const nestedNumber: {\n nested(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n constrained(inner: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n copied(inner: U): {\n outer: number;\n inner: U;\n owner: typeof nestedOwner;\n };\n rest(values_0: U): {\n outer: number;\n inner: U;\n owner: {\n make(outer: T): {\n nested(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n constrained(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n copied(inner: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n rest(values_0: U_1): {\n outer: T;\n inner: U_1;\n owner: typeof nestedOwner;\n };\n };\n };\n };\n};\nexport declare const mappedCycle: {\n Node: {\n value: number;\n next: (typeof mappedCycle)[\"Node\"];\n };\n};\nexport declare const mappedCycleCopy: {\n Node: {\n value: number;\n next: (typeof mappedCycleCopy)[\"Node\"];\n };\n};\nexport declare const nestedCycle: {\n wrapped: {\n Node: {\n value: string;\n next: (typeof nestedCycle)[\"wrapped\"][\"Node\"];\n };\n };\n};\nexport declare const cycleKey: unique symbol;\nexport declare const keyedCycles: {\n \"a-b\": {\n value: string;\n next: (typeof keyedCycles)[\"a-b\"];\n };\n 0: {\n value: boolean;\n next: (typeof keyedCycles)[0];\n };\n [cycleKey]: {\n value: number;\n next: (typeof keyedCycles)[typeof cycleKey];\n };\n};\nexport declare const sharedCycles: {\n first: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"first\"][\"Node\"];\n };\n };\n second: {\n Node: {\n value: number;\n next: (typeof sharedCycles)[\"second\"][\"Node\"];\n };\n };\n};\nexport declare const mutualCycle: {\n First: {\n value: number;\n next: {\n value: string;\n next: (typeof mutualCycle)[\"First\"];\n };\n };\n Second: {\n value: string;\n next: {\n value: number;\n next: (typeof mutualCycle)[\"Second\"];\n };\n };\n};\nexport declare const shadowedCycle: {\n Node: {\n value: number;\n next: (shadowedCycle: T) => typeof import(\".\").shadowedCycle[\"Node\"];\n };\n};\nexport declare const optionalCycle: {\n Node?: optionalCycle_recursive;\n};\nexport declare const nullableCycle: {\n Node: nullableCycle_recursive | null;\n};\nexport declare const mixedCycles: {\n required: {\n Node?: mixedCycles_recursive;\n };\n optional?: {\n Node?: mixedCycles_recursive;\n } | null;\n};\nexport declare const sharedOptionalCycles: {\n first: {\n Node?: sharedOptionalCycles_recursive;\n };\n second: {\n Node?: sharedOptionalCycles_recursive;\n };\n};\nexport declare const nullableKeys: {\n \"a-b\": nullableKeys_recursive | null;\n 0: nullableKeys_recursive_1 | null;\n [cycleKey]: nullableKeys_recursive_2 | null;\n};\nexport declare const nullableRoot: nullableRoot_recursive | null;\nexport declare const optionalRoot: optionalRoot_recursive | undefined;\nexport declare const nullableLinks: {\n Node: {\n value: number;\n next: (typeof nullableLinks)[\"Node\"];\n } | null;\n};\nexport declare const optionalNullableLinks: {\n Node?: optionalNullableLinks_recursive | null;\n};\nexport declare const nullableOptionalLinks: {\n Node: nullableOptionalLinks_recursive | null;\n};\nexport declare const nullishLinks: {\n Node?: nullishLinks_recursive | null;\n};\nexport declare const mixedUnionCycle: {\n Node?: false | mixedUnionCycle_recursive | null;\n};\nexport declare const _recursive = 1;\nexport declare const factory: () => () => factory_recursive;\nexport declare function captured(value: T): captured_recursive;\nexport declare function nestedCaptured(outer: T): (inner: U) => nestedCaptured_recursive;\nexport declare function constrained(key: K): constrained_recursive;\nexport declare function optionalCaptured(value: T): {\n node?: optionalCaptured_recursive | false | null;\n};\nexport declare function annotatedCaptured(value: T): annotatedCaptured_recursive;\nexport declare function recursiveTuple(value: T): recursiveTuple_recursive;\nexport declare function inferredCaptured(): (T extends () => infer U ? inferredCaptured_recursive : never);\nexport declare function mappedCaptured(): mappedCaptured_recursive;\nexport declare function freshGeneric(unused: T): freshGeneric_recursive;\nexport declare function mutualCaptured(left: T, right: U): {\n left: mutualCaptured_recursive_1;\n right: mutualCaptured_recursive;\n};\nexport declare class CapturedClass {\n value: T;\n constructor(value: T);\n make(inner: U): CapturedClass_make_recursive;\n}\nexport declare function covariantClass(): {\n new (): covariantClass_recursive;\n};\nexport declare function contravariantClass(): {\n new (): contravariantClass_recursive;\n};\nexport declare namespace Nested {\n type captured_recursive_1 = {\n value: T;\n next: () => captured_recursive_1;\n };\n export function captured(value: T): captured_recursive_1;\n export {};\n}\nexport {};\n", "impliedNodeFormat": 1 } } ], + "fileIdsList": [ + [ + "../recursive-conditional-utils.ts" + ] + ], "options": { "composite": true, + "exactOptionalPropertyTypes": true, "outDir": "./", "strict": true }, + "referencedMap": { + "../index.ts": [ + "../recursive-conditional-utils.ts" + ] + }, "latestChangedDtsFile": "./index.d.ts", - "size": 11175 + "size": 26586 } producer/tsconfig.json:: @@ -1073,6 +2387,7 @@ Signatures:: consumer/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/producer/dist/recursive-conditional-utils.d.ts *refresh* /home/src/workspaces/project/producer/dist/index.d.ts *refresh* /home/src/workspaces/project/consumer/index.ts Signatures:: @@ -1083,98 +2398,210 @@ Edit [2]:: no change tsgo --build consumer ExitStatus:: DiagnosticsPresent_OutputsGenerated Output:: -consumer/index.ts:58:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +consumer/index.ts:166:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +166 const invalid: number = arrow()()(); +   ~~~~~~~ + +consumer/index.ts:167:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. + +167 const invalidExpression: number = expression()()(); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:168:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. + +168 const invalidObject: number = objectReturn().call; +   ~~~~~~~~~~~~~ + +consumer/index.ts:169:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. + +169 const invalidTuple: number = tupleReturn()[0]; +   ~~~~~~~~~~~~ + +consumer/index.ts:170:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. + +170 const invalidShadowed: number = shadowed(1); +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:171:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +171 const invalidObjectValue: string = object.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:172:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. + +172 const invalidTupleValue: number = tuple[0](); +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:173:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +173 const invalidSpecialized: number = specialized.next().value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:174:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. + +174 const invalidMapped: number = mapped.next; +   ~~~~~~~~~~~~~ + +consumer/index.ts:175:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +175 const invalidAnnotation: number = viaAnnotation.next().value; +   ~~~~~~~~~~~~~~~~~ + +consumer/index.ts:176:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +176 const invalidLink: number = nextLink.next.value; +   ~~~~~~~~~~~ + +consumer/index.ts:177:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +177 const invalidCallable: string = nextCallable(1).link.value; +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:178:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +178 const invalidHiddenValue: number = hiddenAlias.next.next.value; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:179:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. + +179 const invalidMethod: number = Methods.recur()(); +   ~~~~~~~~~~~~~ + +consumer/index.ts:180:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. + +180 const invalidComputedMethod: number = Methods[key]()(); +   ~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:181:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. + +181 const invalidNestedOuter: boolean = nestedString.outer; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:182:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +182 const invalidNestedInner: string = nestedString.inner; +   ~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:183:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + +183 nestedNumber.constrained("wrong"); +   ~~~~~~~ + +consumer/index.ts:184:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +184 const invalidMappedCycleValue: string = mappedCycle.Node.next.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:185:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +185 const invalidMutualCycleValue: number = mutualCycle.First.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:186:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +186 const invalidShadowedMappedValue: string = shadowedCycle.Node.next(1).next("text").value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +consumer/index.ts:187:7 - error TS2322: Type 'null' is not assignable to type 'optionalCycle_recursive'. + +187 const invalidNullNext: OptionalNode["next"] = null; +   ~~~~~~~~~~~~~~~ + +consumer/index.ts:188:7 - error TS2322: Type 'undefined' is not assignable to type 'optionalCycle_recursive'. -58 const invalid: number = arrow()()(); -   ~~~~~~~ +188 const invalidUndefinedNext: OptionalNode["next"] = undefined; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:59:7 - error TS2322: Type '() => ...' is not assignable to type 'number'. +consumer/index.ts:189:42 - error TS2531: Object is possibly 'null'. -59 const invalidExpression: number = expression()()(); -   ~~~~~~~~~~~~~~~~~ +189 const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:60:7 - error TS2322: Type '() => { call: ...; }' is not assignable to type 'number'. +consumer/index.ts:190:41 - error TS2533: Object is possibly 'null' or 'undefined'. -60 const invalidObject: number = objectReturn().call; -   ~~~~~~~~~~~~~ +190 const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:61:7 - error TS2322: Type '() => readonly [...]' is not assignable to type 'number'. +consumer/index.ts:191:26 - error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -61 const invalidTuple: number = tupleReturn()[0]; -   ~~~~~~~~~~~~ +191 captured("text").consume(1); +   ~ -consumer/index.ts:62:7 - error TS2322: Type '(shadowed: number) => ...' is not assignable to type 'number'. +consumer/index.ts:192:7 - error TS2322: Type 'string' is not assignable to type 'number'. -62 const invalidShadowed: number = shadowed(1); -   ~~~~~~~~~~~~~~~ +192 const invalidRecursiveTupleValue: number = recursiveTuple("text")[1][0]; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:63:7 - error TS2322: Type 'number' is not assignable to type 'string'. +consumer/index.ts:193:7 - error TS2322: Type 'number' is not assignable to type 'string'. -63 const invalidObjectValue: string = object.next().value; -   ~~~~~~~~~~~~~~~~~~ +193 const invalidCapturedOuter: string = nestedCapturedValue.outer; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:64:7 - error TS2322: Type 'readonly [() => ...]' is not assignable to type 'number'. +consumer/index.ts:194:7 - error TS2322: Type 'string' is not assignable to type 'number'. -64 const invalidTupleValue: number = tuple[0](); -   ~~~~~~~~~~~~~~~~~ +194 const invalidCapturedInner: number = nestedCapturedValue.inner; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:65:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:196:7 - error TS2322: Type 'boolean' is not assignable to type 'mixedUnionCycle_recursive'. -65 const invalidSpecialized: number = specialized.next().value; -   ~~~~~~~~~~~~~~~~~~ +196 const invalidMixedNext: WithoutFalseOrNullish["next"] = false; +   ~~~~~~~~~~~~~~~~ -consumer/index.ts:66:7 - error TS2322: Type '{ next: ...; }' is not assignable to type 'number'. +consumer/index.ts:197:7 - error TS2322: Type 'string' is not assignable to type 'number'. -66 const invalidMapped: number = mapped.next; -   ~~~~~~~~~~~~~ +197 const invalidInferredCapturedValue: number = inferredCaptured<() => string>().next.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:67:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:198:7 - error TS2322: Type 'number' is not assignable to type 'string'. -67 const invalidAnnotation: number = viaAnnotation.next().value; -   ~~~~~~~~~~~~~~~~~ +198 const invalidMappedCapturedValue: string = mappedCaptured<{ value: number }>().value.next.value.value; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:68:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:199:7 - error TS2322: Type 'number' is not assignable to type 'boolean'. -68 const invalidLink: number = nextLink.next.value; -   ~~~~~~~~~~~ +199 const invalidMutualCapturedValue: boolean = mutualCaptured(1, "text").right.self.next.left; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:69:7 - error TS2322: Type 'number' is not assignable to type 'string'. +consumer/index.ts:200:7 - error TS2322: Type 'string' is not assignable to type 'number'. -69 const invalidCallable: string = nextCallable(1).link.value; -   ~~~~~~~~~~~~~~~ +200 const invalidCapturedClassValue: number = capturedClassResult.outer; +   ~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:70:7 - error TS2322: Type 'string' is not assignable to type 'number'. +consumer/index.ts:201:7 - error TS2322: Type 'covariantClass_recursive' is not assignable to type 'covariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. -70 const invalidHiddenValue: number = hiddenAlias.next.next.value; -   ~~~~~~~~~~~~~~~~~~ +201 const invalidCovariance: typeof covariantString = covariantUnknown.next(); +   ~~~~~~~~~~~~~~~~~ -consumer/index.ts:71:7 - error TS2322: Type '() => (typeof Methods)["recur"]' is not assignable to type 'number'. +consumer/index.ts:202:7 - error TS2322: Type 'contravariantClass_recursive' is not assignable to type 'contravariantClass_recursive'. + Type 'unknown' is not assignable to type 'string'. -71 const invalidMethod: number = Methods.recur()(); -   ~~~~~~~~~~~~~ +202 const invalidContravariance: typeof contravariantUnknown = contravariantString.next(); +   ~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:72:7 - error TS2322: Type '() => (typeof Methods)[typeof key]' is not assignable to type 'number'. +consumer/index.ts:203:7 - error TS2322: Type 'anonymousThisReturn_recursive' is not assignable to type 'number'. -72 const invalidComputedMethod: number = Methods[key]()(); -   ~~~~~~~~~~~~~~~~~~~~~ +203 const invalidAnonymousThis: number = anonymousThisResult; +   ~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:73:7 - error TS2322: Type 'string' is not assignable to type 'boolean'. +consumer/index.ts:204:7 - error TS2322: Type '() => anonymousThisReturn_recursive' is not assignable to type 'number'. -73 const invalidNestedOuter: boolean = nestedString.outer; -   ~~~~~~~~~~~~~~~~~~ +204 const invalidAnonymousThisMethod: number = anonymousThisResult.relyingOnThis; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:74:7 - error TS2322: Type 'number' is not assignable to type 'string'. +consumer/index.ts:205:7 - error TS2322: Type 'number' is not assignable to type 'string'. -74 const invalidNestedInner: string = nestedString.inner; -   ~~~~~~~~~~~~~~~~~~ +205 const invalidConditionalAlias: string = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~ -consumer/index.ts:75:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +consumer/index.ts:206:7 - error TS2322: Type 'number' is not assignable to type 'number[]'. -75 nestedNumber.constrained("wrong"); -   ~~~~~~~ +206 const invalidConditionalAliasArray: number[] = conditionalAliasResult; +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Found 18 errors in the same file, starting at: consumer/index.ts:58 +Found 40 errors in the same file, starting at: consumer/index.ts:166 //// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo] *rewrite with same content* //// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo.readable.baseline.txt] *rewrite with same content* @@ -1182,6 +2609,7 @@ Found 18 errors in the same file, starting at: consumer/index.ts:58 consumer/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/producer/dist/recursive-conditional-utils.d.ts *refresh* /home/src/workspaces/project/producer/dist/index.d.ts *refresh* /home/src/workspaces/project/consumer/index.ts Signatures:: diff --git a/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-global-declaration-consumption.js b/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-global-declaration-consumption.js new file mode 100644 index 0000000000000..e3176edaff68e --- /dev/null +++ b/tsc/testdata/baselines/reference/tsbuild/incremental/recursive-global-declaration-consumption.js @@ -0,0 +1,764 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/consumer/index.ts] *new* +export {}; +const fromA: number = makeA().self().value; +const fromB: string = makeB().self().value; +const reserved: boolean = makeReserved().self().value; +const genericA: string = GlobalA.create("text").next().value; +const genericB: number = GlobalB.create(1).next().value; +const quoted: boolean = GlobalA["a-b"]().next().value; +const invalidA: string = makeA().self().value; +const invalidB: number = makeB().self().value; +//// [/home/src/workspaces/project/consumer/tsconfig.json] *new* +{ + "compilerOptions": { "strict": true, "composite": true, "skipLibCheck": false }, + "files": ["index.ts", "../first/dist/index.d.ts", "../second/dist/index.d.ts"], + "references": [{ "path": "../first" }, { "path": "../second" }] + } +//// [/home/src/workspaces/project/first/index.ts] *new* +function makeA() { + return { value: 1, self() { return this; } }; +} +type makeReserved_recursive = "reserved"; +function makeReserved() { + return { value: true, self() { return this; } }; +} +class GlobalA { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} +//// [/home/src/workspaces/project/first/tsconfig.json] *new* +{ + "compilerOptions": { "strict": true, "composite": true, "outDir": "dist" }, + "files": ["index.ts"] + } +//// [/home/src/workspaces/project/second/index.ts] *new* +function makeB() { + return { value: "text", self() { return this; } }; +} +class GlobalB { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } +} +//// [/home/src/workspaces/project/second/tsconfig.json] *new* +{ + "compilerOptions": { "strict": true, "composite": true, "outDir": "dist" }, + "files": ["index.ts"] + } + +tsgo --build consumer +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +consumer/index.ts:8:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +8 const invalidA: string = makeA().self().value; +   ~~~~~~~~ + +consumer/index.ts:9:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +9 const invalidB: number = makeB().self().value; +   ~~~~~~~~ + + +Found 2 errors in the same file, starting at: consumer/index.ts:8 + +//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib* +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +interface SymbolConstructor { + (desc?: string | number): symbol; + for(name: string): symbol; + readonly toStringTag: symbol; +} +declare var Symbol: SymbolConstructor; +interface Symbol { + readonly [Symbol.toStringTag]: string; +} +declare const console: { log(msg: any): void; }; +//// [/home/src/workspaces/project/consumer/index.d.ts] *new* +export {}; + +//// [/home/src/workspaces/project/consumer/index.js] *new* +const fromA = makeA().self().value; +const fromB = makeB().self().value; +const reserved = makeReserved().self().value; +const genericA = GlobalA.create("text").next().value; +const genericB = GlobalB.create(1).next().value; +const quoted = GlobalA["a-b"]().next().value; +const invalidA = makeA().self().value; +const invalidB = makeB().self().value; +export {}; + +//// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo] *new* +{"version":"FakeTSVersion","root":[[2,4]],"fileNames":["lib.es2026.full.d.ts","./index.ts","../first/dist/index.d.ts","../second/dist/index.d.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"c96c6feb8050748fb0780a02a020929d-export {};\nconst fromA: number = makeA().self().value;\nconst fromB: string = makeB().self().value;\nconst reserved: boolean = makeReserved().self().value;\nconst genericA: string = GlobalA.create(\"text\").next().value;\nconst genericB: number = GlobalB.create(1).next().value;\nconst quoted: boolean = GlobalA[\"a-b\"]().next().value;\nconst invalidA: string = makeA().self().value;\nconst invalidB: number = makeB().self().value;","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1},{"version":"02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1}],"options":{"composite":true,"skipLibCheck":false,"strict":true},"semanticDiagnosticsPerFile":[[2,[{"pos":334,"end":342,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["number","string"]},{"pos":381,"end":389,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["string","number"]}]]],"latestChangedDtsFile":"./index.d.ts"} +//// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo.readable.baseline.txt] *new* +{ + "version": "FakeTSVersion", + "root": [ + { + "files": [ + "./index.ts", + "../first/dist/index.d.ts", + "../second/dist/index.d.ts" + ], + "original": [ + 2, + 4 + ] + } + ], + "fileNames": [ + "lib.es2026.full.d.ts", + "./index.ts", + "../first/dist/index.d.ts", + "../second/dist/index.d.ts" + ], + "fileInfos": [ + { + "fileName": "lib.es2026.full.d.ts", + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "./index.ts", + "version": "c96c6feb8050748fb0780a02a020929d-export {};\nconst fromA: number = makeA().self().value;\nconst fromB: string = makeB().self().value;\nconst reserved: boolean = makeReserved().self().value;\nconst genericA: string = GlobalA.create(\"text\").next().value;\nconst genericB: number = GlobalB.create(1).next().value;\nconst quoted: boolean = GlobalA[\"a-b\"]().next().value;\nconst invalidA: string = makeA().self().value;\nconst invalidB: number = makeB().self().value;", + "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n", + "impliedNodeFormat": "CommonJS", + "original": { + "version": "c96c6feb8050748fb0780a02a020929d-export {};\nconst fromA: number = makeA().self().value;\nconst fromB: string = makeB().self().value;\nconst reserved: boolean = makeReserved().self().value;\nconst genericA: string = GlobalA.create(\"text\").next().value;\nconst genericB: number = GlobalB.create(1).next().value;\nconst quoted: boolean = GlobalA[\"a-b\"]().next().value;\nconst invalidA: string = makeA().self().value;\nconst invalidB: number = makeB().self().value;", + "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n", + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../first/dist/index.d.ts", + "version": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "signature": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../second/dist/index.d.ts", + "version": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "signature": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + } + ], + "options": { + "composite": true, + "skipLibCheck": false, + "strict": true + }, + "semanticDiagnosticsPerFile": [ + [ + "./index.ts", + [ + { + "pos": 334, + "end": 342, + "code": 2322, + "category": 1, + "messageKey": "Type_0_is_not_assignable_to_type_1_2322", + "messageArgs": [ + "number", + "string" + ] + }, + { + "pos": 381, + "end": 389, + "code": 2322, + "category": 1, + "messageKey": "Type_0_is_not_assignable_to_type_1_2322", + "messageArgs": [ + "string", + "number" + ] + } + ] + ] + ], + "latestChangedDtsFile": "./index.d.ts", + "size": 3196 +} +//// [/home/src/workspaces/project/first/dist/index.d.ts] *new* +type makeA_recursive = { + value: number; + self(): makeA_recursive; +}; +type makeReserved_recursive_1 = { + value: boolean; + self(): makeReserved_recursive_1; +}; +type GlobalA_create_recursive = { + value: T; + next: () => GlobalA_create_recursive; +}; +type GlobalA_a_b_recursive = { + value: boolean; + next: () => GlobalA_a_b_recursive; +}; +declare function makeA(): { + value: number; + self(): makeA_recursive; +}; +type makeReserved_recursive = "reserved"; +declare function makeReserved(): { + value: boolean; + self(): makeReserved_recursive_1; +}; +declare class GlobalA { + static create(value: T): GlobalA_create_recursive; + static "a-b"(): GlobalA_a_b_recursive; +} + +//// [/home/src/workspaces/project/first/dist/index.js] *new* +"use strict"; +function makeA() { + return { value: 1, self() { return this; } }; +} +function makeReserved() { + return { value: true, self() { return this; } }; +} +class GlobalA { + static create(value) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} + +//// [/home/src/workspaces/project/first/dist/tsconfig.tsbuildinfo] *new* +{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"ceb88b9ff61ebe91c7080ce8a28b3fc4-function makeA() {\n return { value: 1, self() { return this; } };\n}\ntype makeReserved_recursive = \"reserved\";\nfunction makeReserved() {\n return { value: true, self() { return this; } };\n}\nclass GlobalA {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n static \"a-b\"() {\n const node = { value: true, next: () => node };\n return node;\n }\n}","signature":"02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./","strict":true},"latestChangedDtsFile":"./index.d.ts"} +//// [/home/src/workspaces/project/first/dist/tsconfig.tsbuildinfo.readable.baseline.txt] *new* +{ + "version": "FakeTSVersion", + "root": [ + { + "files": [ + "../index.ts" + ], + "original": 2 + } + ], + "fileNames": [ + "lib.es2026.full.d.ts", + "../index.ts" + ], + "fileInfos": [ + { + "fileName": "lib.es2026.full.d.ts", + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../index.ts", + "version": "ceb88b9ff61ebe91c7080ce8a28b3fc4-function makeA() {\n return { value: 1, self() { return this; } };\n}\ntype makeReserved_recursive = \"reserved\";\nfunction makeReserved() {\n return { value: true, self() { return this; } };\n}\nclass GlobalA {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n static \"a-b\"() {\n const node = { value: true, next: () => node };\n return node;\n }\n}", + "signature": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "ceb88b9ff61ebe91c7080ce8a28b3fc4-function makeA() {\n return { value: 1, self() { return this; } };\n}\ntype makeReserved_recursive = \"reserved\";\nfunction makeReserved() {\n return { value: true, self() { return this; } };\n}\nclass GlobalA {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n static \"a-b\"() {\n const node = { value: true, next: () => node };\n return node;\n }\n}", + "signature": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + } + ], + "options": { + "composite": true, + "outDir": "./", + "strict": true + }, + "latestChangedDtsFile": "./index.d.ts", + "size": 2300 +} +//// [/home/src/workspaces/project/second/dist/index.d.ts] *new* +type makeB_recursive = { + value: string; + self(): makeB_recursive; +}; +type GlobalB_create_recursive = { + value: T; + next: () => GlobalB_create_recursive; +}; +declare function makeB(): { + value: string; + self(): makeB_recursive; +}; +declare class GlobalB { + static create(value: T): GlobalB_create_recursive; +} + +//// [/home/src/workspaces/project/second/dist/index.js] *new* +"use strict"; +function makeB() { + return { value: "text", self() { return this; } }; +} +class GlobalB { + static create(value) { + const node = { value, next: () => node }; + return node; + } +} + +//// [/home/src/workspaces/project/second/dist/tsconfig.tsbuildinfo] *new* +{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"694c69b9db6086cbefa6a892b18ab1d4-function makeB() {\n return { value: \"text\", self() { return this; } };\n}\nclass GlobalB {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}","signature":"1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./","strict":true},"latestChangedDtsFile":"./index.d.ts"} +//// [/home/src/workspaces/project/second/dist/tsconfig.tsbuildinfo.readable.baseline.txt] *new* +{ + "version": "FakeTSVersion", + "root": [ + { + "files": [ + "../index.ts" + ], + "original": 2 + } + ], + "fileNames": [ + "lib.es2026.full.d.ts", + "../index.ts" + ], + "fileInfos": [ + { + "fileName": "lib.es2026.full.d.ts", + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../index.ts", + "version": "694c69b9db6086cbefa6a892b18ab1d4-function makeB() {\n return { value: \"text\", self() { return this; } };\n}\nclass GlobalB {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}", + "signature": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "694c69b9db6086cbefa6a892b18ab1d4-function makeB() {\n return { value: \"text\", self() { return this; } };\n}\nclass GlobalB {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n}", + "signature": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + } + ], + "options": { + "composite": true, + "outDir": "./", + "strict": true + }, + "latestChangedDtsFile": "./index.d.ts", + "size": 1681 +} + +first/tsconfig.json:: +SemanticDiagnostics:: +*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/first/index.ts +Signatures:: +(stored at emit) /home/src/workspaces/project/first/index.ts + +second/tsconfig.json:: +SemanticDiagnostics:: +*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/second/index.ts +Signatures:: +(stored at emit) /home/src/workspaces/project/second/index.ts + +consumer/tsconfig.json:: +SemanticDiagnostics:: +*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/consumer/index.ts +*refresh* /home/src/workspaces/project/first/dist/index.d.ts +*refresh* /home/src/workspaces/project/second/dist/index.d.ts +Signatures:: +(stored at emit) /home/src/workspaces/project/consumer/index.ts + + +Edit [0]:: no change + +tsgo --build consumer +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +consumer/index.ts:8:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +8 const invalidA: string = makeA().self().value; +   ~~~~~~~~ + +consumer/index.ts:9:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +9 const invalidB: number = makeB().self().value; +   ~~~~~~~~ + + +Found 2 errors in the same file, starting at: consumer/index.ts:8 + + +consumer/tsconfig.json:: +SemanticDiagnostics:: +Signatures:: + + +Edit [1]:: add a comment to the first script +//// [/home/src/workspaces/project/first/index.ts] *modified* +function makeA() { + return { value: 1, self() { return this; } }; +} +type makeReserved_recursive = "reserved"; +function makeReserved() { + return { value: true, self() { return this; } }; +} +class GlobalA { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} +// comment-only edit + + +tsgo --build consumer +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +consumer/index.ts:8:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +8 const invalidA: string = makeA().self().value; +   ~~~~~~~~ + +consumer/index.ts:9:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +9 const invalidB: number = makeB().self().value; +   ~~~~~~~~ + + +Found 2 errors in the same file, starting at: consumer/index.ts:8 + +//// [/home/src/workspaces/project/first/dist/index.js] *modified* +"use strict"; +function makeA() { + return { value: 1, self() { return this; } }; +} +function makeReserved() { + return { value: true, self() { return this; } }; +} +class GlobalA { + static create(value) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} +// comment-only edit + +//// [/home/src/workspaces/project/first/dist/tsconfig.tsbuildinfo] *modified* +{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"2ed9ea09308db619d5987fe87b218899-function makeA() {\n return { value: 1, self() { return this; } };\n}\ntype makeReserved_recursive = \"reserved\";\nfunction makeReserved() {\n return { value: true, self() { return this; } };\n}\nclass GlobalA {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n static \"a-b\"() {\n const node = { value: true, next: () => node };\n return node;\n }\n}\n// comment-only edit\n","signature":"02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./","strict":true},"latestChangedDtsFile":"./index.d.ts"} +//// [/home/src/workspaces/project/first/dist/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* +{ + "version": "FakeTSVersion", + "root": [ + { + "files": [ + "../index.ts" + ], + "original": 2 + } + ], + "fileNames": [ + "lib.es2026.full.d.ts", + "../index.ts" + ], + "fileInfos": [ + { + "fileName": "lib.es2026.full.d.ts", + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../index.ts", + "version": "2ed9ea09308db619d5987fe87b218899-function makeA() {\n return { value: 1, self() { return this; } };\n}\ntype makeReserved_recursive = \"reserved\";\nfunction makeReserved() {\n return { value: true, self() { return this; } };\n}\nclass GlobalA {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n static \"a-b\"() {\n const node = { value: true, next: () => node };\n return node;\n }\n}\n// comment-only edit\n", + "signature": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "2ed9ea09308db619d5987fe87b218899-function makeA() {\n return { value: 1, self() { return this; } };\n}\ntype makeReserved_recursive = \"reserved\";\nfunction makeReserved() {\n return { value: true, self() { return this; } };\n}\nclass GlobalA {\n static create(value: T) {\n const node = { value, next: () => node };\n return node;\n }\n static \"a-b\"() {\n const node = { value: true, next: () => node };\n return node;\n }\n}\n// comment-only edit\n", + "signature": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + } + ], + "options": { + "composite": true, + "outDir": "./", + "strict": true + }, + "latestChangedDtsFile": "./index.d.ts", + "size": 2324 +} + +first/tsconfig.json:: +SemanticDiagnostics:: +*refresh* /home/src/workspaces/project/first/index.ts +Signatures:: +(computed .d.ts) /home/src/workspaces/project/first/index.ts + +consumer/tsconfig.json:: +SemanticDiagnostics:: +Signatures:: + + +Edit [2]:: no change + +tsgo --build consumer +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +consumer/index.ts:8:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +8 const invalidA: string = makeA().self().value; +   ~~~~~~~~ + +consumer/index.ts:9:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +9 const invalidB: number = makeB().self().value; +   ~~~~~~~~ + + +Found 2 errors in the same file, starting at: consumer/index.ts:8 + + +consumer/tsconfig.json:: +SemanticDiagnostics:: +Signatures:: + + +Edit [3]:: check both declarations with skipLibCheck +//// [/home/src/workspaces/project/consumer/tsconfig.json] *modified* +{ + "compilerOptions": { "strict": true, "composite": true, "skipLibCheck": true }, + "files": ["index.ts", "../first/dist/index.d.ts", "../second/dist/index.d.ts"], + "references": [{ "path": "../first" }, { "path": "../second" }] + } + +tsgo --build consumer +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +consumer/index.ts:8:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +8 const invalidA: string = makeA().self().value; +   ~~~~~~~~ + +consumer/index.ts:9:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +9 const invalidB: number = makeB().self().value; +   ~~~~~~~~ + + +Found 2 errors in the same file, starting at: consumer/index.ts:8 + +//// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo] *modified* +{"version":"FakeTSVersion","root":[[2,4]],"fileNames":["lib.es2026.full.d.ts","./index.ts","../first/dist/index.d.ts","../second/dist/index.d.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"c96c6feb8050748fb0780a02a020929d-export {};\nconst fromA: number = makeA().self().value;\nconst fromB: string = makeB().self().value;\nconst reserved: boolean = makeReserved().self().value;\nconst genericA: string = GlobalA.create(\"text\").next().value;\nconst genericB: number = GlobalB.create(1).next().value;\nconst quoted: boolean = GlobalA[\"a-b\"]().next().value;\nconst invalidA: string = makeA().self().value;\nconst invalidB: number = makeB().self().value;","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1},{"version":"02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n","affectsGlobalScope":true,"impliedNodeFormat":1}],"options":{"composite":true,"skipLibCheck":true,"strict":true},"semanticDiagnosticsPerFile":[[2,[{"pos":334,"end":342,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["number","string"]},{"pos":381,"end":389,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["string","number"]}]]],"latestChangedDtsFile":"./index.d.ts"} +//// [/home/src/workspaces/project/consumer/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* +{ + "version": "FakeTSVersion", + "root": [ + { + "files": [ + "./index.ts", + "../first/dist/index.d.ts", + "../second/dist/index.d.ts" + ], + "original": [ + 2, + 4 + ] + } + ], + "fileNames": [ + "lib.es2026.full.d.ts", + "./index.ts", + "../first/dist/index.d.ts", + "../second/dist/index.d.ts" + ], + "fileInfos": [ + { + "fileName": "lib.es2026.full.d.ts", + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "./index.ts", + "version": "c96c6feb8050748fb0780a02a020929d-export {};\nconst fromA: number = makeA().self().value;\nconst fromB: string = makeB().self().value;\nconst reserved: boolean = makeReserved().self().value;\nconst genericA: string = GlobalA.create(\"text\").next().value;\nconst genericB: number = GlobalB.create(1).next().value;\nconst quoted: boolean = GlobalA[\"a-b\"]().next().value;\nconst invalidA: string = makeA().self().value;\nconst invalidB: number = makeB().self().value;", + "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n", + "impliedNodeFormat": "CommonJS", + "original": { + "version": "c96c6feb8050748fb0780a02a020929d-export {};\nconst fromA: number = makeA().self().value;\nconst fromB: string = makeB().self().value;\nconst reserved: boolean = makeReserved().self().value;\nconst genericA: string = GlobalA.create(\"text\").next().value;\nconst genericB: number = GlobalB.create(1).next().value;\nconst quoted: boolean = GlobalA[\"a-b\"]().next().value;\nconst invalidA: string = makeA().self().value;\nconst invalidB: number = makeB().self().value;", + "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n", + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../first/dist/index.d.ts", + "version": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "signature": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "02702dd1cd4f6805e366ae36e2943eb6-type makeA_recursive = {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive_1 = {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ntype GlobalA_create_recursive = {\n value: T;\n next: () => GlobalA_create_recursive;\n};\ntype GlobalA_a_b_recursive = {\n value: boolean;\n next: () => GlobalA_a_b_recursive;\n};\ndeclare function makeA(): {\n value: number;\n self(): makeA_recursive;\n};\ntype makeReserved_recursive = \"reserved\";\ndeclare function makeReserved(): {\n value: boolean;\n self(): makeReserved_recursive_1;\n};\ndeclare class GlobalA {\n static create(value: T): GlobalA_create_recursive;\n static \"a-b\"(): GlobalA_a_b_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + }, + { + "fileName": "../second/dist/index.d.ts", + "version": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "signature": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": "CommonJS", + "original": { + "version": "1b1d198fb9025c7d8314d76bb2445e46-type makeB_recursive = {\n value: string;\n self(): makeB_recursive;\n};\ntype GlobalB_create_recursive = {\n value: T;\n next: () => GlobalB_create_recursive;\n};\ndeclare function makeB(): {\n value: string;\n self(): makeB_recursive;\n};\ndeclare class GlobalB {\n static create(value: T): GlobalB_create_recursive;\n}\n", + "affectsGlobalScope": true, + "impliedNodeFormat": 1 + } + } + ], + "options": { + "composite": true, + "skipLibCheck": true, + "strict": true + }, + "semanticDiagnosticsPerFile": [ + [ + "./index.ts", + [ + { + "pos": 334, + "end": 342, + "code": 2322, + "category": 1, + "messageKey": "Type_0_is_not_assignable_to_type_1_2322", + "messageArgs": [ + "number", + "string" + ] + }, + { + "pos": 381, + "end": 389, + "code": 2322, + "category": 1, + "messageKey": "Type_0_is_not_assignable_to_type_1_2322", + "messageArgs": [ + "string", + "number" + ] + } + ] + ] + ], + "latestChangedDtsFile": "./index.d.ts", + "size": 3195 +} + +consumer/tsconfig.json:: +SemanticDiagnostics:: +*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts +*refresh* /home/src/workspaces/project/first/dist/index.d.ts +*refresh* /home/src/workspaces/project/second/dist/index.d.ts +Signatures:: + + +Edit [4]:: no change + +tsgo --build consumer +ExitStatus:: DiagnosticsPresent_OutputsGenerated +Output:: +consumer/index.ts:8:7 - error TS2322: Type 'number' is not assignable to type 'string'. + +8 const invalidA: string = makeA().self().value; +   ~~~~~~~~ + +consumer/index.ts:9:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +9 const invalidB: number = makeB().self().value; +   ~~~~~~~~ + + +Found 2 errors in the same file, starting at: consumer/index.ts:8 + + +consumer/tsconfig.json:: +SemanticDiagnostics:: +Signatures:: diff --git a/tsc/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js b/tsc/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js index 21aa78f4efbca..ff1d0c052f99c 100644 --- a/tsc/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js +++ b/tsc/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js @@ -225,10 +225,12 @@ declare const console: { log(msg: any): void; }; {"id":115,"symbolName":"__type","recursionId":85,"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":3,"character":16},"end":{"line":3,"character":27}},"flags":["Object"],"display":"(x: U) => U"}, {"id":116,"recursionId":97,"flags":["StringLiteral"],"display":"\"value\""}, {"id":117,"recursionId":98,"flags":["StringLiteral"],"display":"\"map\""}, -{"id":118,"symbolName":"Container","recursionId":83,"instantiatedType":91,"typeArguments":[112],"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":1,"character":1},"end":{"line":4,"character":2}},"flags":["Object"]}, -{"id":119,"symbolName":"Nullable","recursionId":99,"unionTypes":[10,13,14],"aliasTypeArguments":[14],"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":5,"character":1},"end":{"line":5,"character":48}},"flags":["Union"],"display":"Nullable"}, -{"id":120,"recursionId":100,"flags":["StringLiteral"],"display":"\"hello\""}, -{"id":121,"recursionId":101,"flags":["StringLiteral"],"display":"\"hello\""}, -{"id":122,"symbolName":"__object","recursionId":102,"firstDeclaration":{"path":"/home/src/workspaces/project/main.ts","start":{"line":2,"character":57},"end":{"line":2,"character":86}},"flags":["Object"],"display":"{ value: U; map: (fn: (x: number) => U) => Container; }"}] +{"id":118,"symbolName":"__type","recursionId":85,"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":3,"character":16},"end":{"line":3,"character":27}},"flags":["Object"],"display":"(x: number) => U"}, +{"id":119,"symbolName":"__type","recursionId":85,"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":3,"character":16},"end":{"line":3,"character":27}},"flags":["Object"],"display":"(x: U) => U"}, +{"id":120,"symbolName":"Container","recursionId":83,"instantiatedType":91,"typeArguments":[112],"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":1,"character":1},"end":{"line":4,"character":2}},"flags":["Object"]}, +{"id":121,"symbolName":"Nullable","recursionId":99,"unionTypes":[10,13,14],"aliasTypeArguments":[14],"firstDeclaration":{"path":"/home/src/workspaces/project/types.ts","start":{"line":5,"character":1},"end":{"line":5,"character":48}},"flags":["Union"],"display":"Nullable"}, +{"id":122,"recursionId":100,"flags":["StringLiteral"],"display":"\"hello\""}, +{"id":123,"recursionId":101,"flags":["StringLiteral"],"display":"\"hello\""}, +{"id":124,"symbolName":"__object","recursionId":102,"firstDeclaration":{"path":"/home/src/workspaces/project/main.ts","start":{"line":2,"character":57},"end":{"line":2,"character":86}},"flags":["Object"],"display":"{ value: U; map: (fn: (x: number) => U) => Container; }"}] diff --git a/tsc/testdata/baselines/reference/tsc/incremental/recursive-tagged-tuple-after-incremental-edits.js b/tsc/testdata/baselines/reference/tsc/incremental/recursive-tagged-tuple-after-incremental-edits.js index 4b5a5ad527188..d6e60ab2dc542 100644 --- a/tsc/testdata/baselines/reference/tsc/incremental/recursive-tagged-tuple-after-incremental-edits.js +++ b/tsc/testdata/baselines/reference/tsc/incremental/recursive-tagged-tuple-after-incremental-edits.js @@ -155,7 +155,7 @@ tsgo ExitStatus:: Success Output:: //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *modified* -{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","./doc.ts","./consumer.ts"],"fileInfos":[{"version":"0e330bc1e98a7e2601e4b38548df5e2b-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray { readonly length: number; readonly [n: number]: T; }\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"209790a380ab2edc475c402e3a85e110-type Doc =\n | string\n | { [k: string]: Doc }\n | readonly [\"array\", Doc]\n | readonly [\"array\", Doc, { length: number }]\n | readonly [\"array\", Doc, { min?: number; max?: number }]\n | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\n// comment-only edit\n","signature":"17befdf8983ce76b78c64e0ef9b49c73-type Doc = string | {\n [k: string]: Doc;\n} | readonly [\"array\", Doc] | readonly [\"array\", Doc, {\n length: number;\n}] | readonly [\"array\", Doc, {\n min?: number;\n max?: number;\n}] | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\nexport {};\n","impliedNodeFormat":1},{"version":"e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;","signature":"a56617d7ff45ff02880e982e94937f59-export declare const value: any;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"module":99,"strict":true},"referencedMap":[[3,1]],"affectedFilesPendingEmit":[3,2]} +{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","./doc.ts","./consumer.ts"],"fileInfos":[{"version":"0e330bc1e98a7e2601e4b38548df5e2b-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray { readonly length: number; readonly [n: number]: T; }\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"209790a380ab2edc475c402e3a85e110-type Doc =\n | string\n | { [k: string]: Doc }\n | readonly [\"array\", Doc]\n | readonly [\"array\", Doc, { length: number }]\n | readonly [\"array\", Doc, { min?: number; max?: number }]\n | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\n// comment-only edit\n","signature":"17befdf8983ce76b78c64e0ef9b49c73-type Doc = string | {\n [k: string]: Doc;\n} | readonly [\"array\", Doc] | readonly [\"array\", Doc, {\n length: number;\n}] | readonly [\"array\", Doc, {\n min?: number;\n max?: number;\n}] | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\nexport {};\n","impliedNodeFormat":1},{"version":"e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;","signature":"d5413f57bca15c0bb9b5773c356982d0-type value_recursive = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"module":99,"strict":true},"referencedMap":[[3,1]],"affectedFilesPendingEmit":[3,2]} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* { "version": "FakeTSVersion", @@ -203,11 +203,11 @@ Output:: { "fileName": "./consumer.ts", "version": "e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;", - "signature": "a56617d7ff45ff02880e982e94937f59-export declare const value: any;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n", + "signature": "d5413f57bca15c0bb9b5773c356982d0-type value_recursive = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport {};\n", "impliedNodeFormat": "CommonJS", "original": { "version": "e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;", - "signature": "a56617d7ff45ff02880e982e94937f59-export declare const value: any;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n", + "signature": "d5413f57bca15c0bb9b5773c356982d0-type value_recursive = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport {};\n", "impliedNodeFormat": 1 } } @@ -238,7 +238,7 @@ Output:: 2 ] ], - "size": 2108 + "size": 3059 } tsconfig.json:: @@ -279,7 +279,7 @@ tsgo ExitStatus:: Success Output:: //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *modified* -{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","./doc.ts","./consumer.ts"],"fileInfos":[{"version":"0e330bc1e98a7e2601e4b38548df5e2b-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray { readonly length: number; readonly [n: number]: T; }\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"703658314ddb6e78faa0ecabe01e9319-type Doc =\n | number\n | string\n | { [k: string]: Doc }\n | readonly [\"array\", Doc]\n | readonly [\"array\", Doc, { length: number }]\n | readonly [\"array\", Doc, { min?: number; max?: number }]\n | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\n// comment-only edit\n","signature":"e0d759702454fa5818ea5747e4408ca8-type Doc = number | string | {\n [k: string]: Doc;\n} | readonly [\"array\", Doc] | readonly [\"array\", Doc, {\n length: number;\n}] | readonly [\"array\", Doc, {\n min?: number;\n max?: number;\n}] | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\nexport {};\n","impliedNodeFormat":1},{"version":"e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;","signature":"a56617d7ff45ff02880e982e94937f59-export declare const value: any;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"module":99,"strict":true},"referencedMap":[[3,1]],"affectedFilesPendingEmit":[3,2]} +{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","./doc.ts","./consumer.ts"],"fileInfos":[{"version":"0e330bc1e98a7e2601e4b38548df5e2b-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray { readonly length: number; readonly [n: number]: T; }\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"703658314ddb6e78faa0ecabe01e9319-type Doc =\n | number\n | string\n | { [k: string]: Doc }\n | readonly [\"array\", Doc]\n | readonly [\"array\", Doc, { length: number }]\n | readonly [\"array\", Doc, { min?: number; max?: number }]\n | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\n// comment-only edit\n","signature":"e0d759702454fa5818ea5747e4408ca8-type Doc = number | string | {\n [k: string]: Doc;\n} | readonly [\"array\", Doc] | readonly [\"array\", Doc, {\n length: number;\n}] | readonly [\"array\", Doc, {\n min?: number;\n max?: number;\n}] | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\nexport {};\n","impliedNodeFormat":1},{"version":"e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;","signature":"073dcb2621ddd8f6400ee46322fc6e7d-type value_recursive = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | number | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"module":99,"strict":true},"referencedMap":[[3,1]],"affectedFilesPendingEmit":[3,2]} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* { "version": "FakeTSVersion", @@ -327,11 +327,11 @@ Output:: { "fileName": "./consumer.ts", "version": "e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;", - "signature": "a56617d7ff45ff02880e982e94937f59-export declare const value: any;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n", + "signature": "073dcb2621ddd8f6400ee46322fc6e7d-type value_recursive = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | number | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport {};\n", "impliedNodeFormat": "CommonJS", "original": { "version": "e3e1863b40b48bf670281f2578788e0b-import { doc } from \"./doc\";\nexport const value = doc;", - "signature": "a56617d7ff45ff02880e982e94937f59-export declare const value: any;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n", + "signature": "073dcb2621ddd8f6400ee46322fc6e7d-type value_recursive = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | number | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport {};\n", "impliedNodeFormat": 1 } } @@ -362,7 +362,7 @@ Output:: 2 ] ], - "size": 2131 + "size": 3145 } tsconfig.json:: @@ -405,7 +405,7 @@ Output:: Found 1 error in consumer.ts:3 //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *modified* -{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","./doc.ts","./consumer.ts"],"fileInfos":[{"version":"0e330bc1e98a7e2601e4b38548df5e2b-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray { readonly length: number; readonly [n: number]: T; }\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"703658314ddb6e78faa0ecabe01e9319-type Doc =\n | number\n | string\n | { [k: string]: Doc }\n | readonly [\"array\", Doc]\n | readonly [\"array\", Doc, { length: number }]\n | readonly [\"array\", Doc, { min?: number; max?: number }]\n | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\n// comment-only edit\n","signature":"e0d759702454fa5818ea5747e4408ca8-type Doc = number | string | {\n [k: string]: Doc;\n} | readonly [\"array\", Doc] | readonly [\"array\", Doc, {\n length: number;\n}] | readonly [\"array\", Doc, {\n min?: number;\n max?: number;\n}] | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\nexport {};\n","impliedNodeFormat":1},{"version":"8af491d326de0701fb4d07a415b35dec-import { doc } from \"./doc\";\nexport const value = doc;\nexport const invalid: number = value;\n","signature":"b0465247e2bd6863c6a086f723d673e8-export declare const value: any;\nexport declare const invalid: number;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"module":99,"strict":true},"referencedMap":[[3,1]],"semanticDiagnosticsPerFile":[[3,[{"pos":68,"end":75,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["Doc","number"],"messageChain":[{"pos":68,"end":75,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["string","number"]}]}]]],"affectedFilesPendingEmit":[3,2]} +{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.es2026.full.d.ts","./doc.ts","./consumer.ts"],"fileInfos":[{"version":"0e330bc1e98a7e2601e4b38548df5e2b-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray { readonly length: number; readonly [n: number]: T; }\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"703658314ddb6e78faa0ecabe01e9319-type Doc =\n | number\n | string\n | { [k: string]: Doc }\n | readonly [\"array\", Doc]\n | readonly [\"array\", Doc, { length: number }]\n | readonly [\"array\", Doc, { min?: number; max?: number }]\n | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\n// comment-only edit\n","signature":"e0d759702454fa5818ea5747e4408ca8-type Doc = number | string | {\n [k: string]: Doc;\n} | readonly [\"array\", Doc] | readonly [\"array\", Doc, {\n length: number;\n}] | readonly [\"array\", Doc, {\n min?: number;\n max?: number;\n}] | readonly [\"union\", Doc, ...Doc[]];\nexport declare const doc: Doc;\nexport {};\n","impliedNodeFormat":1},{"version":"8af491d326de0701fb4d07a415b35dec-import { doc } from \"./doc\";\nexport const value = doc;\nexport const invalid: number = value;\n","signature":"00e384d4d515015edeff00bca55df3a8-type value_recursive = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | number | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport declare const invalid: number;\nexport {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"module":99,"strict":true},"referencedMap":[[3,1]],"semanticDiagnosticsPerFile":[[3,[{"pos":68,"end":75,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["Doc","number"],"messageChain":[{"pos":68,"end":75,"code":2322,"category":1,"messageKey":"Type_0_is_not_assignable_to_type_1_2322","messageArgs":["string","number"]}]}]]],"affectedFilesPendingEmit":[3,2]} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *modified* { "version": "FakeTSVersion", @@ -453,11 +453,11 @@ Found 1 error in consumer.ts:3 { "fileName": "./consumer.ts", "version": "8af491d326de0701fb4d07a415b35dec-import { doc } from \"./doc\";\nexport const value = doc;\nexport const invalid: number = value;\n", - "signature": "b0465247e2bd6863c6a086f723d673e8-export declare const value: any;\nexport declare const invalid: number;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n", + "signature": "00e384d4d515015edeff00bca55df3a8-type value_recursive = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | number | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport declare const invalid: number;\nexport {};\n", "impliedNodeFormat": "CommonJS", "original": { "version": "8af491d326de0701fb4d07a415b35dec-import { doc } from \"./doc\";\nexport const value = doc;\nexport const invalid: number = value;\n", - "signature": "b0465247e2bd6863c6a086f723d673e8-export declare const value: any;\nexport declare const invalid: number;\n\n(42,5): error5088: The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088\nvalue\n", + "signature": "00e384d4d515015edeff00bca55df3a8-type value_recursive = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4];\ntype value_recursive_2 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n length: number;\n}];\ntype value_recursive_3 = readonly [\"array\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, {\n min?: number;\n max?: number;\n}];\ntype value_recursive_4 = readonly [\"union\", string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4, ...(string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4)[]];\ntype value_recursive_1 = {\n [k: string]: string | number | value_recursive_1 | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\n};\nexport declare const value: string | number | {\n [k: string]: typeof value;\n} | value_recursive | value_recursive_2 | value_recursive_3 | value_recursive_4;\nexport declare const invalid: number;\nexport {};\n", "impliedNodeFormat": 1 } } @@ -519,7 +519,7 @@ Found 1 error in consumer.ts:3 2 ] ], - "size": 2530 + "size": 3544 } tsconfig.json:: diff --git a/tsc/testdata/tests/cases/compiler/recursiveFunctionDeclarationSerialization.ts b/tsc/testdata/tests/cases/compiler/recursiveFunctionDeclarationSerialization.ts index 21f4a0718bb77..61ae3038bbddf 100644 --- a/tsc/testdata/tests/cases/compiler/recursiveFunctionDeclarationSerialization.ts +++ b/tsc/testdata/tests/cases/compiler/recursiveFunctionDeclarationSerialization.ts @@ -243,3 +243,299 @@ export type Inferred = T extends (value: infer U) => infer R export declare const inferred: Inferred<(value: number) => { next: typeof reused }>; export const inferredCopy = inferred; const inferredValue: string = inferredCopy.next(1).second("text").value; + +// @filename: mappedCycles.ts +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +export const mappedCycle = build<{ Node: { value: number; next: "ref" } }>(); +export const mappedCycleCopy = mappedCycle; +export const nestedCycle = { wrapped: build<{ Node: { value: string; next: "ref" } }>() }; +export const cycleKey = Symbol(); +export const keyedCycles = build<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [cycleKey]: { value: number; next: "ref" }; +}>(); +export const sharedCycles = { + first: mappedCycle, + second: mappedCycle, +}; +export const broadCycle: { Node: unknown } = mappedCycle; + +type ResolveMutual = Show<{ + [P in keyof M[K]]: M[K][P] extends { ref: infer R extends keyof M } ? ResolveMutual : M[K][P]; +}>; +declare const buildMutual: () => { [K in keyof M]: ResolveMutual }; +export const mutualCycle = buildMutual<{ + First: { value: number; next: { ref: "Second" } }; + Second: { value: string; next: { ref: "First" } }; +}>(); + +const mappedValue: number = mappedCycle.Node.next.next.value; +const nestedMappedValue: string = nestedCycle.wrapped.Node.next.next.value; +const quotedMappedValue: string = keyedCycles["a-b"].next.next.value; +const numericMappedValue: boolean = keyedCycles[0].next.next.value; +const symbolMappedValue: number = keyedCycles[cycleKey].next.next.value; +const sharedMappedValue: number = sharedCycles.second.Node.next.next.value; +const mutualFirstValue: number = mutualCycle.First.next.next.value; +const mutualSecondValue: string = mutualCycle.First.next.value; +const invalidMappedValue: string = mappedCycle.Node.next.next.value; +const invalidMutualValue: number = mutualCycle.First.next.value; + +// @filename: optionalMappedCycle.ts +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]?: Resolve }; +export const optionalCycle = build<{ Node: { value: number; next: "ref" } }>(); +const optionalValue: number | undefined = optionalCycle.Node?.next.next.value; +export const optionalCopy = optionalCycle; +declare const buildNullable: () => { [K in keyof M]: Resolve | null }; +export const nullableCycle = buildNullable<{ Node: { value: string; next: "ref" } }>(); +declare const wrap: (value: T) => { required: T; optional?: T | null }; +export const mixedCycles = wrap(optionalCycle); +export const sharedOptionalCycles = { first: optionalCycle, second: optionalCycle }; +export const nullableKey = Symbol(); +export const nullableKeys = buildNullable<{ + "a-b": { value: string; next: "ref" }; + 0: { value: boolean; next: "ref" }; + [nullableKey]: { value: number; next: "ref" }; +}>(); +declare const buildNullableRoot: () => Resolve | null; +export const nullableRoot = buildNullableRoot<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalRoot: () => Resolve | undefined; +export const optionalRoot = buildOptionalRoot<{ Node: { value: string; next: "ref" } }>(); +type ResolveNullable = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullable | null : M[K][P]; +}>; +declare const buildNullableLinks: () => { [K in keyof M]: ResolveNullable | null }; +export const nullableLinks = buildNullableLinks<{ Node: { value: number; next: "ref" } }>(); +declare const buildOptionalNullableLinks: () => { [K in keyof M]?: ResolveNullable | null }; +export const optionalNullableLinks = buildOptionalNullableLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveOptional = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveOptional | undefined : M[K][P]; +}>; +declare const buildNullableOptionalLinks: () => { [K in keyof M]: ResolveOptional | null }; +export const nullableOptionalLinks = buildNullableOptionalLinks<{ Node: { value: number; next: "ref" } }>(); +type ResolveNullish = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? ResolveNullish | null | undefined : M[K][P]; +}>; +declare const buildNullishLinks: () => { [K in keyof M]?: ResolveNullish | null }; +export const nullishLinks = buildNullishLinks<{ Node: { value: number; next: "ref" } }>(); +type NonNullable = "shadowed"; +type OptionalNode = (typeof optionalCycle)["Node"] & {}; +type NullableNode = (typeof nullableCycle)["Node"] & {}; +type NullableLinkNode = (typeof nullableLinks)["Node"] & {}; +type NullishLinkNode = (typeof nullishLinks)["Node"] & {}; +type OptionalNullableLinkNode = (typeof optionalNullableLinks)["Node"] & {}; +type NullableOptionalLinkNode = (typeof nullableOptionalLinks)["Node"] & {}; +const copiedValue: number | undefined = optionalCopy.Node?.next.next.value; +const nullableValue: string | undefined = nullableCycle.Node?.next.next.value; +const mixedValue: number | undefined = mixedCycles.optional?.Node?.next.next.value; +const sharedValue: number | undefined = sharedOptionalCycles.second.Node?.next.next.value; +const quotedValue: string | undefined = nullableKeys["a-b"]?.next.next.value; +const numericValue: boolean | undefined = nullableKeys[0]?.next.next.value; +const symbolValue: number | undefined = nullableKeys[nullableKey]?.next.next.value; +const nullableRootValue: number | undefined = nullableRoot?.next.next.value; +const optionalRootValue: string | undefined = optionalRoot?.next.next.value; +const nullableLinkValue: number | undefined = nullableLinks.Node?.next?.next?.value; +const nullishLinkValue: number | undefined = nullishLinks.Node?.next?.next?.value; +const optionalNullableLinkValue: number | undefined = optionalNullableLinks.Node?.next?.next?.value; +const nullableOptionalLinkValue: number | undefined = nullableOptionalLinks.Node?.next?.next?.value; +const optionalNextHasNull: null extends OptionalNode["next"] ? true : false = false; +const optionalNextHasUndefined: undefined extends OptionalNode["next"] ? true : false = false; +const nullableNextHasNull: null extends NullableNode["next"] ? true : false = false; +const nullableNextHasUndefined: undefined extends NullableNode["next"] ? true : false = false; +const nullableLinkHasNull: null extends NullableLinkNode["next"] ? true : false = true; +const nullableLinkHasUndefined: undefined extends NullableLinkNode["next"] ? true : false = false; +const nullishLinkHasNull: null extends NullishLinkNode["next"] ? true : false = true; +const nullishLinkHasUndefined: undefined extends NullishLinkNode["next"] ? true : false = true; +const optionalNullableLinkHasNull: null extends OptionalNullableLinkNode["next"] ? true : false = true; +const optionalNullableLinkHasUndefined: undefined extends OptionalNullableLinkNode["next"] ? true : false = false; +const nullableOptionalLinkHasNull: null extends NullableOptionalLinkNode["next"] ? true : false = false; +const nullableOptionalLinkHasUndefined: undefined extends NullableOptionalLinkNode["next"] ? true : false = true; +const invalidNullNext: OptionalNode["next"] = null; +const invalidUndefinedNext: OptionalNode["next"] = undefined; +const invalidNullableLinkValue: number = nullableLinks.Node!.next.value; +const invalidNullishLinkValue: number = nullishLinks.Node!.next.value; + +// @filename: mixedMappedCycle.ts +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve | false | null }; +export const mixedCycle = build<{ Node: { value: number; next: "ref" } }>(); +if (mixedCycle.Node) { + const value: number = mixedCycle.Node.next.next.value; +} + +// @filename: anonymousThisReturn.ts +export function test() { + return { + relyingOnThis() { + return this; + }, + }; +} +test().relyingOnThis(); + +// @filename: recursiveConditionalAliasUtils.ts +type Recursive = T extends Array ? Recursive : T; +export const f = (): Recursive => { + return null!; +}; + +// @filename: recursiveConditionalAliasCopy.ts +import { f } from "./recursiveConditionalAliasUtils"; +export const a = f; +const numberValue: number = a(); +const stringValue: string = a(); + +// @filename: anonymousBindings.ts +export const _recursive = 1; +export const factory = () => function self() { return self; }; +export function captured(value: T) { + const node = { value, next: () => node, consume: (other: T) => node }; + return node; +} +export function nestedCaptured(outer: T) { + return (inner: U) => { + const node = { + outer, + inner, + next: () => node, + shadow: (value: T) => ({ outer, inner, value, next: node }), + }; + return node; + }; +} +export function constrained(key: K) { + const node = { value: null! as T[K], next: () => node }; + return node; +} +export function optionalCaptured(value: T) { + type Node = { value: T; next: Node }; + return null! as { node?: Node | false | null }; +} +export function annotatedCaptured(value: T) { + const node: { value: typeof value; next: typeof node } = { value, next: null! }; + return node; +} +export function recursiveTuple(value: T) { + type Tuple = readonly [T, Tuple]; + return null! as Tuple; +} +export function inferredCaptured() { + type Node = { value: V; next: Node }; + return null! as (T extends () => infer U ? Node : never); +} +export function mappedCaptured() { + type Node = { [K in keyof T]: { value: T[K]; next: Node } }; + return null! as Node; +} +export function freshGeneric(unused: T) { + const recur = (value: U) => recur; + return recur; +} +export function mutualCaptured(left: T, right: U) { + type Left = { left: T; next: Right }; + type Right = { right: U; self: Right; next: Left }; + return { left: null! as Left, right: null! as Right }; +} +export class CapturedClass { + constructor(public value: T) {} + make(inner: U) { + const node = { outer: this.value, inner, next: () => node }; + return node; + } +} +export function covariantClass() { + return class Node { + value!: T; + next(): Node { return this; } + }; +} +export function contravariantClass() { + return class Node { + consume!: (value: T) => void; + next(): Node { return this; } + }; +} +export namespace Nested { + export function captured(value: T) { + const node = { value, next: () => node }; + return node; + } +} +const capturedValue: string = captured("text").next().consume("other").value; +const nestedValue = nestedCaptured(1)("text").shadow(true).next.next(); +const nestedOuter: number = nestedValue.outer; +const nestedInner: string = nestedValue.inner; +const constrainedValue: number = constrained<{ value: number }, "value">("value").next().value; +const annotatedValue: string = annotatedCaptured("text").next.next.value; +const tupleValue: string = recursiveTuple("text")[1][1][0]; +const namespaceValue: number = Nested.captured(1).next().next().value; +const inferredValue: string = inferredCaptured<() => string>().next.next.value; +const mappedValue: number = mappedCaptured<{ value: number }>().value.next.value.value; +const freshValue = freshGeneric(1)("text")(true)(2); +const mutualValue: string = mutualCaptured(1, "text").left.next.self.next.next.right; +const classValue: string = new CapturedClass("text").make("other").next().outer; +const optional = optionalCaptured("text"); +if (optional.node) { + const value: string = optional.node.next.next.value; +} +captured("text").consume(1); +const invalidTupleValue: number = recursiveTuple("text")[1][0]; + +// @filename: shadowedMappedCycle.ts +type Show = { [K in keyof T]: T[K] } & unknown; +type Resolve = Show<{ + [P in keyof M[K]]: M[K][P] extends "ref" ? (shadowedCycle: T) => Resolve : M[K][P]; +}>; +declare const build: () => { [K in keyof M]: Resolve }; +export const shadowedCycle = build<{ Node: { value: number; next: "ref" } }>(); +const shadowedValue: number = shadowedCycle.Node.next(1).next("text").value; + +// @filename: globalRecursiveA.ts +function makeA() { + return { + value: 1, + self() { return this; }, + }; +} +type makeReserved_recursive = "reserved"; +function makeReserved() { + return { + value: true, + self() { return this; }, + }; +} +class GlobalA { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } + static "a-b"() { + const node = { value: true, next: () => node }; + return node; + } +} + +// @filename: globalRecursiveB.ts +function makeB() { + return { + value: "text", + self() { return this; }, + }; +} +class GlobalB { + static create(value: T) { + const node = { value, next: () => node }; + return node; + } +}